"use client";

import React, { useMemo, useState } from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Download, XCircle } from "lucide-react";
import { cancelVendorUploadedFile } from "@/lib/swp/vendor-actions";
import type { SwpFileApiResponse } from "@/lib/swp/api-client";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { formatSwpDate } from "@/lib/swp/utils";
import { SwpInboxHistoryDialog } from "./swp-inbox-history-dialog";

// 업로드 필요 문서 타입 (DB stageDocuments에서 조회)
interface RequiredDocument {
  vendorDocNumber: string;
  title: string;
  buyerSystemComment: string | null;
}

interface SwpInboxTableProps {
  files: SwpFileApiResponse[];
  requiredDocs: RequiredDocument[];
  projNo: string;
  vendorCode: string;
  userId: string;
}

// 테이블 행 데이터 (플랫하게 펼침)
interface TableRowData {
  uploadId: string | null; // 업로드 필요 문서는 null
  docNo: string;
  revNo: string | null;
  stage: string | null;
  status: string | null;
  statusNm: string | null;
  actvNo: string | null;
  crter: string | null; // CRTER (그대로 표시)
  note: string | null; // Activity의 note 또는 buyerSystemComment
  file: SwpFileApiResponse | null; // 업로드 필요 문서는 null
  uploadDate: string | null;
  // 각 행이 속한 그룹의 정보 (계층적 rowSpan 처리)
  isFirstInUpload: boolean;
  fileCountInUpload: number;
  isFirstInDoc: boolean;
  fileCountInDoc: number;
  isFirstInRev: boolean;
  fileCountInRev: number;
  isFirstInActivity: boolean;
  fileCountInActivity: number;
  // 업로드 필요 문서 여부
  isRequiredDoc: boolean;
}

// Status 집계 타입
interface StatusCount {
  status: string;
  statusNm: string;
  count: number;
  color: string;
}

export function SwpInboxTable({
  files,
  requiredDocs,
  projNo,
  userId,
}: SwpInboxTableProps) {
  const [selectedStatus, setSelectedStatus] = useState<string | null>(null);
  const [selectedFiles, setSelectedFiles] = useState<Set<string>>(new Set()); // 선택된 파일 (fileKey)
  const [historyDialogOpen, setHistoryDialogOpen] = useState(false);
  const [selectedDocNo, setSelectedDocNo] = useState<string | null>(null);

  // Status 집계 (API 응답 + 업로드 필요 문서)
  const statusCounts = useMemo(() => {
    const statusMap = new Map<string, { statusNm: string; count: number }>();
    
    // API 응답 파일 집계
    files.forEach((file) => {
      const status = file.STAT || "UNKNOWN";
      const statusNm = file.STAT_NM || status;
      
      if (statusMap.has(status)) {
        statusMap.get(status)!.count++;
      } else {
        statusMap.set(status, { statusNm, count: 1 });
      }
    });

    // 업로드 필요 문서 집계
    if (requiredDocs.length > 0) {
      const status = "UPLOAD_REQUIRED";
      const statusNm = "Upload Required";
      statusMap.set(status, { statusNm, count: requiredDocs.length });
    }

    const counts: StatusCount[] = [];
    statusMap.forEach((value, status) => {
      const color =
        status === "SCW03" || status === "SCW08" ? "bg-green-100 text-green-800 hover:bg-green-200" :
        status === "SCW02" ? "bg-blue-100 text-blue-800 hover:bg-blue-200" :
        status === "SCW01" ? "bg-yellow-100 text-yellow-800 hover:bg-yellow-200" :
        status === "SCW04" || status === "SCW05" || status === "SCW06" ? "bg-red-100 text-red-800 hover:bg-red-200" :
        status === "SCW07" ? "bg-purple-100 text-purple-800 hover:bg-purple-200" :
        status === "SCW09" ? "bg-gray-100 text-gray-800 hover:bg-gray-200" :
        status === "SCW00" ? "bg-orange-100 text-orange-800 hover:bg-orange-200" :
        status === "UPLOAD_REQUIRED" ? "bg-amber-100 text-amber-800 hover:bg-amber-200" :
        "bg-gray-100 text-gray-800 hover:bg-gray-200";

      counts.push({
        status,
        statusNm: value.statusNm,
        count: value.count,
        color,
      });
    });

    // 개수 순으로 정렬 (Upload Required를 맨 앞으로)
    return counts.sort((a, b) => {
      if (a.status === "UPLOAD_REQUIRED") return -1;
      if (b.status === "UPLOAD_REQUIRED") return 1;
      return b.count - a.count;
    });
  }, [files, requiredDocs]);

  // 데이터 그룹화 및 플랫 변환 (API 응답 + 업로드 필요 문서)
  const tableRows = useMemo(() => {
    const rows: TableRowData[] = [];

    // 1. API 응답 파일 처리
    // Status 필터링
    let filteredFiles = files;
    if (selectedStatus && selectedStatus !== "UPLOAD_REQUIRED") {
      filteredFiles = files.filter((file) => file.STAT === selectedStatus);
    }

    // 1단계: BOX_SEQ (Upload ID) 기준으로 그룹화
    const uploadGroups = new Map<string, SwpFileApiResponse[]>();
    
    if (!selectedStatus || selectedStatus !== "UPLOAD_REQUIRED") {
      filteredFiles.forEach((file) => {
        const uploadId = file.BOX_SEQ || "NO_UPLOAD_ID";
        if (!uploadGroups.has(uploadId)) {
          uploadGroups.set(uploadId, []);
        }
        uploadGroups.get(uploadId)!.push(file);
      });
    }

    // Upload ID별로 처리
    uploadGroups.forEach((uploadFiles, uploadId) => {
      // 2단계: Document No 기준으로 그룹화
      const docGroups = new Map<string, SwpFileApiResponse[]>();
      
      uploadFiles.forEach((file) => {
        const docNo = file.OWN_DOC_NO;
        if (!docGroups.has(docNo)) {
          docGroups.set(docNo, []);
        }
        docGroups.get(docNo)!.push(file);
      });

      // 전체 Upload ID의 파일 수 계산
      const totalUploadFileCount = uploadFiles.length;
      let isFirstInUpload = true;

      // Document No별로 처리
      docGroups.forEach((docFiles, docNo) => {
        // 3단계: 최신 RevNo 찾기 (CRTE_DTM 기준)
        const sortedByDate = [...docFiles].sort((a, b) =>
          (b.CRTE_DTM || "").localeCompare(a.CRTE_DTM || "")
        );
        const latestRevNo = sortedByDate[0]?.REV_NO || "";
        const latestStage = sortedByDate[0]?.STAGE || null;
        const latestStatus = sortedByDate[0]?.STAT || null;
        const latestStatusNm = sortedByDate[0]?.STAT_NM || null;

        // 4단계: 최신 Rev의 파일들만 필터링
        const latestRevFiles = docFiles.filter(
          (file) => file.REV_NO === latestRevNo
        );

        const totalDocFileCount = latestRevFiles.length;
        let isFirstInDoc = true;

        // 5단계: Activity 기준으로 그룹화
        const activityGroups = new Map<string, SwpFileApiResponse[]>();
        
        latestRevFiles.forEach((file) => {
          const actvNo = file.ACTV_NO || "NO_ACTIVITY";
          if (!activityGroups.has(actvNo)) {
            activityGroups.set(actvNo, []);
          }
          activityGroups.get(actvNo)!.push(file);
        });

        let isFirstInRev = true;

        // Activity별로 처리
        activityGroups.forEach((activityFiles, actvNo) => {
          // 6단계: Upload Date 기준 DESC 정렬
          const sortedFiles = activityFiles.sort((a, b) =>
            (b.CRTE_DTM || "").localeCompare(a.CRTE_DTM || "")
          );

          const totalActivityFileCount = sortedFiles.length;
          
          // Activity의 첫 번째 파일에서 메타데이터 가져오기
          const firstActivityFile = sortedFiles[0];
          if (!firstActivityFile) return;

          // 7단계: 각 파일을 테이블 행으로 변환
          sortedFiles.forEach((file, idx) => {
            rows.push({
              uploadId,
              docNo,
              revNo: latestRevNo,
              stage: latestStage,
              status: latestStatus,
              statusNm: latestStatusNm,
              actvNo: actvNo === "NO_ACTIVITY" ? null : actvNo,
              crter: firstActivityFile.CRTER, // Activity 첫 파일의 CRTER
              note: firstActivityFile.NOTE || null, // Activity 첫 파일의 note
              file,
              uploadDate: file.CRTE_DTM,
              isFirstInUpload,
              fileCountInUpload: totalUploadFileCount,
              isFirstInDoc,
              fileCountInDoc: totalDocFileCount,
              isFirstInRev,
              fileCountInRev: totalDocFileCount, // Rev = Doc의 최신 Rev이므로 파일 수 동일
              isFirstInActivity: idx === 0,
              fileCountInActivity: totalActivityFileCount,
              isRequiredDoc: false,
            });

            // 첫 번째 플래그들 업데이트
            if (idx === 0) {
              isFirstInUpload = false;
              isFirstInDoc = false;
              isFirstInRev = false;
            }
          });
        });
      });
    });

    // 2. 업로드 필요 문서 추가 (Upload Required 필터일 때만 또는 필터 없을 때)
    if (!selectedStatus || selectedStatus === "UPLOAD_REQUIRED") {
      requiredDocs.forEach((doc) => {
        rows.push({
          uploadId: null,
          docNo: doc.vendorDocNumber,
          revNo: null,
          stage: null,
          status: "UPLOAD_REQUIRED",
          statusNm: "Upload Required",
          actvNo: null,
          crter: null,
          note: doc.buyerSystemComment,
          file: null,
          uploadDate: null,
          isFirstInUpload: true,
          fileCountInUpload: 1,
          isFirstInDoc: true,
          fileCountInDoc: 1,
          isFirstInRev: true,
          fileCountInRev: 1,
          isFirstInActivity: true,
          fileCountInActivity: 1,
          isRequiredDoc: true,
        });
      });
    }

    // Upload Date 기준 전체 정렬 (null은 맨 뒤로)
    return rows.sort((a, b) => {
      if (!a.uploadDate) return 1;
      if (!b.uploadDate) return -1;
      return b.uploadDate.localeCompare(a.uploadDate);
    });
  }, [files, requiredDocs, selectedStatus]);

  // 선택 가능한 파일들 (Standby 상태만)
  const selectableFiles = useMemo(() => {
    return tableRows
      .filter((row) => row.file && row.status === "SCW01")
      .map((row) => `${row.file!.BOX_SEQ}_${row.file!.FILE_SEQ}`);
  }, [tableRows]);

  // 전체 선택/해제
  const handleSelectAll = (checked: boolean) => {
    if (checked) {
      setSelectedFiles(new Set(selectableFiles));
    } else {
      setSelectedFiles(new Set());
    }
  };

  // 개별 선택/해제
  const handleSelectFile = (fileKey: string, checked: boolean | "indeterminate") => {
    const isChecked = checked === true;
    setSelectedFiles((prev) => {
      const newSet = new Set(prev);
      if (isChecked) {
        newSet.add(fileKey);
      } else {
        newSet.delete(fileKey);
      }
      return newSet;
    });
  };

  // 선택된 파일 일괄 취소
  const handleBulkCancel = async () => {
    if (selectedFiles.size === 0) {
      toast.error("취소할 파일을 선택해주세요");
      return;
    }

    const filesToCancel = tableRows.filter((row) => 
      row.file && selectedFiles.has(`${row.file.BOX_SEQ}_${row.file.FILE_SEQ}`)
    );

    if (filesToCancel.length === 0) {
      toast.error("취소할 파일이 없습니다");
      return;
    }

    try {
      toast.info(`${filesToCancel.length}개 파일 취소 중...`);

      // 병렬 취소
      const cancelPromises = filesToCancel.map((row) =>
        cancelVendorUploadedFile({
          boxSeq: row.file!.BOX_SEQ!,
          actvSeq: row.file!.ACTV_SEQ!,
          userId,
        })
      );

      await Promise.all(cancelPromises);

      toast.success(`${filesToCancel.length}개 파일 취소 완료`);
      setSelectedFiles(new Set()); // 선택 초기화
      
      // 페이지 리프레시
      window.location.reload();
    } catch (error) {
      console.error("일괄 취소 실패:", error);
      toast.error("일부 파일 취소에 실패했습니다");
    }
  };


  const handleDownloadFile = async (file: SwpFileApiResponse) => {
    try {
      toast.info("파일 다운로드 준비 중...");
      
      // API route를 통해 다운로드
      const downloadUrl = `/api/swp/download/${encodeURIComponent(file.OWN_DOC_NO)}?projNo=${encodeURIComponent(projNo)}&fileName=${encodeURIComponent(file.FILE_NM)}`;
      
      // 새 탭에서 다운로드
      window.open(downloadUrl, "_blank");
      
      toast.success(`파일 다운로드 시작: ${file.FILE_NM}`);
    } catch (error) {
      console.error("파일 다운로드 실패:", error);
      toast.error("파일 다운로드에 실패했습니다");
    }
  };


  // 행 클릭 핸들러 (Document No 기준 전체 이력 보기)
  const handleRowClick = (docNo: string) => {
    setSelectedDocNo(docNo);
    setHistoryDialogOpen(true);
  };

  const getStatusBadge = (status: string | null, statusNm: string | null) => {
    const displayStatus = statusNm || status || "-";
    
    if (!status) return <span className="text-muted-foreground">{displayStatus}</span>;

    const color =
      status === "SCW03" || status === "SCW08" ? "bg-green-100 text-green-800" :
      status === "SCW02" ? "bg-blue-100 text-blue-800" :
      status === "SCW01" ? "bg-yellow-100 text-yellow-800" :
      status === "SCW04" || status === "SCW05" || status === "SCW06" ? "bg-red-100 text-red-800" :
      status === "SCW07" ? "bg-purple-100 text-purple-800" :
      status === "SCW09" ? "bg-gray-100 text-gray-800" :
      status === "SCW00" ? "bg-orange-100 text-orange-800" :
      "bg-gray-100 text-gray-800";

    return (
      <Badge variant="outline" className={color}>
        {displayStatus}
      </Badge>
    );
  };

  if (files.length === 0 && requiredDocs.length === 0) {
    return (
      <div className="border rounded-lg p-8 text-center text-muted-foreground">
        업로드한 파일이 없습니다.
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Status 필터 UI */}
      <div className="flex items-center justify-between gap-4">
        <div className="flex flex-wrap gap-2 p-4 bg-muted/30 rounded-lg flex-1">
          <Button
            variant={selectedStatus === null ? "default" : "outline"}
            size="sm"
            onClick={() => setSelectedStatus(null)}
            className="h-9"
          >
            전체 ({files.length + requiredDocs.length})
          </Button>
          {statusCounts.map((statusCount) => (
            <Button
              key={statusCount.status}
              variant="outline"
              size="sm"
              onClick={() => setSelectedStatus(statusCount.status)}
              className={cn(
                "h-9",
                selectedStatus === statusCount.status ? statusCount.color : "",
                selectedStatus !== statusCount.status && "hover:opacity-80"
              )}
            >
              {statusCount.statusNm} ({statusCount.count})
            </Button>
          ))}
        </div>

        {/* 선택된 파일 정보 및 일괄 취소 버튼 */}
        {selectedFiles.size > 0 && (
          <div className="flex items-center gap-2">
            <span className="text-sm text-muted-foreground">
              {selectedFiles.size}개 선택됨
            </span>
            <Button
              variant="destructive"
              size="sm"
              onClick={handleBulkCancel}
            >
              <XCircle className="h-4 w-4 mr-1" />
              Cancel
            </Button>
          </div>
        )}
      </div>

      {/* 테이블 */}
      {tableRows.length === 0 ? (
        <div className="border rounded-lg p-8 text-center text-muted-foreground">
          해당 상태의 파일이 없습니다.
        </div>
      ) : (
        <div className="rounded-md border overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-[50px]">
                  <Checkbox
                    checked={selectableFiles.length > 0 && selectedFiles.size === selectableFiles.length}
                    onCheckedChange={handleSelectAll}
                    disabled={selectableFiles.length === 0}
                  />
                </TableHead>
                <TableHead className="w-[100px]">Upload ID</TableHead>
                <TableHead className="w-[200px]">Document No</TableHead>
                <TableHead className="w-[80px]">Rev No</TableHead>
                <TableHead className="w-[80px]">Stage</TableHead>
                <TableHead className="w-[120px]">Status</TableHead>
                <TableHead className="w-[100px]">Activity</TableHead>
                <TableHead className="w-[120px]">Upload ID (User)</TableHead>
                <TableHead className="w-[150px]">Note</TableHead>
                <TableHead className="w-[400px]">Attachment File</TableHead>
                <TableHead className="w-[180px]">Upload Date</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {tableRows.map((row, idx) => {
                const fileKey = row.file ? `${row.file.BOX_SEQ}_${row.file.FILE_SEQ}` : `required_${idx}`;
                const canSelect = row.status === "SCW01" && row.file; // Standby이고 file이 있는 경우만 선택 가능
                const isSelected = canSelect && selectedFiles.has(fileKey);

                return (
                  <TableRow 
                    key={`${row.uploadId}_${row.docNo}_${row.revNo}_${row.actvNo}_${idx}`}
                    className="cursor-pointer hover:bg-muted/50"
                    onClick={() => handleRowClick(row.docNo)}
                  >
                    {/* Select Checkbox */}
                    <TableCell onClick={(e) => e.stopPropagation()}>
                      {canSelect ? (
                        <Checkbox
                          checked={!!isSelected}
                          onCheckedChange={(checked) => handleSelectFile(fileKey, checked)}
                        />
                      ) : null}
                    </TableCell>

                    {/* Upload ID - Upload의 첫 파일에만 표시 */}
                    {row.isFirstInUpload ? (
                      <TableCell rowSpan={row.fileCountInUpload} className="font-mono text-sm align-top" style={{ verticalAlign: "top" }}>
                        {row.uploadId || <span className="text-muted-foreground">-</span>}
                      </TableCell>
                    ) : null}

                    {/* Document No - Document의 첫 파일에만 표시 */}
                    {row.isFirstInDoc ? (
                      <TableCell rowSpan={row.fileCountInDoc} className="font-mono text-xs align-top" style={{ verticalAlign: "top" }}>
                        {row.docNo}
                      </TableCell>
                    ) : null}

                    {/* Rev No - Rev의 첫 파일에만 표시 */}
                    {row.isFirstInRev ? (
                      <TableCell rowSpan={row.fileCountInRev} className="align-top" style={{ verticalAlign: "top" }}>
                        {row.revNo || <span className="text-muted-foreground">-</span>}
                      </TableCell>
                    ) : null}

                    {/* Stage - Rev의 첫 파일에만 표시 */}
                    {row.isFirstInRev ? (
                      <TableCell rowSpan={row.fileCountInRev} className="align-top text-sm" style={{ verticalAlign: "top" }}>
                        {row.stage || <span className="text-muted-foreground">-</span>}
                      </TableCell>
                    ) : null}

                    {/* Status - Rev의 첫 파일에만 표시 */}
                    {row.isFirstInRev ? (
                      <TableCell rowSpan={row.fileCountInRev} className="align-top" style={{ verticalAlign: "top" }}>
                        {getStatusBadge(row.status, row.statusNm)}
                      </TableCell>
                    ) : null}

                    {/* Activity - Activity의 첫 파일에만 표시 */}
                    {row.isFirstInActivity ? (
                      <TableCell rowSpan={row.fileCountInActivity} className="font-mono text-xs align-top" style={{ verticalAlign: "top" }}>
                        {row.actvNo || <span className="text-muted-foreground">-</span>}
                      </TableCell>
                    ) : null}

                    {/* CRTER (Upload ID User) - Activity의 첫 파일에만 표시 */}
                    {row.isFirstInActivity ? (
                      <TableCell rowSpan={row.fileCountInActivity} className="text-sm font-mono align-top" style={{ verticalAlign: "top" }}>
                        {row.crter || <span className="text-muted-foreground">-</span>}
                      </TableCell>
                    ) : null}

                    {/* Note - Activity의 첫 파일에만 표시 (개행문자 처리) */}
                    {row.isFirstInActivity ? (
                      <TableCell 
                        rowSpan={row.fileCountInActivity} 
                        className="text-xs max-w-[150px] align-top whitespace-pre-wrap"
                        style={{ verticalAlign: "top" }}
                      >
                        {row.note || <span className="text-muted-foreground">-</span>}
                      </TableCell>
                    ) : null}

                    {/* Attachment File - 각 파일마다 표시 (줄바꿈 허용) */}
                    <TableCell className="max-w-[400px]">
                      {row.file ? (
                        <div className="flex items-center justify-between gap-2">
                          <span className="text-sm font-mono break-words" style={{ wordBreak: "break-all" }}>
                            {row.file.FILE_NM}
                          </span>
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={(e) => {
                              e.stopPropagation();
                              handleDownloadFile(row.file!);
                            }}
                            className="h-7 w-7 p-0 flex-shrink-0"
                          >
                            <Download className="h-4 w-4" />
                          </Button>
                        </div>
                      ) : (
                        <span className="text-muted-foreground">-</span>
                      )}
                    </TableCell>

                    {/* Upload Date - 각 파일마다 표시 */}
                    <TableCell className="text-xs">
                      {row.uploadDate ? formatSwpDate(row.uploadDate) : <span className="text-muted-foreground">-</span>}
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </div>
      )}

      {/* Document 전체 이력 Dialog */}
      <SwpInboxHistoryDialog
        open={historyDialogOpen}
        onOpenChange={setHistoryDialogOpen}
        docNo={selectedDocNo}
        files={files}
        projNo={projNo}
        userId={userId}
      />
    </div>
  );
}
