/*
 * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
 *
 * Licensed under the GNU Affero General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.gnu.org/licenses/agpl-3.0.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import type { Ref } from 'vue'
import { nextTick, ref } from 'vue'

type ScrollElement = HTMLDivElement | null

interface ScrollReturn {
  contentRef: Ref<ScrollElement>
  scrollRef: Ref<ScrollElement>
  scrollToBottom: () => Promise<void>
  scrollToTop: () => Promise<void>
  scrollToBottomIfAtBottom: () => Promise<void>
}

export function useScroll(): ScrollReturn {
  const scrollRef = ref<ScrollElement>(null)
  const contentRef = ref<ScrollElement>(null)

  const scrollToBottom = async () => {
    await nextTick()
    if (contentRef.value) {
      contentRef.value.scrollTo({ top: contentRef.value.scrollHeight, behavior: 'smooth' })
    }
  }

  const scrollToTop = async () => {
    await nextTick()
    if (contentRef.value) {
      contentRef.value.scrollTo({ top: 0, behavior: 'smooth' })
    }
  }

  const scrollToBottomIfAtBottom = async () => {
    await nextTick()
    if (contentRef.value) {
      const threshold = 100 // 阈值，表示滚动条到底部的距离阈值
      const distanceToBottom =
        contentRef.value.scrollHeight - contentRef.value.scrollTop - contentRef.value.clientHeight
      if (distanceToBottom <= threshold) {
        contentRef.value.scrollTo({ top: contentRef.value.scrollHeight, behavior: 'smooth' })
      }
    }
  }

  return {
    scrollRef,
    contentRef,
    scrollToBottom,
    scrollToTop,
    scrollToBottomIfAtBottom,
  }
}
