"use client";

import { useState, useTransition, useMemo } from "react";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
import { FileText, ChevronRight, ChevronDown, X, Loader2, RefreshCw } from "lucide-react";
import { fetchVendorUploadedFiles, cancelVendorUploadedFile } from "../actions";
import type { SwpFileApiResponse } from "../api-client";

interface SwpUploadedFilesDialogProps {
  projNo: string;
  vndrCd: string;
  userId: string;
}

interface FileTreeNode {
  files: SwpFileApiResponse[];
}

interface RevisionTreeNode {
  revNo: string;
  files: FileTreeNode;
}

interface DocumentTreeNode {
  docNo: string;
  revisions: Map<string, RevisionTreeNode>;
}

export function SwpUploadedFilesDialog({ projNo, vndrCd, userId }: SwpUploadedFilesDialogProps) {
  const [open, setOpen] = useState(false);
  const [files, setFiles] = useState<SwpFileApiResponse[]>([]);
  const [isLoading, startLoading] = useTransition();
  const [expandedDocs, setExpandedDocs] = useState<Set<string>>(new Set());
  const [expandedRevs, setExpandedRevs] = useState<Set<string>>(new Set());
  const [cancellingFiles, setCancellingFiles] = useState<Set<string>>(new Set());
  const { toast } = useToast();

  // 파일 목록을 트리 구조로 변환
  const fileTree = useMemo(() => {
    const tree = new Map<string, DocumentTreeNode>();

    files.forEach((file) => {
      const docNo = file.OWN_DOC_NO;
      const revNo = file.REV_NO;

      if (!tree.has(docNo)) {
        tree.set(docNo, {
          docNo,
          revisions: new Map(),
        });
      }

      const docNode = tree.get(docNo)!;

      if (!docNode.revisions.has(revNo)) {
        docNode.revisions.set(revNo, {
          revNo,
          files: { files: [] },
        });
      }

      const revNode = docNode.revisions.get(revNo)!;
      revNode.files.files.push(file);
    });

    return tree;
  }, [files]);

  // 다이얼로그 열릴 때 파일 목록 조회
  const handleOpenChange = (newOpen: boolean) => {
    setOpen(newOpen);
    if (newOpen) {
      loadFiles();
    }
  };

  // 파일 목록 조회
  const loadFiles = () => {
    if (!projNo || !vndrCd) {
      toast({
        variant: "destructive",
        title: "조회 불가",
        description: "프로젝트와 업체 정보가 필요합니다.",
      });
      return;
    }

    startLoading(async () => {
      try {
        const result = await fetchVendorUploadedFiles(projNo, vndrCd);
        setFiles(result);
        toast({
          title: "조회 완료",
          description: `${result.length}개의 파일을 조회했습니다.`,
        });
      } catch (error) {
        console.error("파일 목록 조회 실패:", error);
        toast({
          variant: "destructive",
          title: "조회 실패",
          description: error instanceof Error ? error.message : "알 수 없는 오류",
        });
      }
    });
  };

  // 파일 취소
  const handleCancelFile = async (file: SwpFileApiResponse) => {
    if (!file.BOX_SEQ || !file.ACTV_SEQ) {
      toast({
        variant: "destructive",
        title: "취소 불가",
        description: "파일 정보가 올바르지 않습니다.",
      });
      return;
    }

    const fileKey = `${file.BOX_SEQ}_${file.ACTV_SEQ}`;
    setCancellingFiles((prev) => new Set(prev).add(fileKey));

    try {
      await cancelVendorUploadedFile({
        boxSeq: file.BOX_SEQ,
        actvSeq: file.ACTV_SEQ,
        userId,
      });

      toast({
        title: "취소 완료",
        description: `${file.FILE_NM} 파일이 취소되었습니다.`,
      });

      // 목록 새로고침
      loadFiles();
    } catch (error) {
      console.error("파일 취소 실패:", error);
      toast({
        variant: "destructive",
        title: "취소 실패",
        description: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    } finally {
      setCancellingFiles((prev) => {
        const newSet = new Set(prev);
        newSet.delete(fileKey);
        return newSet;
      });
    }
  };

  // 문서 토글
  const toggleDoc = (docNo: string) => {
    setExpandedDocs((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(docNo)) {
        newSet.delete(docNo);
      } else {
        newSet.add(docNo);
      }
      return newSet;
    });
  };

  // 리비전 토글
  const toggleRev = (docNo: string, revNo: string) => {
    const key = `${docNo}_${revNo}`;
    setExpandedRevs((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(key)) {
        newSet.delete(key);
      } else {
        newSet.add(key);
      }
      return newSet;
    });
  };

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogTrigger asChild>
        <Button variant="outline" size="sm" disabled={!projNo || !vndrCd}>
          <FileText className="h-4 w-4 mr-2" />
          업로드 파일 관리
        </Button>
      </DialogTrigger>
      <DialogContent className="max-w-4xl max-h-[80vh]">
        <DialogHeader>
          <DialogTitle>업로드한 파일 목록</DialogTitle>
          <DialogDescription>
            프로젝트: {projNo} | 업체: {vndrCd}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* 액션 바 */}
          <div className="flex items-center justify-between">
            <div className="text-sm text-muted-foreground">
              총 {files.length}개 파일
            </div>
            <Button
              variant="outline"
              size="sm"
              onClick={loadFiles}
              disabled={isLoading}
            >
              {isLoading ? (
                <>
                  <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                  조회 중...
                </>
              ) : (
                <>
                  <RefreshCw className="h-4 w-4 mr-2" />
                  새로고침
                </>
              )}
            </Button>
          </div>

          {/* 파일 트리 */}
          <ScrollArea className="h-[500px] rounded-md border p-4">
            {isLoading && files.length === 0 ? (
              <div className="flex items-center justify-center h-full text-muted-foreground">
                <Loader2 className="h-6 w-6 animate-spin mr-2" />
                파일 목록을 조회하는 중...
              </div>
            ) : files.length === 0 ? (
              <div className="flex items-center justify-center h-full text-muted-foreground">
                업로드한 파일이 없습니다.
              </div>
            ) : (
              <div className="space-y-2">
                {Array.from(fileTree.entries()).map(([docNo, docNode]) => (
                  <div key={docNo} className="space-y-1">
                    {/* 문서번호 */}
                    <div
                      className="flex items-center gap-2 p-2 rounded-md hover:bg-muted cursor-pointer"
                      onClick={() => toggleDoc(docNo)}
                    >
                      {expandedDocs.has(docNo) ? (
                        <ChevronDown className="h-4 w-4 text-muted-foreground shrink-0" />
                      ) : (
                        <ChevronRight className="h-4 w-4 text-muted-foreground shrink-0" />
                      )}
                      <FileText className="h-4 w-4 text-blue-600 shrink-0" />
                      <span className="font-semibold">{docNo}</span>
                      <Badge variant="outline" className="text-xs">
                        {docNode.revisions.size}개 리비전
                      </Badge>
                    </div>

                    {/* 리비전 목록 */}
                    {expandedDocs.has(docNo) && (
                      <div className="ml-6 space-y-1">
                        {Array.from(docNode.revisions.entries()).map(([revNo, revNode]) => {
                          const revKey = `${docNo}_${revNo}`;
                          return (
                            <div key={revKey} className="space-y-1">
                              {/* 리비전 번호 */}
                              <div
                                className="flex items-center gap-2 p-2 rounded-md hover:bg-muted cursor-pointer"
                                onClick={() => toggleRev(docNo, revNo)}
                              >
                                {expandedRevs.has(revKey) ? (
                                  <ChevronDown className="h-4 w-4 text-muted-foreground shrink-0" />
                                ) : (
                                  <ChevronRight className="h-4 w-4 text-muted-foreground shrink-0" />
                                )}
                                <span className="font-medium text-sm">Rev: {revNo}</span>
                                <Badge variant="secondary" className="text-xs">
                                  {revNode.files.files.length}개 파일
                                </Badge>
                              </div>

                              {/* 파일 목록 */}
                              {expandedRevs.has(revKey) && (
                                <div className="ml-6 space-y-1">
                                  {revNode.files.files.map((file, idx) => {
                                    const fileKey = `${file.BOX_SEQ}_${file.ACTV_SEQ}`;
                                    const isCancellable = file.STAT === "SCW01";
                                    const isCancelling = cancellingFiles.has(fileKey);

                                    return (
                                      <div
                                        key={`${fileKey}_${idx}`}
                                        className="flex items-center gap-2 p-2 rounded-md border bg-card"
                                      >
                                        <FileText className="h-4 w-4 text-muted-foreground shrink-0" />
                                        <div className="flex-1 min-w-0">
                                          <div className="text-sm truncate">{file.FILE_NM}</div>
                                          <div className="flex items-center gap-2 text-xs text-muted-foreground">
                                            <span>Stage: {file.STAGE}</span>
                                            <span>•</span>
                                            <span>상태: {file.STAT_NM || file.STAT || "알 수 없음"}</span>
                                          </div>
                                        </div>
                                        <Button
                                          variant="destructive"
                                          size="sm"
                                          onClick={() => handleCancelFile(file)}
                                          disabled={!isCancellable || isCancelling}
                                          title={
                                            isCancellable
                                              ? "파일 업로드 취소"
                                              : `취소 불가 (상태: ${file.STAT_NM || file.STAT})`
                                          }
                                        >
                                          {isCancelling ? (
                                            <>
                                              <Loader2 className="h-3 w-3 mr-1 animate-spin" />
                                              취소 중...
                                            </>
                                          ) : (
                                            <>
                                              <X className="h-3 w-3 mr-1" />
                                              취소
                                            </>
                                          )}
                                        </Button>
                                      </div>
                                    );
                                  })}
                                </div>
                              )}
                            </div>
                          );
                        })}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}
          </ScrollArea>

          {/* 안내 메시지 */}
          <div className="rounded-lg bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3">
            <div className="text-xs text-blue-600 dark:text-blue-400 space-y-1">
              <p>ℹ️ 접수 전(SCW01) 상태의 파일만 취소할 수 있습니다.</p>
              <p>ℹ️ 취소된 파일은 목록에서 제거됩니다.</p>
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
