"use client"

import * as React from "react"
import type {
  DataTableAdvancedFilterField,
  DataTableFilterField,
} from "@/types/table"
import { useSession } from "next-auth/react"

import { useDataTable } from "@/hooks/use-data-table"
import { DataTable } from "@/components/data-table/data-table"
import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
import { Button } from "@/components/ui/button"
import { toast } from "sonner"
import { BulkImportDialog } from "./bulk-import-dialog"

import { columns, type VendorPoolItem } from "./vendor-pool-table-columns"
import { createVendorPool, updateVendorPool, deleteVendorPool } from "../service"
import type { VendorPool } from "@/db/schema/avl/vendor-pool"
import { Download, FileSpreadsheet, Upload } from "lucide-react"
import { ImportVendorPoolButton } from "./vendor-pool-excel-import-button"
import { exportVendorPoolToExcel, createVendorPoolTemplate } from "../excel-utils"

// vendor-pool 테이블 메타 타입
interface VendorPoolTableMeta {
  onCellUpdate?: (id: string | number, field: string, newValue: any) => Promise<void>
  onCellCancel?: (id: string | number, field: string) => void
  onAction?: (action: string, data?: any) => void
  onSaveEmptyRow?: (tempId: string) => Promise<void>
  onCancelEmptyRow?: (tempId: string) => void
  isEmptyRow?: (id: string) => boolean
  getPendingChanges?: () => Record<string, Partial<VendorPoolItem>>
}

interface VendorPoolTableProps {
  data: VendorPoolItem[]
  pageCount?: number
  onRefresh?: () => void // 데이터 새로고침 콜백
}

// 빈 행 기본값 객체
const createEmptyVendorPoolBase = (): Omit<VendorPool, 'id'> & { id?: string | number } => ({
  constructionSector: "",
  htDivision: "",
  designCategoryCode: "",
  designCategory: "",
  equipBulkDivision: "",
  packageCode: null,
  packageName: null,
  materialGroupCode: null,
  materialGroupName: null,
  smCode: null,
  similarMaterialNamePurchase: null,
  similarMaterialNameOther: null,
  vendorCode: null,
  vendorName: "",
  taxId: null,
  faTarget: false,
  faStatus: null,
  faRemark: null,
  tier: null,
  isAgent: false,
  contractSignerCode: null,
  contractSignerName: "",
  headquarterLocation: "",
  manufacturingLocation: "",
  avlVendorName: null,
  similarVendorName: null,
  hasAvl: false,
  isBlacklist: false,
  isBcc: false,
  purchaseOpinion: null,
  shipTypeCommon: false,
  shipTypeAmax: false,
  shipTypeSmax: false,
  shipTypeVlcc: false,
  shipTypeLngc: false,
  shipTypeCont: false,
  offshoreTypeCommon: false,
  offshoreTypeFpso: false,
  offshoreTypeFlng: false,
  offshoreTypeFpu: false,
  offshoreTypePlatform: false,
  offshoreTypeWtiv: false,
  offshoreTypeGom: false,
  picName: null,
  picEmail: null,
  picPhone: null,
  agentName: null,
  agentEmail: null,
  agentPhone: null,
  recentQuoteDate: null,
  recentQuoteNumber: null,
  recentOrderDate: null,
  recentOrderNumber: null,
  registrationDate: null,
  registrant: null,
  lastModifiedDate: null,
  lastModifier: null,
})

export function VendorPoolTable({ data, pageCount, onRefresh }: VendorPoolTableProps) {
  const { data: session } = useSession()

  // 수정사항 추적 (일괄 저장용)
  const [pendingChanges, setPendingChanges] = React.useState<Record<string, Partial<VendorPoolItem>>>({})
  const [isSaving, setIsSaving] = React.useState(false)

  // 빈 행 관리 (신규 등록용)
  const [emptyRows, setEmptyRows] = React.useState<Record<string, VendorPoolItem>>({})
  const [isCreating, setIsCreating] = React.useState(false)

  // 일괄입력 다이얼로그 상태
  const [bulkImportDialogOpen, setBulkImportDialogOpen] = React.useState(false)



  // 인라인 편집 핸들러 (일괄 저장용)
  const handleCellUpdate = React.useCallback(async (id: string | number, field: string, newValue: any) => {
    const isEmptyRow = String(id).startsWith('temp-')

    if (isEmptyRow) {
      // 빈 행의 경우 emptyRows 상태도 업데이트
      setEmptyRows(prev => ({
        ...prev,
        [id]: {
          ...prev[id],
          [field]: newValue
        }
      }))
    }

    // pendingChanges에 변경사항 저장 (실시간 표시용)
    setPendingChanges(prev => ({
      ...prev,
      [id]: {
        ...prev[id],
        [field]: newValue
      }
    }))
  }, [])



  // 편집 취소 핸들러
  const handleCellCancel = React.useCallback((id: string | number, field: string) => {
    const isEmptyRow = String(id).startsWith('temp-')

    if (isEmptyRow) {
      // 빈 행의 경우 emptyRows와 pendingChanges 모두 취소
      setEmptyRows(prev => ({
        ...prev,
        [id]: {
          ...prev[id],
          [field]: prev[id][field] // 원래 값으로 복원 (pendingChanges의 초기값 사용)
        }
      }))

      setPendingChanges(prev => {
        const itemChanges = { ...prev[id] }
        delete itemChanges[field]

        if (Object.keys(itemChanges).length === 0) {
          const newChanges = { ...prev }
          delete newChanges[id]
          return newChanges
        }

        return {
          ...prev,
          [id]: itemChanges
        }
      })
    } else {
      // 기존 데이터의 경우
      setPendingChanges(prev => {
        const itemChanges = { ...prev[id] }
        delete itemChanges[field]

        if (Object.keys(itemChanges).length === 0) {
          const newChanges = { ...prev }
          delete newChanges[id]
          return newChanges
        }

        return {
          ...prev,
          [id]: itemChanges
        }
      })
    }
  }, [])

  // 일괄 저장 핸들러
  const handleBatchSave = React.useCallback(async () => {
    if (Object.keys(pendingChanges).length === 0) return

    setIsSaving(true)
    let successCount = 0
    let errorCount = 0
    let duplicateErrors: string[] = []

    try {
      // 각 항목의 변경사항을 순차적으로 저장
      for (const [id, changes] of Object.entries(pendingChanges)) {
        try {
          // changes에서 id 필드 제거 (서버에서 자동 생성)
          const { id: _, no: __, selected: ___, ...updateData } = changes
          // 최종변경자를 현재 세션 사용자 정보로 설정
          const updateDataWithModifier: any = {
            ...updateData,
            lastModifier: session?.user?.name || null
          }
          const result = await updateVendorPool(Number(id), updateDataWithModifier)
          if (result) {
            successCount++
          } else {
            errorCount++
          }
        } catch (error) {
          console.error(`항목 ${id} 저장 실패:`, error)

          // Unique 제약 조건 위반 감지
          const errorMessage = error instanceof Error ? error.message : String(error);
          if (errorMessage === 'DUPLICATE_VENDOR_POOL') {
            const changes = pendingChanges[id]
            duplicateErrors.push(`항목 ${id}: 공사부문(${changes.constructionSector}), H/T(${changes.htDivision}), 자재그룹코드(${changes.materialGroupCode}), 협력업체명(${changes.vendorName})`)
          }
          errorCount++
        }
      }

      // 저장 완료 후 pendingChanges 초기화
      setPendingChanges({})

      if (successCount > 0) {
        toast.success(`${successCount}개 항목이 저장되었습니다.`)

        // 편집 모드 종료를 위해 테이블 상태 리셋 및 데이터 새로고침
        table.resetRowSelection()
        onRefresh?.() // 데이터 새로고침
      }

      // 중복 에러가 있는 경우 개별적으로 표시
      if (duplicateErrors.length > 0) {
        duplicateErrors.forEach(errorMsg => {
          toast.error(`중복된 항목입니다. ${errorMsg}`)
        })
      }

      // 일반적인 에러 메시지 (중복 에러 제외)
      const generalErrorCount = errorCount - duplicateErrors.length
      if (generalErrorCount > 0) {
        toast.error(`${generalErrorCount}개 항목 저장에 실패했습니다.`)
      }
    } catch (error) {
      console.error("Batch save error:", error)
      toast.error("저장 중 오류가 발생했습니다.")
    } finally {
      setIsSaving(false)
    }
  }, [pendingChanges, onRefresh])

  // 수정사항 존재 여부
  const hasPendingChanges = Object.keys(pendingChanges).length > 0

  // 빈 행 생성 함수
  const createEmptyRow = React.useCallback(() => {
    if (isCreating) return // 이미 생성 중이면 중복 생성 방지

    const tempId = `temp-${Date.now()}`
    const userName = session?.user?.name || null

    const emptyRow: VendorPoolItem = {
      ...createEmptyVendorPoolBase(),
      id: tempId, // string 타입으로 설정
      no: 0, // 나중에 계산
      selected: false,
      registrationDate: "", // 빈 행에서는 string으로 표시
      registrant: userName,
      lastModifiedDate: "",
      lastModifier: userName,
    } as unknown as VendorPoolItem

    setEmptyRows(prev => ({ ...prev, [tempId]: emptyRow }))
    setIsCreating(true)


    // 빈 행의 초기값들을 pendingChanges에 설정 (임시 저장용)
    // emptyRow의 실제 값들을 반영
    setPendingChanges(prev => ({
      ...prev,
      [tempId]: { ...emptyRow }
    }))
  }, [isCreating])

  // 빈 행 저장 함수
  const saveEmptyRow = React.useCallback(async (tempId: string) => {
    const rowData = emptyRows[tempId]
    const changes = pendingChanges[tempId]


    if (!rowData || !changes) {
      console.error('rowData 또는 changes가 없음')
      return
    }

    // emptyRows와 pendingChanges를 병합한 최종 데이터
    const finalData = { ...rowData, ...changes }

    // 필수 필드 검증 (최종 데이터 기준)
    const requiredFields = ['constructionSector', 'htDivision', 'designCategory', 'taxId', 'vendorName', 'materialGroupCode', 'materialGroupName', 'tier', 'contractSignerName', 'headquarterLocation', 'manufacturingLocation', 'avlVendorName']

    // 필드명과 한국어 레이블 매핑
    const fieldLabels: Record<string, string> = {
      constructionSector: '공사부문',
      htDivision: 'H/T구분',
      designCategory: '설계기능',
      taxId: '사업자번호',
      vendorName: '협력업체명',
      materialGroupCode: '자재그룹코드',
      materialGroupName: '자재그룹명',
      tier: '등급(Tier)',
      contractSignerName: '계약서명주체명',
      headquarterLocation: '위치(국가)',
      manufacturingLocation: '제작/선적지(국가)',
      avlVendorName: 'AVL등재업체명'
    }

    const missingFields = requiredFields.filter(field => {
      const value = finalData[field as keyof VendorPoolItem]
      return !value || value === ''
    })

    if (missingFields.length > 0) {
      const missingFieldLabels = missingFields.map(field => fieldLabels[field]).join(', ')
      toast.error(`필수 항목을 입력해주세요: ${missingFieldLabels}`)
      return
    }

    try {
      setIsSaving(true)

      // id, no, selected 필드 제거 및 타입 변환
      const { id: _, no: __, selected: ___, registrationDate: ____, lastModifiedDate: _____, ...createData } = finalData

      const result = await createVendorPool(createData as any)

      if (result) {
        toast.success("새 항목이 추가되었습니다.")

        // 빈 행 제거
        setEmptyRows(prev => {
          const newRows = { ...prev }
          delete newRows[tempId]
          return newRows
        })

        setPendingChanges(prev => {
          const newChanges = { ...prev }
          delete newChanges[tempId]
          return newChanges
        })

        setIsCreating(false)

        // 데이터 새로고침
        onRefresh?.()
      }
    } catch (error) {
      console.error("빈 행 저장 실패:", error)

      // Unique 제약 조건 위반 감지
      const errorMessage = error instanceof Error ? error.message : String(error);
      if (errorMessage === 'DUPLICATE_VENDOR_POOL') {
        toast.error(`중복된 항목입니다. (공사부문: ${finalData.constructionSector}, H/T: ${finalData.htDivision}, 자재그룹코드: ${finalData.materialGroupCode}, 협력업체명: ${finalData.vendorName})`)
      } else {
        toast.error("저장 중 오류가 발생했습니다.")
      }
    } finally {
      setIsSaving(false)
    }
  }, [emptyRows, pendingChanges, onRefresh])

  // 빈 행 취소 함수
  const cancelEmptyRow = React.useCallback((tempId: string) => {
    setEmptyRows(prev => {
      const newRows = { ...prev }
      delete newRows[tempId]
      return newRows
    })

    setPendingChanges(prev => {
      const newChanges = { ...prev }
      delete newChanges[tempId]
      return newChanges
    })

    setIsCreating(false)
    toast.info("새 항목 추가가 취소되었습니다.")
  }, [])


  // 필터 필드 정의
  const filterFields: DataTableFilterField<VendorPoolItem>[] = [
    {
      id: "constructionSector",
      label: "공사부문",
      options: [
        { label: "조선", value: "조선" },
        { label: "해양", value: "해양" },
      ]
    },
    {
      id: "htDivision",
      label: "H/T구분",
      options: [
        { label: "H", value: "H" },
        { label: "T", value: "T" },
        { label: "공통", value: "공통" },
      ]
    },
    {
      id: "equipBulkDivision",
      label: "Equip/Bulk 구분",
      options: [
        { label: "E (Equip)", value: "E" },
        { label: "B (Bulk)", value: "B" },
      ]
    },
    {
      id: "faTarget",
      label: "FA대상",
      options: [
        { label: "대상", value: "true" },
        { label: "비대상", value: "false" },
      ]
    },
    {
      id: "isAgent",
      label: "Agent 여부",
      options: [
        { label: "Agent", value: "true" },
        { label: "일반", value: "false" },
      ]
    },
    {
      id: "hasAvl",
      label: "AVL 존재",
      options: [
        { label: "있음", value: "true" },
        { label: "없음", value: "false" },
      ]
    },
    {
      id: "isBlacklist",
      label: "Blacklist",
      options: [
        { label: "등록됨", value: "true" },
        { label: "미등록", value: "false" },
      ]
    },
    {
      id: "isBcc",
      label: "BCC",
      options: [
        { label: "등록됨", value: "true" },
        { label: "미등록", value: "false" },
      ]
    }
  ]

  const advancedFilterFields: DataTableAdvancedFilterField<VendorPoolItem>[] = [
    {
      id: "constructionSector",
      label: "공사부문",
      type: "select",
      options: [
        { label: "조선", value: "조선" },
        { label: "해양", value: "해양" },
      ]
    },
    {
      id: "htDivision",
      label: "H/T구분",
      type: "select",
      options: [
        { label: "H", value: "H" },
        { label: "T", value: "T" },
        { label: "공통", value: "공통" },
      ]
    },
    {
      id: "designCategoryCode",
      label: "설계기능코드",
      type: "text",
    },
    {
      id: "designCategory",
      label: "설계기능(공종)",
      type: "text",
    },
    {
      id: "packageCode",
      label: "패키지 코드",
      type: "text",
    },
    {
      id: "packageName",
      label: "패키지 명",
      type: "text",
    },
    {
      id: "materialGroupCode",
      label: "자재그룹 코드",
      type: "text",
    },
    {
      id: "materialGroupName",
      label: "자재그룹 명",
      type: "text",
    },
    {
      id: "vendorCode",
      label: "협력업체 코드",
      type: "text",
    },
    {
      id: "vendorName",
      label: "협력업체 명",
      type: "text",
    },
    {
      id: "taxId",
      label: "사업자번호",
      type: "text",
    },
    {
      id: "faStatus",
      label: "FA현황",
      type: "text",
    },
    {
      id: "tier",
      label: "등급",
      type: "text",
    },
    {
      id: "headquarterLocation",
      label: "본사 위치",
      type: "text",
    },
    {
      id: "manufacturingLocation",
      label: "제작/선적지",
      type: "text",
    },
    {
      id: "avlVendorName",
      label: "AVL 등재업체명",
      type: "text",
    },
    {
      id: "registrant",
      label: "등재자",
      type: "text",
    },
    {
      id: "lastModifier",
      label: "최종변경자",
      type: "text",
    },
    {
      id: "registrationDate",
      label: "등재일",
      type: "date",
    },
    {
      id: "lastModifiedDate",
      label: "최종변경일",
      type: "date",
    },
  ]

  // 빈 행들을 기존 데이터와 합치기 (빈 행들을 최상단에 배치)
  const combinedData = React.useMemo(() => {
    const existingData = [...data]
    const emptyRowList = Object.values(emptyRows)

    // 빈 행들의 no 필드 업데이트 (음수로 설정하여 최상단에 배치)
    const updatedEmptyRows = emptyRowList.map((row, index) => ({
      ...row,
      no: -(emptyRowList.length - index) // -3, -2, -1 순으로 설정
    }))

    // 기존 데이터의 no 필드도 1부터 재설정
    const updatedExistingData = existingData.map((row, index) => {
      const originalRow = existingData[index]
      const rowId = String(originalRow.id)
      const pendingChange = pendingChanges[rowId]

      // pendingChanges의 값으로 데이터 병합
      const mergedRow = pendingChange ? { ...originalRow, ...pendingChange } : originalRow

      return {
        ...mergedRow,
        no: index + 1
      }
    })

    // 빈 행들을 최상단에 배치
    return [...updatedEmptyRows, ...updatedExistingData]
  }, [data, emptyRows, pendingChanges])

  const { table } = useDataTable({
    data: combinedData,
    columns,
    pageCount: pageCount || 0,
    filterFields,
    enablePinning: true,
    enableAdvancedFilter: true,
    // enableColumnResizing: true,
    columnResizeMode: "onChange",
    initialState: {
      sorting: [{ id: "registrationDate", desc: true }],
      columnPinning: { right: ["actions"] },
    },
    getRowId: (originalRow) => String(originalRow.id),
    shallow: false,
    clearOnDefault: true,
  })

  // 액션 핸들러
  const handleAction = React.useCallback(async (action: string, data?: any) => {
    try {
      switch (action) {
        case 'new-registration':
          createEmptyRow()
          break

        case 'bulk-import':
          setBulkImportDialogOpen(true)
          break

        case 'save':
          toast.info('저장 기능은 개발 중입니다.')
          break


        case 'excel-export':
          try {
            // 현재 테이블 데이터를 Excel로 내보내기 (ID 포함)
            const currentData = table.getFilteredRowModel().rows.map(row => row.original)
            await exportVendorPoolToExcel(
              currentData, 
              `vendor-pool-${new Date().toISOString().split('T')[0]}.xlsx`,
              true // ID 포함
            )
            toast.success('Excel 파일이 다운로드되었습니다.')
          } catch (error) {
            console.error('Excel export 실패:', error)
            toast.error('Excel 내보내기에 실패했습니다.')
          }
          break

        case 'excel-template':
          try {
            // 템플릿 파일 다운로드 (데이터 없음, ID 컬럼 제외)
            await createVendorPoolTemplate(
              `vendor-pool-template-${new Date().toISOString().split('T')[0]}.xlsx`
            )
            toast.success('Excel 템플릿이 다운로드되었습니다.')
          } catch (error) {
            console.error('Excel template export 실패:', error)
            toast.error('Excel 템플릿 다운로드에 실패했습니다.')
          }
          break

        case 'delete':
          if (data?.id && confirm('정말 삭제하시겠습니까?')) {
            const success = await deleteVendorPool(Number(data.id))
            if (success) {
              toast.success('삭제가 완료되었습니다.')
              onRefresh?.() // 데이터 새로고침
            } else {
              toast.error('삭제에 실패했습니다.')
            }
          }
          break

        default:
          console.log('알 수 없는 액션:', action)
          toast.error('알 수 없는 액션입니다.')
      }
    } catch (error) {
      console.error('액션 처리 실패:', error)
      toast.error('액션 처리 중 오류가 발생했습니다.')
    }
  }, [table, onRefresh])

  // 일괄입력 핸들러
  const handleBulkImport = React.useCallback(async (bulkData: Record<string, any>) => {
    const selectedRows = table.getFilteredSelectedRowModel().rows

    if (selectedRows.length === 0) {
      toast.error('일괄 입력할 행이 선택되지 않았습니다.')
      return
    }

    try {
      // 선택된 각 행에 대해 값 적용
      for (const row of selectedRows) {
        const rowId = String(row.original.id)

        // 제공된 값들만 적용 (빈 값이나 undefined는 건너뜀)
        Object.entries(bulkData).forEach(([field, value]) => {
          if (value !== undefined && value !== null && value !== '') {
            handleCellUpdate(rowId, field as keyof VendorPool, value)
          }
        })
      }

      toast.success(`${selectedRows.length}개 행에 일괄 입력이 적용되었습니다.`)
      setBulkImportDialogOpen(false)
    } catch (error) {
      console.error('일괄입력 처리 실패:', error)
      toast.error('일괄입력 처리 중 오류가 발생했습니다.')
    }
  }, [table, handleCellUpdate])

  // 테이블 메타에 핸들러 설정
  const tableMeta: VendorPoolTableMeta = {
    onAction: handleAction,
    onCellUpdate: handleCellUpdate,
    onCellCancel: handleCellCancel,
    onSaveEmptyRow: saveEmptyRow,
    onCancelEmptyRow: cancelEmptyRow,
    isEmptyRow: (id: string) => String(id).startsWith('temp-'),
    getPendingChanges: () => pendingChanges
  }
  
  table.options.meta = tableMeta as any


  // 툴바 액션 핸들러들
  const handleToolbarAction = React.useCallback((action: string, data?: any) => {
    handleAction(action, data)
  }, [handleAction])

  // 저장 버튼 핸들러
  const handleSaveChanges = React.useCallback(() => {
    handleBatchSave()
  }, [handleBatchSave])

  return (
    <>
      <DataTable
        table={table}
        className="[&_[data-row-id^='temp-']]:bg-blue-50 [&_[data-row-id^='temp-']]:border-blue-200"
        // autoSizeColumns={true}
      >
        <DataTableAdvancedToolbar
          table={table}
          filterFields={advancedFilterFields}
          shallow={false}
        >
          <div className="flex items-center gap-2">
            <Button
              onClick={() => handleToolbarAction('new-registration')}
              disabled={isCreating}
              variant="outline"
              size="sm"
            >
              신규등록
            </Button>
            
            <Button
              onClick={() => handleToolbarAction('bulk-import')}
              variant="outline"
              size="sm"
            >
              일괄입력
            </Button>

            <ImportVendorPoolButton onSuccess={onRefresh} />

            <Button
              onClick={() => handleToolbarAction('excel-export')}
              variant="outline"
              size="sm"
            >
              <Download className="mr-2 h-4 w-4" />
              Excel Export
            </Button>

            <Button
              onClick={() => handleToolbarAction('excel-template')}
              variant="outline"
              size="sm"
            >
              <FileSpreadsheet className="mr-2 h-4 w-4" />
              Template
            </Button>

            <Button
              onClick={handleSaveChanges}
              disabled={!hasPendingChanges || isSaving}
              variant={hasPendingChanges && !isSaving ? "default" : "outline"}
              size="sm"
            >
              {isSaving ? "저장 중..." : `저장${hasPendingChanges ? ` (${Object.keys(pendingChanges).length})` : ""}`}
            </Button>

            {/* <Button
              onClick={() => handleToolbarAction('fixed-values')}
              variant="outline"
              size="sm"
            >
              고정값 설정
            </Button> */}
          </div>
        </DataTableAdvancedToolbar>
      </DataTable>

      <BulkImportDialog
        open={bulkImportDialogOpen}
        onOpenChange={setBulkImportDialogOpen}
        onSubmit={handleBulkImport}
      />
    </>
  )
}
