"use client";

import { useState, useTransition, useMemo } 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 { RefreshCw, Search, X, Check, ChevronsUpDown, Upload } from "lucide-react";
import { syncSwpProjectAction, uploadSwpFilesAction, type SwpTableFilters } from "../actions";
import { useToast } from "@/hooks/use-toast";
import { useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import { useRef } from "react";
import { SwpUploadHelpDialog } from "./swp-help-dialog";
import { SwpUploadResultDialog } from "./swp-upload-result-dialog";

interface SwpTableToolbarProps {
  filters: SwpTableFilters;
  onFiltersChange: (filters: SwpTableFilters) => void;
  projects?: Array<{ PROJ_NO: string; PROJ_NM: string }>;
  vendorCode?: string; // 벤더가 접속했을 때 고정할 벤더 코드
}

export function SwpTableToolbar({
  filters,
  onFiltersChange,
  projects = [],
  vendorCode,
}: SwpTableToolbarProps) {
  const [isSyncing, startSync] = useTransition();
  const [isUploading, startUpload] = useTransition();
  const [localFilters, setLocalFilters] = useState<SwpTableFilters>(filters);
  const { toast } = useToast();
  const router = useRouter();
  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 handleSync = () => {
    const projectNo = localFilters.projNo;
    
    if (!projectNo) {
      toast({
        variant: "destructive",
        title: "프로젝트 선택 필요",
        description: "동기화할 프로젝트를 먼저 선택해주세요.",
      });
      return;
    }

    startSync(async () => {
      try {
        toast({
          title: "동기화 시작",
          description: `프로젝트 ${projectNo} 동기화를 시작합니다...`,
        });

        const result = await syncSwpProjectAction(projectNo, "V");

        if (result.success) {
          toast({
            title: "동기화 완료",
            description: `문서 ${result.stats.documents.total}개, 파일 ${result.stats.files.total}개 동기화 완료`,
          });
          
          // 페이지 새로고침
          router.refresh();
        } else {
          throw new Error(result.errors.join(", "));
        }
      } catch (error) {
        console.error("동기화 실패:", error);
        toast({
          variant: "destructive",
          title: "동기화 실패",
          description: error instanceof Error ? error.message : "알 수 없는 오류",
        });
      }
    });
  };

  /**
   * 파일 업로드 핸들러
   * 1) 네트워크 드라이브에 정해진 규칙대로, 파일이름 기반으로 파일 업로드하기
   * 2) 1~N개 파일 받아서, 파일 이름 기준으로 파싱해서 SaveInBoxList API를 통해 업로드 처리
  */ 
  const handleUploadFiles = () => {
    // 프로젝트와 벤더 코드 체크
    const projectNo = localFilters.projNo;
    const vndrCd = vendorCode || localFilters.vndrCd;

    if (!projectNo) {
      toast({
        variant: "destructive",
        title: "프로젝트 선택 필요",
        description: "파일을 업로드할 프로젝트를 먼저 선택해주세요.",
      });
      return;
    }

    if (!vndrCd) {
      toast({
        variant: "destructive",
        title: "업체 코드 입력 필요",
        description: "파일을 업로드할 업체 코드를 입력해주세요.",
      });
      return;
    }

    // 파일 선택 다이얼로그 열기
    fileInputRef.current?.click();
  };

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

    const projectNo = localFilters.projNo!;
    const vndrCd = vendorCode || localFilters.vndrCd!;

    startUpload(async () => {
      try {
        toast({
          title: "파일 업로드 시작",
          description: `${selectedFiles.length}개 파일을 업로드합니다...`,
        });

        // 파일을 Buffer로 변환
        const fileInfos = await Promise.all(
          Array.from(selectedFiles).map(async (file) => {
            const arrayBuffer = await file.arrayBuffer();
            return {
              fileName: file.name,
              fileBuffer: Buffer.from(arrayBuffer),
            };
          })
        );

        // 서버 액션 호출
        const result = await uploadSwpFilesAction(projectNo, vndrCd, fileInfos);

        // 결과 저장 및 다이얼로그 표시
        setUploadResults(result.details);
        setShowResultDialog(true);

        // 성공한 파일이 있으면 페이지 새로고침
        const successCount = result.details.filter((d) => d.success).length;
        if (successCount > 0) {
          router.refresh();
        }
      } catch (error) {
        console.error("파일 업로드 실패:", error);
        
        // 예외 발생 시에도 결과 다이얼로그 표시
        const errorResults = Array.from(selectedFiles).map((file) => ({
          fileName: file.name,
          success: false,
          error: error instanceof Error ? error.message : "알 수 없는 오류",
        }));
        
        setUploadResults(errorResults);
        setShowResultDialog(true);
      } finally {
        // 파일 입력 초기화
        if (fileInputRef.current) {
          fileInputRef.current.value = "";
        }
      }
    });
  };

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

  // 검색 초기화
  const handleReset = () => {
    const resetFilters: SwpTableFilters = {};
    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)
    );
  }, [projects, projectSearch]);

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

      <div className="space-y-4">
        {/* 상단 액션 바 */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Button
              onClick={handleSync}
              disabled={isSyncing || !localFilters.projNo}
              size="sm"
            >
              <RefreshCw className={`h-4 w-4 mr-2 ${isSyncing ? "animate-spin" : ""}`} />
              {isSyncing ? "동기화 중..." : "SWP 동기화"}
            </Button>
          </div>
          
          <div className="flex items-center gap-2">
            {/* 벤더만 파일 업로드 기능 사용 가능 */}
            {vendorCode && (
              <>
                <input
                  ref={fileInputRef}
                  type="file"
                  multiple
                  className="hidden"
                  onChange={handleFileChange}
                  accept="*/*"
                />
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleUploadFiles}
                  disabled={isUploading || !localFilters.projNo || (!vendorCode && !localFilters.vndrCd)}
                >
                  <Upload className={`h-4 w-4 mr-2 ${isUploading ? "animate-pulse" : ""}`} />
                  {isUploading ? "업로드 중..." : "파일 업로드"}
                </Button>

                <SwpUploadHelpDialog />
              </>
            )}
          </div>
        </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"
                  >
                    {localFilters.projNo ? (
                      <span>
                        {projects.find((p) => p.PROJ_NO === localFilters.projNo)?.PROJ_NO || localFilters.projNo}
                        {" ["}
                        {projects.find((p) => p.PROJ_NO === localFilters.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">
                      <Button
                        variant="ghost"
                        className="w-full justify-start font-normal"
                        onClick={() => {
                          setLocalFilters({ ...localFilters, projNo: undefined });
                          setProjectSearchOpen(false);
                          setProjectSearch("");
                        }}
                      >
                        <Check
                          className={cn(
                            "mr-2 h-4 w-4",
                            !localFilters.projNo ? "opacity-100" : "opacity-0"
                          )}
                        />
                        전체
                      </Button>
                      {filteredProjects.map((proj) => (
                        <Button
                          key={proj.PROJ_NO}
                          variant="ghost"
                          className="w-full justify-start font-normal"
                          onClick={() => {
                            setLocalFilters({ ...localFilters, projNo: proj.PROJ_NO });
                            setProjectSearchOpen(false);
                            setProjectSearch("");
                          }}
                        >
                          <Check
                            className={cn(
                              "mr-2 h-4 w-4",
                              localFilters.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={localFilters.projNo || ""}
                onChange={(e) =>
                  setLocalFilters({ ...localFilters, projNo: e.target.value })
                }
                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="vndrCd">업체 코드</Label>
            <Input
              id="vndrCd"
              placeholder="업체 코드"
              value={vendorCode || localFilters.vndrCd || ""}
              onChange={(e) =>
                setLocalFilters({ ...localFilters, vndrCd: e.target.value })
              }
              disabled={!!vendorCode} // 벤더 코드가 제공되면 입력 비활성화
              className={vendorCode ? "bg-muted" : ""}
            />
          </div>

          {/* 스테이지 */}
          <div className="space-y-2">
            <Label htmlFor="stage">스테이지</Label>
            <Input
              id="stage"
              placeholder="스테이지 입력"
              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>
    </>
  );
}

