"use client";

import { useState, useTransition, useMemo, useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Label } from "@/components/ui/label";
import { Search, X, Check, ChevronsUpDown, Upload, RefreshCw } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { cn } from "@/lib/utils";
import { SwpUploadHelpDialog } from "./swp-help-dialog";
import { SwpUploadResultDialog } from "./swp-upload-result-dialog";
import { 
  SwpUploadValidationDialog, 
  validateFileName 
} from "./swp-upload-validation-dialog";
import { SwpUploadedFilesDialog } from "./swp-uploaded-files-dialog";

interface SwpTableFilters {
  docNo?: string;
  docTitle?: string;
  pkgNo?: string;
  stage?: string;
}

interface SwpTableToolbarProps {
  projNo: string;
  filters: SwpTableFilters;
  onProjNoChange: (projNo: string) => void;
  onFiltersChange: (filters: SwpTableFilters) => void;
  onRefresh: () => void;
  isRefreshing: boolean;
  projects?: Array<{ PROJ_NO: string; PROJ_NM: string | null }>;
  vendorCode?: string;
  droppedFiles?: File[];
  onFilesProcessed?: () => void;
  documents?: Array<{ OWN_DOC_NO: string | null }>; // 업로드 권한 검증용 문서 목록 (OWN_DOC_NO 기준)
  userId?: string; // 파일 취소 시 필요
}

export function SwpTableToolbar({
  projNo,
  filters,
  onProjNoChange,
  onFiltersChange,
  onRefresh,
  isRefreshing,
  projects = [],
  vendorCode,
  droppedFiles = [],
  onFilesProcessed,
  documents = [],
  userId,
}: SwpTableToolbarProps) {
  const [isUploading, startUpload] = useTransition();
  const [localFilters, setLocalFilters] = useState(filters);
  const { toast } = useToast();
  const [projectSearchOpen, setProjectSearchOpen] = useState(false);
  const [projectSearch, setProjectSearch] = useState("");
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [uploadResults, setUploadResults] = useState<Array<{ fileName: string; success: boolean; error?: string }>>([]);
  const [showResultDialog, setShowResultDialog] = useState(false);
  
  // 검증 다이얼로그 상태
  const [validationResults, setValidationResults] = useState<Array<{
    file: File;
    valid: boolean;
    parsed?: {
      ownDocNo: string;
      revNo: string;
      stage: string;
      fileName: string;
      extension: string;
    };
    error?: string;
  }>>([]);
  const [showValidationDialog, setShowValidationDialog] = useState(false);

  /**
   * 업로드 가능한 문서번호 목록 추출 (OWN_DOC_NO 기준)
   */
  const availableDocNos = useMemo(() => {
    return documents
      .map(doc => doc.OWN_DOC_NO)
      .filter((ownDocNo): ownDocNo is string => ownDocNo !== null && ownDocNo !== undefined);
  }, [documents]);

  /**
   * 벤더 모드 여부 (벤더 코드가 있으면 벤더 모드)
   */
  const isVendorMode = !!vendorCode;

  /**
   * 드롭된 파일 처리 - useEffect로 감지하여 자동 검증
   */
  useEffect(() => {
    if (droppedFiles.length > 0) {
      // 프로젝트와 벤더 코드 검증
      if (!projNo) {
        toast({
          variant: "destructive",
          title: "프로젝트 선택 필요",
          description: "파일을 업로드할 프로젝트를 먼저 선택해주세요.",
        });
        onFilesProcessed?.();
        return;
      }

      if (!vendorCode) {
        toast({
          variant: "destructive",
          title: "업체 코드 오류",
          description: "벤더 정보를 가져올 수 없습니다.",
        });
        onFilesProcessed?.();
        return;
      }

      // 파일명 검증 (문서번호 권한 포함)
      const results = droppedFiles.map((file) => {
        const validation = validateFileName(file.name, availableDocNos, isVendorMode);
        return {
          file,
          valid: validation.valid,
          parsed: validation.parsed,
          error: validation.error,
        };
      });

      setValidationResults(results);
      setShowValidationDialog(true);
      onFilesProcessed?.();
    }
  }, [droppedFiles, projNo, vendorCode, toast, onFilesProcessed, availableDocNos, isVendorMode]);

  /**
   * 파일 업로드 핸들러
   */
  const handleUploadFiles = () => {
    if (!projNo) {
      toast({
        variant: "destructive",
        title: "프로젝트 선택 필요",
        description: "파일을 업로드할 프로젝트를 먼저 선택해주세요.",
      });
      return;
    }

    if (!vendorCode) {
      toast({
        variant: "destructive",
        title: "업체 코드 오류",
        description: "벤더 정보를 가져올 수 없습니다.",
      });
      return;
    }

    fileInputRef.current?.click();
  };

  /**
   * 파일 선택 핸들러 - 검증만 수행
   */
  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = event.target.files;
    if (!selectedFiles || selectedFiles.length === 0) {
      return;
    }

    // 각 파일의 파일명 검증 (문서번호 권한 포함)
    const results = Array.from(selectedFiles).map((file) => {
      const validation = validateFileName(file.name, availableDocNos, isVendorMode);
      return {
        file,
        valid: validation.valid,
        parsed: validation.parsed,
        error: validation.error,
      };
    });

    setValidationResults(results);
    setShowValidationDialog(true);

    // input 초기화 (같은 파일 재선택 가능하도록)
    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
  };

  /**
   * 검증 완료 후 실제 업로드 실행
   */
  const handleConfirmUpload = async (validFiles: File[]) => {
    startUpload(async () => {
      try {
        toast({
          title: "파일 업로드 시작",
          description: `${validFiles.length}개 파일을 업로드합니다...`,
        });

        const formData = new FormData();
        formData.append("projNo", projNo);
        formData.append("vndrCd", vendorCode!);

        validFiles.forEach((file) => {
          formData.append("files", file);
        });

        const response = await fetch("/api/swp/upload", {
          method: "POST",
          body: formData,
        });

        if (!response.ok) {
          throw new Error(`업로드 실패: ${response.statusText}`);
        }

        const result = await response.json();

        // 검증 다이얼로그 닫기
        setShowValidationDialog(false);

        // 결과 다이얼로그 표시
        setUploadResults(result.details || []);
        setShowResultDialog(true);

        toast({
          title: result.success ? "업로드 완료" : "일부 업로드 실패",
          description: result.message,
        });
      } catch (error) {
        console.error("파일 업로드 실패:", error);

        // 검증 다이얼로그 닫기
        setShowValidationDialog(false);

        const errorResults = validFiles.map((file) => ({
          fileName: file.name,
          success: false,
          error: error instanceof Error ? error.message : "알 수 없는 오류",
        }));

        setUploadResults(errorResults);
        setShowResultDialog(true);
      }
    });
  };

  // 검색 적용
  const handleSearch = () => {
    onFiltersChange(localFilters);
  };

  // 검색 초기화
  const handleReset = () => {
    const resetFilters: SwpTableFilters = {
      docNo: "",
      docTitle: "",
      pkgNo: "",
      stage: "",
    };
    setLocalFilters(resetFilters);
    onFiltersChange(resetFilters);
  };

  // 프로젝트 필터링
  const filteredProjects = useMemo(() => {
    if (!projectSearch) return projects;

    const search = projectSearch.toLowerCase();
    return projects.filter(
      (proj) =>
        proj.PROJ_NO.toLowerCase().includes(search) ||
        (proj.PROJ_NM?.toLowerCase().includes(search) ?? false)
    );
  }, [projects, projectSearch]);

  return (
    <>
      {/* 업로드 검증 다이얼로그 */}
      <SwpUploadValidationDialog
        open={showValidationDialog}
        onOpenChange={setShowValidationDialog}
        validationResults={validationResults}
        onConfirmUpload={handleConfirmUpload}
        isUploading={isUploading}
        availableDocNos={availableDocNos}
        isVendorMode={isVendorMode}
      />

      {/* 업로드 결과 다이얼로그 */}
      <SwpUploadResultDialog
        open={showResultDialog}
        onOpenChange={setShowResultDialog}
        results={uploadResults}
      />

      <div className="space-y-4 w-full">
        {/* 상단 액션 바 */}
        {vendorCode && (
          <div className="flex items-center justify-end gap-2">
            <input
              ref={fileInputRef}
              type="file"
              multiple
              className="hidden"
              onChange={handleFileChange}
              accept="*/*"
            />
            <Button
              variant="outline"
              size="sm"
              onClick={onRefresh}
              disabled={isRefreshing || !projNo}
            >
              <RefreshCw className={`h-4 w-4 mr-2 ${isRefreshing ? "animate-spin" : ""}`} />
              새로고침
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={handleUploadFiles}
              disabled={isUploading || !projNo}
            >
              <Upload className={`h-4 w-4 mr-2 ${isUploading ? "animate-pulse" : ""}`} />
              {isUploading ? "업로드 중..." : "파일 업로드"}
            </Button>

            {userId && (
              <SwpUploadedFilesDialog
                projNo={projNo}
                vndrCd={vendorCode}
                userId={userId}
              />
            )}

            <SwpUploadHelpDialog />
          </div>
        )}

        {/* 검색 필터 */}
        <div className="rounded-lg border p-4 space-y-4">
          <div className="flex items-center justify-between">
            <h3 className="text-sm font-semibold">검색 필터</h3>
            <Button
              variant="ghost"
              size="sm"
              onClick={handleReset}
              className="h-8"
            >
              <X className="h-4 w-4 mr-1" />
              초기화
            </Button>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {/* 프로젝트 번호 */}
            <div className="space-y-2">
              <Label htmlFor="projNo">프로젝트 번호</Label>
              {projects.length > 0 ? (
                <Popover open={projectSearchOpen} onOpenChange={setProjectSearchOpen}>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={projectSearchOpen}
                      className="w-full justify-between"
                    >
                      {projNo ? (
                        <span>
                          {projects.find((p) => p.PROJ_NO === projNo)?.PROJ_NO || projNo}
                          {" ["}
                          {projects.find((p) => p.PROJ_NO === projNo)?.PROJ_NM}
                          {"]"}
                        </span>
                      ) : (
                        <span className="text-muted-foreground">프로젝트 선택</span>
                      )}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-[400px] p-0" align="start">
                    <div className="p-2">
                      <div className="flex items-center border rounded-md px-3">
                        <Search className="h-4 w-4 mr-2 opacity-50" />
                        <Input
                          placeholder="프로젝트 번호 또는 이름으로 검색..."
                          value={projectSearch}
                          onChange={(e) => setProjectSearch(e.target.value)}
                          className="border-0 focus-visible:ring-0 focus-visible:ring-offset-0"
                        />
                      </div>
                    </div>
                    <div className="max-h-[300px] overflow-y-auto">
                      <div className="p-1">
                        {filteredProjects.map((proj) => (
                          <Button
                            key={proj.PROJ_NO}
                            variant="ghost"
                            className="w-full justify-start font-normal"
                            onClick={() => {
                              onProjNoChange(proj.PROJ_NO);
                              setProjectSearchOpen(false);
                              setProjectSearch("");
                            }}
                          >
                            <Check
                              className={cn(
                                "mr-2 h-4 w-4",
                                projNo === proj.PROJ_NO ? "opacity-100" : "opacity-0"
                              )}
                            />
                            <span className="font-mono text-sm">{proj.PROJ_NO} [{proj.PROJ_NM || ""}]</span>
                          </Button>
                        ))}
                        {filteredProjects.length === 0 && (
                          <div className="py-6 text-center text-sm text-muted-foreground">
                            검색 결과가 없습니다.
                          </div>
                        )}
                      </div>
                    </div>
                  </PopoverContent>
                </Popover>
              ) : (
                <Input
                  id="projNo"
                  placeholder="계약된 프로젝트가 없습니다"
                  value={projNo}
                  disabled
                  className="bg-muted"
                />
              )}
            </div>

            {/* 문서 번호 */}
            <div className="space-y-2">
              <Label htmlFor="docNo">문서 번호</Label>
              <Input
                id="docNo"
                placeholder="문서 번호 검색"
                value={localFilters.docNo || ""}
                onChange={(e) =>
                  setLocalFilters({ ...localFilters, docNo: e.target.value })
                }
              />
            </div>

            {/* 문서 제목 */}
            <div className="space-y-2">
              <Label htmlFor="docTitle">문서 제목</Label>
              <Input
                id="docTitle"
                placeholder="제목 검색"
                value={localFilters.docTitle || ""}
                onChange={(e) =>
                  setLocalFilters({ ...localFilters, docTitle: e.target.value })
                }
              />
            </div>

            {/* 패키지 번호 */}
            <div className="space-y-2">
              <Label htmlFor="pkgNo">패키지</Label>
              <Input
                id="pkgNo"
                placeholder="패키지 번호"
                value={localFilters.pkgNo || ""}
                onChange={(e) =>
                  setLocalFilters({ ...localFilters, pkgNo: e.target.value })
                }
              />
            </div>

            {/* 스테이지 */}
            <div className="space-y-2">
              <Label htmlFor="stage">스테이지</Label>
              <Input
                id="stage"
                placeholder="스테이지 입력 (예: IFC, IFA)"
                value={localFilters.stage || ""}
                onChange={(e) =>
                  setLocalFilters({ ...localFilters, stage: e.target.value })
                }
              />
            </div>
          </div>

          <div className="flex justify-end">
            <Button onClick={handleSearch} size="sm">
              <Search className="h-4 w-4 mr-2" />
              검색
            </Button>
          </div>
        </div>
      </div>
    </>
  );
}
