'use client'
import type { FC } from 'react'
import type { QueryParam } from './filter'
import type { AnnotationItem, AnnotationItemBasic } from './type'
import type { AnnotationReplyConfig } from '@/models/debug'
import type { App } from '@/types/app'
import { RiEqualizer2Line } from '@remixicon/react'
import { useDebounce } from 'ahooks'
import * as React from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ActionButton from '@/app/components/base/action-button'
import ConfigParamModal from '@/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal'
import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication'
import Loading from '@/app/components/base/loading'
import Pagination from '@/app/components/base/pagination'
import Switch from '@/app/components/base/switch'
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
import { APP_PAGE_LIMIT } from '@/config'
import { useProviderContext } from '@/context/provider-context'
import { addAnnotation, delAnnotation, delAnnotations, fetchAnnotationConfig as doFetchAnnotationConfig, editAnnotation, fetchAnnotationList, queryAnnotationJobStatus, updateAnnotationScore, updateAnnotationStatus } from '@/service/annotation'
import { AppModeEnum } from '@/types/app'
import { sleep } from '@/utils'
import { cn } from '@/utils/classnames'
import Toast from '../../base/toast'
import EmptyElement from './empty-element'
import Filter from './filter'
import HeaderOpts from './header-opts'
import List from './list'
import { AnnotationEnableStatus, JobStatus } from './type'
import ViewAnnotationModal from './view-annotation-modal'

type Props = {
  appDetail: App
}

const Annotation: FC<Props> = (props) => {
  const { appDetail } = props
  const { t } = useTranslation()
  const [isShowEdit, setIsShowEdit] = useState(false)
  const [annotationConfig, setAnnotationConfig] = useState<AnnotationReplyConfig | null>(null)
  const [isChatApp] = useState(appDetail.mode !== AppModeEnum.COMPLETION)
  const [controlRefreshSwitch, setControlRefreshSwitch] = useState(() => Date.now())
  const { plan, enableBilling } = useProviderContext()
  const isAnnotationFull = enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse
  const [isShowAnnotationFullModal, setIsShowAnnotationFullModal] = useState(false)
  const [queryParams, setQueryParams] = useState<QueryParam>({})
  const [currPage, setCurrPage] = useState(0)
  const [limit, setLimit] = useState(APP_PAGE_LIMIT)
  const [list, setList] = useState<AnnotationItem[]>([])
  const [total, setTotal] = useState(0)
  const [isLoading, setIsLoading] = useState(false)
  const [controlUpdateList, setControlUpdateList] = useState(() => Date.now())
  const [currItem, setCurrItem] = useState<AnnotationItem | null>(null)
  const [isShowViewModal, setIsShowViewModal] = useState(false)
  const [selectedIds, setSelectedIds] = useState<string[]>([])
  const debouncedQueryParams = useDebounce(queryParams, { wait: 500 })

  const fetchAnnotationConfig = async () => {
    const res = await doFetchAnnotationConfig(appDetail.id)
    setAnnotationConfig(res as AnnotationReplyConfig)
    return (res as AnnotationReplyConfig).id
  }

  useEffect(() => {
    if (isChatApp)
      fetchAnnotationConfig()
  }, [])

  const ensureJobCompleted = async (jobId: string, status: AnnotationEnableStatus) => {
    while (true) {
      const res: any = await queryAnnotationJobStatus(appDetail.id, status, jobId)
      if (res.job_status === JobStatus.completed)
        break
      await sleep(2000)
    }
  }

  const fetchList = async (page = 1) => {
    setIsLoading(true)
    try {
      const { data, total }: any = await fetchAnnotationList(appDetail.id, {
        page,
        limit,
        keyword: debouncedQueryParams.keyword || '',
      })
      setList(data as AnnotationItem[])
      setTotal(total)
    }
    finally {
      setIsLoading(false)
    }
  }

  useEffect(() => {
    fetchList(currPage + 1)
  }, [currPage, limit, debouncedQueryParams])

  const handleAdd = async (payload: AnnotationItemBasic) => {
    await addAnnotation(appDetail.id, payload)
    Toast.notify({ message: t('api.actionSuccess', { ns: 'common' }), type: 'success' })
    fetchList()
    setControlUpdateList(Date.now())
  }

  const handleRemove = async (id: string) => {
    await delAnnotation(appDetail.id, id)
    Toast.notify({ message: t('api.actionSuccess', { ns: 'common' }), type: 'success' })
    fetchList()
    setControlUpdateList(Date.now())
  }

  const handleBatchDelete = async () => {
    try {
      await delAnnotations(appDetail.id, selectedIds)
      Toast.notify({ message: t('api.actionSuccess', { ns: 'common' }), type: 'success' })
      fetchList()
      setControlUpdateList(Date.now())
      setSelectedIds([])
    }
    catch (e: any) {
      Toast.notify({ type: 'error', message: e.message || t('api.actionFailed', { ns: 'common' }) })
    }
  }

  const handleView = (item: AnnotationItem) => {
    setCurrItem(item)
    setIsShowViewModal(true)
  }

  const handleSave = async (question: string, answer: string) => {
    if (!currItem)
      return
    await editAnnotation(appDetail.id, currItem.id, { question, answer })
    Toast.notify({ message: t('api.actionSuccess', { ns: 'common' }), type: 'success' })
    fetchList()
    setControlUpdateList(Date.now())
  }

  useEffect(() => {
    if (!isShowEdit)
      setControlRefreshSwitch(Date.now())
  }, [isShowEdit])

  return (
    <div className="flex h-full flex-col">
      <p className="text-text-tertiary system-sm-regular">{t('description', { ns: 'appLog' })}</p>
      <div className="relative flex h-full flex-1 flex-col py-4">
        <Filter appId={appDetail.id} queryParams={queryParams} setQueryParams={setQueryParams}>
          <div className="flex items-center space-x-2">
            {isChatApp && (
              <>
                <div className={cn(!annotationConfig?.enabled && 'pr-2', 'flex h-7 items-center space-x-1 rounded-lg border border-components-panel-border bg-components-panel-bg-blur pl-2')}>
                  <MessageFast className="h-4 w-4 text-util-colors-indigo-indigo-600" />
                  <div className="text-text-primary system-sm-medium">{t('name', { ns: 'appAnnotation' })}</div>
                  <Switch
                    key={controlRefreshSwitch}
                    value={annotationConfig?.enabled ?? false}
                    size="md"
                    onChange={async (value) => {
                      if (value) {
                        if (isAnnotationFull) {
                          setIsShowAnnotationFullModal(true)
                          setControlRefreshSwitch(Date.now())
                          return
                        }
                        setIsShowEdit(true)
                      }
                      else {
                        const { job_id: jobId }: any = await updateAnnotationStatus(appDetail.id, AnnotationEnableStatus.disable, annotationConfig?.embedding_model, annotationConfig?.score_threshold)
                        await ensureJobCompleted(jobId, AnnotationEnableStatus.disable)
                        await fetchAnnotationConfig()
                        Toast.notify({
                          message: t('api.actionSuccess', { ns: 'common' }),
                          type: 'success',
                        })
                      }
                    }}
                  >
                  </Switch>
                  {annotationConfig?.enabled && (
                    <div className="flex items-center pl-1.5">
                      <div className="mr-1 h-3.5 w-[1px] shrink-0 bg-divider-subtle"></div>
                      <ActionButton onClick={() => setIsShowEdit(true)}>
                        <RiEqualizer2Line className="h-4 w-4 text-text-tertiary" />
                      </ActionButton>
                    </div>
                  )}
                </div>
                <div className="mx-3 h-3.5 w-[1px] shrink-0 bg-divider-regular"></div>
              </>
            )}

            <HeaderOpts
              appId={appDetail.id}
              controlUpdateList={controlUpdateList}
              onAdd={handleAdd}
              onAdded={() => {
                fetchList()
              }}
            />
          </div>
        </Filter>
        {isLoading
          ? <Loading type="app" />

          : total > 0
            ? (
                <List
                  list={list}
                  onRemove={handleRemove}
                  onView={handleView}
                  selectedIds={selectedIds}
                  onSelectedIdsChange={setSelectedIds}
                  onBatchDelete={handleBatchDelete}
                  onCancel={() => setSelectedIds([])}
                />
              )
            : <div className="flex h-full grow items-center justify-center"><EmptyElement /></div>}
        {/* Show Pagination only if the total is more than the limit */}
        {(total && total > APP_PAGE_LIMIT)
          ? (
              <Pagination
                current={currPage}
                onChange={setCurrPage}
                total={total}
                limit={limit}
                onLimitChange={setLimit}
              />
            )
          : null}

        {isShowViewModal && (
          <ViewAnnotationModal
            appId={appDetail.id}
            isShow={isShowViewModal}
            onHide={() => setIsShowViewModal(false)}
            onRemove={async () => {
              await handleRemove((currItem as AnnotationItem)?.id)
            }}
            item={currItem as AnnotationItem}
            onSave={handleSave}
          />
        )}
        {isShowEdit && (
          <ConfigParamModal
            appId={appDetail.id}
            isShow
            isInit={!annotationConfig?.enabled}
            onHide={() => {
              setIsShowEdit(false)
            }}
            onSave={async (embeddingModel, score) => {
              if (
                embeddingModel.embedding_model_name !== annotationConfig?.embedding_model?.embedding_model_name
                || embeddingModel.embedding_provider_name !== annotationConfig?.embedding_model?.embedding_provider_name
              ) {
                const { job_id: jobId }: any = await updateAnnotationStatus(appDetail.id, AnnotationEnableStatus.enable, embeddingModel, score)
                await ensureJobCompleted(jobId, AnnotationEnableStatus.enable)
              }
              const annotationId = await fetchAnnotationConfig()
              if (score !== annotationConfig?.score_threshold)
                await updateAnnotationScore(appDetail.id, annotationId, score)

              await fetchAnnotationConfig()
              Toast.notify({
                message: t('api.actionSuccess', { ns: 'common' }),
                type: 'success',
              })
              setIsShowEdit(false)
            }}
            annotationConfig={annotationConfig!}
          />
        )}
        {
          isShowAnnotationFullModal && (
            <AnnotationFullModal
              show={isShowAnnotationFullModal}
              onHide={() => setIsShowAnnotationFullModal(false)}
            />
          )
        }
      </div>
    </div>
  )
}
export default React.memo(Annotation)
