/**
 * 특정 컬럼들 복합키로 묶어 UPDATE 처리해야 함.
 */

"use client"

import React, { useRef } from 'react'
import ExcelJS from 'exceljs'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Upload, Loader } from 'lucide-react'
import { createVendorPool } from '../service'
import { Input } from '@/components/ui/input'
import { useSession } from "next-auth/react"
import { 
  getCellValueAsString, 
  parseBoolean, 
  getAccessorKeyByHeader,
  vendorPoolExcelColumns 
} from '../excel-utils'
import { decryptWithServerAction } from '@/components/drm/drmUtils'
import { debugLog, debugError, debugWarn, debugSuccess, debugProcess } from '@/lib/debug-utils'
import { enrichVendorPoolData } from '../enrichment-service'
import { ImportResultDialog, ImportResult, ImportResultItem } from './import-result-dialog'
import { ImportProgressDialog } from './import-progress-dialog'

interface ImportExcelProps {
  onSuccess?: () => void
}

export function ImportVendorPoolButton({ onSuccess }: ImportExcelProps) {
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [isImporting, setIsImporting] = React.useState(false)
  const { data: session } = useSession()
  const [importResult, setImportResult] = React.useState<ImportResult | null>(null)
  const [showResultDialog, setShowResultDialog] = React.useState(false)
  
  // Progress 상태
  const [showProgressDialog, setShowProgressDialog] = React.useState(false)
  const [totalRows, setTotalRows] = React.useState(0)
  const [processedRows, setProcessedRows] = React.useState(0)

  // 헬퍼 함수들은 excel-utils에서 import

  const handleImport = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file) {
      debugWarn('[Import] 파일이 선택되지 않았습니다.')
      return
    }

    debugLog('[Import] 파일 임포트 시작:', {
      fileName: file.name,
      fileSize: file.size,
      fileType: file.type
    })

    setIsImporting(true)

    try {
      // DRM 복호화 처리
      debugProcess('[Import] DRM 복호화 시작')
      toast.info("파일을 복호화하고 있습니다...")
      let decryptedData: ArrayBuffer
      
      try {
        decryptedData = await decryptWithServerAction(file)
        debugSuccess('[Import] DRM 복호화 성공')
        toast.success("파일 복호화가 완료되었습니다.")
      } catch (drmError) {
        debugWarn('[Import] DRM 복호화 실패, 원본 파일로 진행:', drmError)
        console.warn("DRM 복호화 실패, 원본 파일로 진행합니다:", drmError)
        toast.warning("DRM 복호화에 실패했습니다. 원본 파일로 진행합니다.")
        decryptedData = await file.arrayBuffer()
        debugLog('[Import] 원본 파일 ArrayBuffer 로드 완료, size:', decryptedData.byteLength)
      }
      
      // 복호화된 데이터로 ExcelJS 워크북 로드
      debugProcess('[Import] ExcelJS 워크북 로드 시작')
      toast.info("엑셀 파일을 분석하고 있습니다...")
      const workbook = new ExcelJS.Workbook()
      await workbook.xlsx.load(decryptedData)
      debugSuccess('[Import] ExcelJS 워크북 로드 완료')

      // Get the first worksheet
      const worksheet = workbook.getWorksheet(1)
      if (!worksheet) {
        debugError('[Import] 워크시트를 찾을 수 없습니다.')
        toast.error("No worksheet found in the spreadsheet")
        return
      }
      debugLog('[Import] 워크시트 확인 완료:', {
        name: worksheet.name,
        rowCount: worksheet.rowCount,
        columnCount: worksheet.columnCount
      })

      // Check if there's an instruction row (템플릿 안내 텍스트가 있는지 확인)
      const firstRowText = getCellValueAsString(worksheet.getRow(1).getCell(1));
      const hasInstructionRow = firstRowText.includes('벤더풀 데이터 입력 템플릿') || 
                               firstRowText.includes('입력 가이드 시트') || 
                               firstRowText.includes('입력 가이드') || 
                               (worksheet.getRow(1).getCell(1).value !== null && 
                                worksheet.getRow(1).getCell(2).value === null);

      debugLog('[Import] 첫 번째 행 확인:', {
        firstRowText,
        hasInstructionRow
      })

      // Get header row index (row 2 if there's an instruction row, otherwise row 1)
      const headerRowIndex = hasInstructionRow ? 2 : 1;
      debugLog('[Import] 헤더 행 인덱스:', headerRowIndex)

      // Get column headers and their indices
      debugProcess('[Import] 컬럼 헤더 매핑 시작')
      const headerRow = worksheet.getRow(headerRowIndex);
      const columnIndices: Record<string, number> = {};

      headerRow.eachCell((cell, colNumber) => {
        const header = getCellValueAsString(cell);
        // Excel 헤더를 통해 accessorKey 찾기
        const accessorKey = getAccessorKeyByHeader(header);
        if (accessorKey) {
          columnIndices[accessorKey] = colNumber;
        }
      });

      debugLog('[Import] 컬럼 매핑 완료:', {
        mappedColumns: Object.keys(columnIndices).length,
        columnIndices
      })

      // Process data rows
      debugProcess('[Import] 데이터 행 처리 시작')
      const rows: any[] = [];
      const startRow = headerRowIndex + 1;
      let skippedRows = 0;

      for (let i = startRow; i <= worksheet.rowCount; i++) {
        const row = worksheet.getRow(i);

        // Skip empty rows
        if (row.cellCount === 0) {
          skippedRows++;
          continue;
        }

        // Check if this is likely an empty template row (빈 템플릿 행 건너뛰기)
        let hasAnyData = false;
        for (let col = 1; col <= row.cellCount; col++) {
          if (getCellValueAsString(row.getCell(col)).trim()) {
            hasAnyData = true;
            break;
          }
        }
        if (!hasAnyData) {
          skippedRows++;
          continue;
        }

        const rowData: Record<string, any> = {};
        let hasData = false;

        // Map the data using accessorKey indices
        Object.entries(columnIndices).forEach(([accessorKey, colIndex]) => {
          const value = getCellValueAsString(row.getCell(colIndex));
          if (value) {
            rowData[accessorKey] = value;
            hasData = true;
          }
        });

        if (hasData) {
          rows.push(rowData);
        } else {
          skippedRows++;
        }
      }

      debugLog('[Import] 데이터 행 처리 완료:', {
        totalRows: worksheet.rowCount - headerRowIndex,
        validRows: rows.length,
        skippedRows
      })

      if (rows.length === 0) {
        debugWarn('[Import] 유효한 데이터가 없습니다.')
        toast.error("No data found in the spreadsheet")
        setIsImporting(false)
        return
      }

      // Progress Dialog 표시
      setTotalRows(rows.length)
      setProcessedRows(0)
      setShowProgressDialog(true)

      // Process each row
      debugProcess('[Import] 데이터베이스 저장 시작')
      let successCount = 0;
      let errorCount = 0;
      let duplicateCount = 0;
      const resultItems: ImportResultItem[] = []; // 실패한 건만 포함

      // Create promises for all vendor pool creation operations
      const promises = rows.map(async (row, rowIndex) => {
        // Excel 컬럼 설정을 기반으로 데이터 매핑 (catch 블록에서도 사용하기 위해 밖에서 선언)
        const vendorPoolData: any = {};

        try {
          debugLog(`[Import] 행 ${rowIndex + 1}/${rows.length} 처리 시작 - 원본 데이터:`, row)
          
          vendorPoolExcelColumns.forEach(column => {
            const { accessorKey, type } = column;
            const value = row[accessorKey] || '';

            if (type === 'boolean') {
              vendorPoolData[accessorKey] = parseBoolean(String(value));
            } else if (value === '') {
              // 빈 문자열은 null로 설정 (스키마에 맞게)
              vendorPoolData[accessorKey] = null;
            } else {
              vendorPoolData[accessorKey] = String(value);
            }
          });

          // 현재 사용자 정보 추가
          vendorPoolData.registrant = session?.user?.name || 'system';
          vendorPoolData.lastModifier = session?.user?.name || 'system';

          debugLog(`[Import] 행 ${rowIndex + 1} 데이터 매핑 완료 - 전체 필드:`, {
            '공사부문': vendorPoolData.constructionSector,
            'H/T구분': vendorPoolData.htDivision,
            '설계기능코드': vendorPoolData.designCategoryCode,
            '설계기능': vendorPoolData.designCategory,
            'Equip/Bulk구분': vendorPoolData.equipBulkDivision,
            '협력업체코드': vendorPoolData.vendorCode,
            '협력업체명': vendorPoolData.vendorName,
            '자재그룹코드': vendorPoolData.materialGroupCode,
            '자재그룹명': vendorPoolData.materialGroupName,
            '계약서명주체코드': vendorPoolData.contractSignerCode,
            '계약서명주체명': vendorPoolData.contractSignerName,
            '사업자번호': vendorPoolData.taxId,
            '패키지코드': vendorPoolData.packageCode,
            '패키지명': vendorPoolData.packageName
          })

          // 코드를 기반으로 자동완성 수행
          debugProcess(`[Import] 행 ${rowIndex + 1} enrichment 시작`);
          const enrichmentResult = await enrichVendorPoolData({
            designCategoryCode: vendorPoolData.designCategoryCode,
            designCategory: vendorPoolData.designCategory,
            materialGroupCode: vendorPoolData.materialGroupCode,
            materialGroupName: vendorPoolData.materialGroupName,
            vendorCode: vendorPoolData.vendorCode,
            vendorName: vendorPoolData.vendorName,
            contractSignerCode: vendorPoolData.contractSignerCode,
            contractSignerName: vendorPoolData.contractSignerName,
          });

          // enrichment 결과 적용
          if (enrichmentResult.enrichedFields.length > 0) {
            debugSuccess(`[Import] 행 ${rowIndex + 1} enrichment 완료 - 자동완성된 필드: ${enrichmentResult.enrichedFields.join(', ')}`);
            
            // enrichment된 데이터를 vendorPoolData에 반영
            if (enrichmentResult.enriched.designCategory) {
              vendorPoolData.designCategory = enrichmentResult.enriched.designCategory;
            }
            if (enrichmentResult.enriched.materialGroupName) {
              vendorPoolData.materialGroupName = enrichmentResult.enriched.materialGroupName;
            }
            if (enrichmentResult.enriched.vendorName) {
              vendorPoolData.vendorName = enrichmentResult.enriched.vendorName;
            }
            if (enrichmentResult.enriched.contractSignerName) {
              vendorPoolData.contractSignerName = enrichmentResult.enriched.contractSignerName;
            }
          }

          // enrichment 경고 메시지 로깅만 (resultItems에 추가하지 않음)
          if (enrichmentResult.warnings.length > 0) {
            debugWarn(`[Import] 행 ${rowIndex + 1} enrichment 경고:`, enrichmentResult.warnings);
            enrichmentResult.warnings.forEach(warning => {
              console.warn(`Row ${rowIndex + 1}: ${warning}`);
            });
          }

          // Validate required fields (필수 필드 검증)
          // 자동완성 가능한 필드는 코드가 있으면 명칭은 optional로 처리
          const requiredFieldsCheck = {
            constructionSector: { value: vendorPoolData.constructionSector, label: '공사부문' },
            htDivision: { value: vendorPoolData.htDivision, label: 'H/T구분' },
            designCategoryCode: { value: vendorPoolData.designCategoryCode, label: '설계기능코드' }
          };

          // 설계기능: 설계기능코드가 없으면 설계기능명 필수
          if (!vendorPoolData.designCategoryCode && !vendorPoolData.designCategory) {
            requiredFieldsCheck['designCategory'] = { value: vendorPoolData.designCategory, label: '설계기능' };
          }

          // 협력업체명: 협력업체코드가 없으면 협력업체명 필수
          if (!vendorPoolData.vendorCode && !vendorPoolData.vendorName) {
            requiredFieldsCheck['vendorName'] = { value: vendorPoolData.vendorName, label: '협력업체명' };
          }

          const missingRequiredFields = Object.entries(requiredFieldsCheck)
            .filter(([_, field]) => !field.value)
            .map(([key, field]) => `${field.label}(${key})`);

          if (missingRequiredFields.length > 0) {
            debugError(`[Import] 행 ${rowIndex + 1} 필수 필드 누락 [${missingRequiredFields.length}개]:`, {
              missingFields: missingRequiredFields,
              currentData: vendorPoolData
            });
            console.error(`Missing required fields in row ${rowIndex + 1}:`, missingRequiredFields.join(', '));
            errorCount++;
            resultItems.push({
              rowNumber: rowIndex + 1,
              status: 'error',
              message: `필수 필드 누락: ${missingRequiredFields.join(', ')}`,
              data: {
                vendorName: vendorPoolData.vendorName,
                materialGroupName: vendorPoolData.materialGroupName,
                designCategory: vendorPoolData.designCategory,
              }
            });
            
            // Progress 업데이트
            setProcessedRows(prev => prev + 1);
            
            return null;
          }
          
          debugSuccess(`[Import] 행 ${rowIndex + 1} 필수 필드 검증 통과`);

          // Validate field lengths and formats (필드 길이 및 형식 검증)
          const validationErrors: string[] = [];

          if (vendorPoolData.designCategoryCode && vendorPoolData.designCategoryCode.length > 2) {
            validationErrors.push(`설계기능코드는 2자리 이하여야 합니다: ${vendorPoolData.designCategoryCode}`);
          }

          if (vendorPoolData.equipBulkDivision && vendorPoolData.equipBulkDivision.length > 1) {
            validationErrors.push(`Equip/Bulk 구분은 1자리여야 합니다: ${vendorPoolData.equipBulkDivision}`);
          }

          if (vendorPoolData.constructionSector && !['조선', '해양'].includes(vendorPoolData.constructionSector)) {
            validationErrors.push(`공사부문은 '조선' 또는 '해양'이어야 합니다: ${vendorPoolData.constructionSector}`);
          }

          if (vendorPoolData.htDivision && !['H', 'T', '공통'].includes(vendorPoolData.htDivision)) {
            validationErrors.push(`H/T구분은 'H', 'T' 또는 '공통'이어야 합니다: ${vendorPoolData.htDivision}`);
          }

          if (validationErrors.length > 0) {
            debugError(`[Import] 행 ${rowIndex + 1} 검증 실패 [${validationErrors.length}개 오류]:`, {
              errors: validationErrors,
              problematicFields: {
                designCategoryCode: vendorPoolData.designCategoryCode,
                equipBulkDivision: vendorPoolData.equipBulkDivision,
                constructionSector: vendorPoolData.constructionSector,
                htDivision: vendorPoolData.htDivision
              }
            });
            console.error(`Validation errors in row ${rowIndex + 1}:`, validationErrors.join(' | '));
            errorCount++;
            resultItems.push({
              rowNumber: rowIndex + 1,
              status: 'error',
              message: `검증 실패: ${validationErrors.join(', ')}`,
              data: {
                vendorName: vendorPoolData.vendorName,
                materialGroupName: vendorPoolData.materialGroupName,
                designCategory: vendorPoolData.designCategory,
              }
            });
            
            // Progress 업데이트
            setProcessedRows(prev => prev + 1);
            
            return null;
          }
          
          debugSuccess(`[Import] 행 ${rowIndex + 1} 형식 검증 통과`);

          if (!session || !session.user || !session.user.id) {
            debugError(`[Import] 행 ${rowIndex + 1} 세션 오류: 로그인 정보 없음`);
            toast.error("인증 오류. 로그인 정보를 찾을 수 없습니다.")
            return
          }

          // Create the vendor pool entry
          debugProcess(`[Import] 행 ${rowIndex + 1} 데이터베이스 저장 시도`);
          const result = await createVendorPool(vendorPoolData as any)

          if (!result) {
            debugError(`[Import] 행 ${rowIndex + 1} 저장 실패: createVendorPool returned null`);
            console.error(`Failed to import row - createVendorPool returned null:`, vendorPoolData);
            errorCount++;
            resultItems.push({
              rowNumber: rowIndex + 1,
              status: 'error',
              message: '데이터 저장 실패',
              data: {
                vendorName: vendorPoolData.vendorName,
                materialGroupName: vendorPoolData.materialGroupName,
                designCategory: vendorPoolData.designCategory,
              }
            });
            
            // Progress 업데이트
            setProcessedRows(prev => prev + 1);
            
            return null;
          }

          debugSuccess(`[Import] 행 ${rowIndex + 1} 저장 성공 (ID: ${result.id})`);
          successCount++;
          // 성공한 건은 resultItems에 추가하지 않음
          
          // Progress 업데이트
          setProcessedRows(prev => prev + 1);
          
          return result;
        } catch (error) {
          debugError(`[Import] 행 ${rowIndex + 1} 처리 중 예외 발생:`, error);
          console.error("Error processing row:", error, row);

          // Unique 제약 조건 위반 감지 (중복 데이터)
          const errorMessage = error instanceof Error ? error.message : String(error);
          if (errorMessage === 'DUPLICATE_VENDOR_POOL') {
            debugWarn(`[Import] 행 ${rowIndex + 1} 중복 데이터 감지:`, {
              constructionSector: vendorPoolData.constructionSector,
              htDivision: vendorPoolData.htDivision,
              materialGroupCode: vendorPoolData.materialGroupCode,
              vendorName: vendorPoolData.vendorName
            });
            duplicateCount++;
            // 중복 건은 resultItems에 추가하지 않음
            
            // Progress 업데이트
            setProcessedRows(prev => prev + 1);
            
            return null;
          }

          // 다른 에러의 경우 에러 카운트 증가
          errorCount++;
          resultItems.push({
            rowNumber: rowIndex + 1,
            status: 'error',
            message: `처리 중 오류 발생: ${errorMessage}`,
            data: {
              vendorName: vendorPoolData.vendorName,
              materialGroupName: vendorPoolData.materialGroupName,
              designCategory: vendorPoolData.designCategory,
            }
          });
          
          // Progress 업데이트
          setProcessedRows(prev => prev + 1);
          
          return null;
        }
      });

      // Wait for all operations to complete
      debugProcess('[Import] 모든 Promise 완료 대기 중...')
      await Promise.all(promises);
      debugSuccess('[Import] 모든 데이터 처리 완료')

      debugLog('[Import] 최종 결과:', {
        totalRows: rows.length,
        successCount,
        errorCount,
        duplicateCount
      })

      // Progress Dialog 닫기
      setShowProgressDialog(false)

      // Import 결과 Dialog 데이터 생성 (실패한 건만 포함)
      const result: ImportResult = {
        totalRows: rows.length,
        successCount,
        errorCount,
        duplicateCount,
        items: resultItems // 실패한 건만 포함됨
      }

      // Show results
      if (successCount > 0) {
        debugSuccess(`[Import] 임포트 성공: ${successCount}개 항목`);
        toast.success(`${successCount}개 항목이 성공적으로 가져와졌습니다.`);

        if (errorCount > 0) {
          debugWarn(`[Import] 일부 실패: ${errorCount}개 항목`);
        }
        // Call the success callback to refresh data
        onSuccess?.();
      } else if (errorCount > 0) {
        debugError(`[Import] 모든 항목 실패: ${errorCount}개`);
        toast.error(`모든 ${errorCount}개 항목 가져오기에 실패했습니다. 데이터 형식을 확인하세요.`);
      }

      if (duplicateCount > 0) {
        debugWarn(`[Import] 중복 데이터: ${duplicateCount}개`);
        toast.warning(`${duplicateCount}개의 중복 데이터가 감지되었습니다.`);
      }

      // Import 결과 Dialog 표시
      setImportResult(result);
      setShowResultDialog(true);

    } catch (error) {
      debugError('[Import] 전체 임포트 프로세스 실패:', error);
      console.error("Import error:", error);
      toast.error("Error importing data. Please check file format.");
      setShowProgressDialog(false);
    } finally {
      debugLog('[Import] 임포트 프로세스 종료');
      setIsImporting(false);
      setShowProgressDialog(false);
      // Reset the file input
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    }
  }

  return (
    <>
      <Input
        type="file"
        ref={fileInputRef}
        onChange={handleImport}
        accept=".xlsx,.xls"
        className="hidden"
      />
      <Button
        variant="outline"
        size="sm"
        onClick={() => fileInputRef.current?.click()}
        disabled={isImporting}
        className="gap-2"
      >
        {isImporting ? (
          <Loader className="size-4 animate-spin" aria-hidden="true" />
        ) : (
          <Upload className="size-4" aria-hidden="true" />
        )}
        <span className="hidden sm:inline">
          {isImporting ? "Importing..." : "Import"}
        </span>
      </Button>

      {/* Import Progress Dialog */}
      <ImportProgressDialog
        open={showProgressDialog}
        totalRows={totalRows}
        processedRows={processedRows}
      />

      {/* Import 결과 Dialog */}
      <ImportResultDialog
        open={showResultDialog}
        onOpenChange={setShowResultDialog}
        result={importResult}
      />
    </>
  )
}
