import { useCallback, useEffect, useState } from 'react'
import { GridDto } from '@/proxy/form/models'
import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource'
import { Pagination, Select } from '@/components/ui'
import classNames from 'classnames'
import { getList } from '@/services/form.service'
import { FaInbox } from 'react-icons/fa'
import FormView from '../form/FormView'

interface CardProps {
  listFormCode: string
  searchParams?: URLSearchParams
}

type Option = {
  value: number
  label: string
}

const CardItem = ({
  row,
  gridDto,
  listFormCode,
}: {
  row: any
  gridDto: GridDto
  listFormCode: string
}) => {
  const keyField = gridDto.gridOptions.keyFieldName
  const rowId = row[keyField!]

  return (
    <div className="bg-white dark:bg-neutral-800 border dark:border-neutral-700 flex flex-col p-4">
      <div className="flex-grow">
        <FormView listFormCode={listFormCode} id={rowId} isSubForm={true} />
      </div>
    </div>
  )
}

const Card = ({ listFormCode, searchParams }: CardProps) => {
  const { createSelectDataSource } = useListFormCustomDataSource({})
  const [gridDto, setGridDto] = useState<GridDto>()
  const [data, setData] = useState<any[]>([])
  const [totalCount, setTotalCount] = useState(0)
  const [currentPage, setCurrentPage] = useState(1)
  const [pageSize, setPageSize] = useState(20)
  const [pageSizeOptions, setPageSizeOptions] = useState<Option[]>([])

  const onPageSizeSelect = ({ value }: Option) => {
    setPageSize(value)
    setCurrentPage(1)
  }

  const onPageChange = (page: number) => {
    setCurrentPage(page)
  }

  const loadData = useCallback(() => {
    if (!gridDto) return

    const store = createSelectDataSource(gridDto.gridOptions, listFormCode, searchParams)

    const loadOptions = {
      skip: (currentPage - 1) * pageSize,
      take: pageSize,
      requireTotalCount: true,
    }

    store.load(loadOptions).then((res: any) => {
      setData(res.data)
      setTotalCount(res.totalCount || 0)
    })
  }, [gridDto, listFormCode, searchParams, currentPage, pageSize])

  useEffect(() => {
    getList({ listFormCode }).then((res: any) => setGridDto(res.data))
  }, [listFormCode])

  useEffect(() => {
    if (!gridDto) return

    const pagerOptions = gridDto.gridOptions.pagerOptionDto
    const allowedSizes =
      pagerOptions?.allowedPageSizes
        ?.split(',')
        .map((s) => Number(s.trim()))
        .filter((n) => !isNaN(n) && n > 0) || [20, 50, 100]

    setPageSizeOptions(allowedSizes.map((size) => ({ value: size, label: `${size} page` })))
  }, [gridDto, listFormCode, searchParams])

  useEffect(() => {
    loadData()
  }, [loadData])

  if (!gridDto) return null

  return (
    <>
      {data.length === 0 && (
        <div className="flex flex-col items-center justify-center p-10 bg-gray-50 dark:bg-neutral-800/50 rounded-md border-2 border-dashed border-gray-200 dark:border-neutral-700">
          <div className="text-center">
            <FaInbox className="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
            <p className="mt-4 text-lg font-semibold text-gray-700 dark:text-gray-300">
              Kayıt Bulunamadı
            </p>
            <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
              Görüntülenecek herhangi bir veri yok.
            </p>
          </div>
        </div>
      )}
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-4 gap-4">
        {data.map((row, idx) => {
          const keyField = gridDto.gridOptions.keyFieldName
          const rowId = row[keyField!]

          return <CardItem key={rowId || idx} row={row} gridDto={gridDto} listFormCode={listFormCode} />
        })}
      </div>

      {gridDto.gridOptions.pagerOptionDto?.visible && totalCount > pageSize && (
        <div className={classNames('flex items-center justify-between border-t-1 gap-4 mt-4')}>
          <div className="flex items-center gap-2">
            <span className="text-xs text-gray-600 dark:text-gray-300">
              Toplam {totalCount} kayıt
            </span>
            <Select
              size="xs"
              menuPlacement="top"
              value={pageSizeOptions.find((o) => o.value === pageSize)}
              options={pageSizeOptions}
              onChange={(selected) => onPageSizeSelect(selected as Option)}
            />
          </div>
          <Pagination
            currentPage={currentPage}
            total={totalCount}
            pageSize={pageSize}
            onChange={onPageChange}
          />
        </div>
      )}
    </>
  )
}

export default Card