// lib/vendor-rfq-response/vendor-tbe-table/vendor-documents-sheet.tsx
"use client"

import * as React from "react"
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
    SheetDescription,
} from "@/components/ui/sheet"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from "@/components/ui/table"
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select"
import { ScrollArea } from "@/components/ui/scroll-area"
import { formatDate } from "@/lib/utils"
import { downloadFile } from "@/lib/file-download"
import {
    FileText,
    Eye,
    Download,
    Filter,
    MessageSquare,
    CheckCircle,
    XCircle,
    Clock,
    AlertCircle,
    Upload,
    CheckCircle2,
    Loader2,
    AlertTriangle,
    Trash2,
} from "lucide-react"
import { toast } from "sonner"
import {
    Dropzone,
    DropzoneZone,
    DropzoneTitle,
    DropzoneDescription,
    DropzoneInput,
    DropzoneUploadIcon,
} from "@/components/ui/dropzone"
import {
    FileList,
    FileListHeader,
    FileListItem,
    FileListIcon,
    FileListInfo,
    FileListName,
    FileListSize,
    FileListDescription,
    FileListAction,
} from "@/components/ui/file-list"
import { useRouter } from "next/navigation"

interface VendorDocumentsSheetProps {
    open: boolean
    onOpenChange: (open: boolean) => void
    sessionDetail: any
    isLoading: boolean
    onUploadSuccess?: () => void
}

// 업로드 큐
type QueueItem = {
    id: string
    file: File
    status: "queued" | "uploading" | "done" | "error"
    progress: number
    error?: string
}

function makeId() {
    // Safari/구형 브라우저 대비 폴백
    return (typeof crypto !== "undefined" && "randomUUID" in crypto)
        ? crypto.randomUUID()
        : Math.random().toString(36).slice(2) + Date.now().toString(36)
}

type CommentCount = { totalCount: number; openCount: number }
type CountMap = Record<number, CommentCount>

export function VendorDocumentsSheet({
    open,
    onOpenChange,
    sessionDetail,
    isLoading,
    onUploadSuccess,
}: VendorDocumentsSheetProps) {
    const [sourceFilter, setSourceFilter] = React.useState<"all" | "buyer" | "vendor">("all")
    const [searchTerm, setSearchTerm] = React.useState("")
    const [queue, setQueue] = React.useState<QueueItem[]>([])
    const router = useRouter()
    const [commentCounts, setCommentCounts] = React.useState<CountMap>({}) // <-- 추가
    const [countLoading, setCountLoading] = React.useState(false)


    console.log(sessionDetail, "sessionDetail")

    const allReviewIds = React.useMemo(() => {
        const docs = sessionDetail?.documents ?? []
        const ids = new Set<number>()
        for (const d of docs) {
            const id = Number(d?.documentReviewId)
            if (Number.isFinite(id)) ids.add(id)
        }
        return Array.from(ids)
    }, [sessionDetail?.documents])

    // 배치로 카운트 로드
    React.useEffect(() => {
        let aborted = false
            ; (async () => {
                if (allReviewIds.length === 0) {
                    setCommentCounts({})
                    return
                }
                setCountLoading(true)
                try {
                    // 너무 길어질 수 있으니 적당히 나눠서 호출(옵션)
                    const chunkSize = 100
                    const chunks: number[][] = []
                    for (let i = 0; i < allReviewIds.length; i += chunkSize) {
                        chunks.push(allReviewIds.slice(i, i + chunkSize))
                    }

                    const merged: CountMap = {}
                    for (const c of chunks) {
                        const qs = encodeURIComponent(c.join(","))
                        const res = await fetch(`/api/pdftron-comments/xfdf/count?ids=${qs}`, {
                            credentials: "include",
                            cache: "no-store",
                        })
                        if (!res.ok) throw new Error(`count api ${res.status}`)
                        const json = await res.json()
                        if (aborted) return
                        const data = (json?.data ?? {}) as Record<string, { totalCount: number; openCount: number }>
                        for (const [k, v] of Object.entries(data)) {
                            const idNum = Number(k)
                            if (Number.isFinite(idNum)) {
                                merged[idNum] = { totalCount: v.totalCount ?? 0, openCount: v.openCount ?? 0 }
                            }
                        }
                    }
                    if (!aborted) setCommentCounts(merged)
                } catch (e) {
                    console.error("Failed to load comment counts", e)
                } finally {
                    if (!aborted) setCountLoading(false)
                }
            })()
        return () => {
            aborted = true
        }
    }, [allReviewIds.join(",")]) // 의존성: id 목록이 바뀔 때만


    // PDFTron 열기
    const handleOpenPDFTron = (doc: any) => {
        if (!doc.filePath) {
            toast.error("파일 경로를 찾을 수 없습니다")
            return
        }
        const params = new URLSearchParams({
            filePath: doc.filePath,
            documentId: String(doc.documentId ?? ""),
            documentReviewId: String(doc.documentReviewId ?? ""),
            sessionId: String(sessionDetail?.session?.tbeSessionId ?? ""),
            documentName: doc.documentName || "",
            mode: doc.documentSource === "vendor" ? "edit" : "comment",
        })
        window.open(`/pdftron-viewer?${params.toString()}`, "_blank")
    }

    const canOpenInPDFTron = (filePath: string) => {
        console.log(filePath, "filePath")
        if (!filePath) return false
        const ext = filePath.split(".").pop()?.toLowerCase()
        const supported = ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "jpg", "jpeg", "png", "tiff", "bmp"]
        return !!ext && supported.includes(ext)
    }

    const handleDownload = async (doc: any) => {
        if (!doc.filePath) {
            toast.error("파일 경로를 찾을 수 없습니다")
            return
        }
        await downloadFile(doc.filePath, doc.originalFileName || doc.documentName, {
            action: "download",
            showToast: true,
            onError: (e) => console.error("Download error:", e),
        })
    }

    // ---- 업로드 ----
    const tbeSessionId = sessionDetail?.session?.tbeSessionId
    const endpoint = tbeSessionId ? `/api/partners/tbe/${tbeSessionId}/documents` : null

    const startUpload = React.useCallback((item: QueueItem) => {
        if (!endpoint) {
            toast.error("세션 정보가 준비되지 않았습니다. 잠시 후 다시 시도하세요.")
            setQueue((prev) =>
                prev.map((q) => (q.id === item.id ? { ...q, status: "error", error: "세션 없음" } : q))
            )
            return
        }

        setQueue((prev) =>
            prev.map((q) => (q.id === item.id ? { ...q, status: "uploading", progress: 0 } : q))
        )

        try {
            const fd = new FormData()
            fd.append("documentType", "설계")                      // 필수값 없이 기본값
            fd.append("documentName", item.file.name.replace(/\.[^.]+$/, ""))
            fd.append("description", "")
            fd.append("file", item.file)

            const xhr = new XMLHttpRequest()
            xhr.withCredentials = true // 동일 출처라면 문제 없지만 안전하게 명시
            xhr.upload.onprogress = (e) => {
                if (e.lengthComputable) {
                    const pct = Math.round((e.loaded / e.total) * 100)
                    setQueue((prev) =>
                        prev.map((q) => (q.id === item.id ? { ...q, progress: pct } : q))
                    )
                }
            }
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        setQueue((prev) =>
                            prev.map((q) => (q.id === item.id ? { ...q, status: "done", progress: 100 } : q))
                        )
                        toast.success(`업로드 완료: ${item.file.name}`)
                        onUploadSuccess?.()
                    } else {
                        const err = (() => { try { return JSON.parse(xhr.responseText)?.error } catch { return null } })()
                            || `서버 오류 (${xhr.status})`
                        setQueue((prev) =>
                            prev.map((q) => (q.id === item.id ? { ...q, status: "error", error: err } : q))
                        )
                        toast.error(err)
                    }
                }
            }

            xhr.open("POST", endpoint)
            // Content-Type 수동 지정 금지 (XHR이 multipart 경계 자동 설정)
            xhr.send(fd)

            if (xhr.status >= 200 && xhr.status < 300) {
                setQueue((prev) =>
                    prev.map((q) => (q.id === item.id ? { ...q, status: "done", progress: 100 } : q))
                )
                toast.success(`업로드 완료: ${item.file.name}`)
                onUploadSuccess?.()
                router.refresh()

                // ✅ 1.5초 뒤 자동 제거 (원하면 시간 조절)
                setTimeout(() => {
                    setQueue((prev) => prev.filter(q => q.id !== item.id))
                }, 1500)
            }

        } catch (e: any) {
            setQueue((prev) =>
                prev.map((q) => (q.id === item.id ? { ...q, status: "error", error: e?.message || "업로드 실패" } : q))
            )
            toast.error(e?.message || "업로드 실패")
        }
    }, [endpoint, onUploadSuccess])

    const lastBatchRef = React.useRef<string>("")

    function batchSig(files: File[]) {
        return files.map(f => `${f.name}:${f.size}:${f.lastModified}`).join("|")
    }

    const handleDrop = React.useCallback((filesOrEvent: any) => {
        let files: File[] = []
        if (Array.isArray(filesOrEvent)) {
            files = filesOrEvent
        } else if (filesOrEvent?.target?.files) {
            files = Array.from(filesOrEvent.target.files as FileList)
        } else if (filesOrEvent?.dataTransfer?.files) {
            files = Array.from(filesOrEvent.dataTransfer.files as FileList)
        }
        if (!files.length) return

        // 🔒 중복 배치 방지
        const sig = batchSig(files)
        if (sig === lastBatchRef.current) return
        lastBatchRef.current = sig
        // 너무 오래 잠기지 않도록 약간 뒤에 초기화
        setTimeout(() => { if (lastBatchRef.current === sig) lastBatchRef.current = "" }, 500)

        const items: QueueItem[] = files.map((f) => ({
            id: makeId(),
            file: f,
            status: "queued",
            progress: 0,
        }))
        setQueue((prev) => [...items, ...prev])
        items.forEach((it) => startUpload(it))
    }, [startUpload])

    const removeFromQueue = (id: string) => {
        setQueue((prev) => prev.filter((q) => q.id !== id))
    }

    React.useEffect(() => {
        if (!open) {
            setQueue([])
            lastBatchRef.current = ""
        }
    }, [open])


    // ---- 목록 필터 ----
    const filteredDocuments = React.useMemo(() => {
        const docs = sessionDetail?.documents ?? []
        return docs.filter((doc: any) => {
            if (sourceFilter !== "all" && doc.documentSource !== sourceFilter) return false
            if (searchTerm) {
                const s = searchTerm.toLowerCase()
                return (
                    doc.documentName?.toLowerCase().includes(s) ||
                    doc.documentType?.toLowerCase().includes(s)
                )
            }
            return true
        })
    }, [sessionDetail?.documents, sourceFilter, searchTerm])

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent className="w-[1200px] sm:w-[1200px] max-w-[90vw]" style={{ width: 1200, maxWidth: "90vw" }}>
                <SheetHeader>
                    <SheetTitle>Document Repository</SheetTitle>
                    <SheetDescription>TBE 관련 문서 조회, 다운로드 및 업로드</SheetDescription>
                </SheetHeader>

                {/* 업로드 안내 (세션 상태) */}
                {sessionDetail?.session?.sessionStatus !== "진행중" && (
                    <div className="mt-3 mb-3 rounded-md border border-dashed p-3 text-sm text-muted-foreground">
                        현재 세션 상태가 <b>{sessionDetail?.session?.sessionStatus}</b> 입니다.
                        파일을 업로드하면 서버 정책에 따라 상태가 <b>진행중</b>으로 전환될 수 있어요.
                    </div>
                )}

                {/* --- 드롭존 영역 --- */}
                <div className="mb-4 rounded-lg border border-dashed">
                    <Dropzone onDrop={handleDrop}>
                        <DropzoneZone className="py-8">
                            <DropzoneUploadIcon />
                            <DropzoneTitle>파일을 여기에 드롭하거나 클릭해서 선택하세요</DropzoneTitle>
                            <DropzoneDescription>
                                PDF, Office, 이미지 등 대용량(최대 1GB)도 지원합니다
                            </DropzoneDescription>
                            <DropzoneInput
                                accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png,.tiff,.bmp"
                                multiple
                            />
                        </DropzoneZone>
                    </Dropzone>

                    {/* 업로드 큐/진행상태 */}
                    {queue.length > 0 && (
                        <div className="p-3">
                            <FileList>
                                <FileListHeader>업로드 큐</FileListHeader>
                                {queue.map((q) => (
                                    <FileListItem key={q.id}>
                                        <FileListIcon>
                                            {q.status === "done" ? (
                                                <CheckCircle2 className="h-5 w-5" />
                                            ) : q.status === "error" ? (
                                                <AlertTriangle className="h-5 w-5" />
                                            ) : (
                                                <Loader2 className="h-5 w-5 animate-spin" />
                                            )}
                                        </FileListIcon>
                                        <FileListInfo>
                                            <FileListName>
                                                {q.file.name}
                                                {q.status === "uploading" && ` · ${q.progress}%`}
                                            </FileListName>
                                            <FileListDescription>
                                                {q.status === "queued" && "대기 중"}
                                                {q.status === "uploading" && "업로드 중"}
                                                {q.status === "done" && "완료"}
                                                {q.status === "error" && (q.error || "실패")}
                                            </FileListDescription>
                                        </FileListInfo>
                                        <FileListSize>{q.file.size}</FileListSize>
                                        <FileListAction>
                                            {(q.status === "done" || q.status === "error") && (
                                                <Button
                                                    variant="ghost"
                                                    size="icon"
                                                    onClick={() => removeFromQueue(q.id)}
                                                    title="제거"
                                                >
                                                    <Trash2 className="h-4 w-4" />
                                                </Button>
                                            )}
                                        </FileListAction>
                                    </FileListItem>
                                ))}
                            </FileList>
                        </div>
                    )}
                </div>

                {/* 필터 & 검색 */}
                <div className="flex items-center gap-4 mt-4 mb-4">
                    <div className="flex items-center gap-2">
                        <Filter className="h-4 w-4 text-muted-foreground" />
                        <Select value={sourceFilter} onValueChange={(v: any) => setSourceFilter(v)}>
                            <SelectTrigger className="w-[150px]">
                                <SelectValue placeholder="Filter by source" />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="all">All Documents</SelectItem>
                                <SelectItem value="buyer">Buyer Documents</SelectItem>
                                <SelectItem value="vendor">My Documents</SelectItem>
                            </SelectContent>
                        </Select>
                    </div>

                    <Input
                        placeholder="Search documents..."
                        value={searchTerm}
                        onChange={(e) => setSearchTerm(e.target.value)}
                        className="max-w-sm"
                    />

                    <div className="ml-auto flex items-center gap-2 text-sm text-muted-foreground">
                        <Badge variant="outline">Total: {filteredDocuments.length}</Badge>
                        {sessionDetail?.documents && (
                            <>
                                <Badge variant="secondary">
                                    Buyer: {sessionDetail.documents.filter((d: any) => d.documentSource === "buyer").length}
                                </Badge>
                                <Badge variant="secondary">
                                    My Docs: {sessionDetail.documents.filter((d: any) => d.documentSource === "vendor").length}
                                </Badge>
                            </>
                        )}
                    </div>
                </div>

                {/* 문서 테이블 */}
                {isLoading ? (
                    <div className="p-8 text-center">Loading...</div>
                ) : (
                    <ScrollArea className="h-[calc(100vh-250px)]">
                        <Table>
                            <TableHeader>
                                <TableRow>
                                    <TableHead className="w-[80px]">Source</TableHead>
                                    <TableHead>Document Name</TableHead>
                                    <TableHead className="w-[120px]">Type</TableHead>
                                    <TableHead className="w-[100px]">Review Status</TableHead>
                                    <TableHead className="w-[120px]">Comments</TableHead>
                                    <TableHead className="w-[150px]">Uploaded</TableHead>
                                    <TableHead className="w-[100px] text-right">Actions</TableHead>
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {filteredDocuments.length === 0 ? (
                                    <TableRow>
                                        <TableCell colSpan={7} className="text-center text-muted-foreground">
                                            No documents found
                                        </TableCell>
                                    </TableRow>
                                ) : (
                                    filteredDocuments.map((doc: any) => (
                                        <TableRow key={doc.documentReviewId || doc.documentId}>
                                            <TableCell>
                                                <Badge variant={doc.documentSource === "buyer" ? "default" : "secondary"}>
                                                    {doc.documentSource === "buyer" ? "Buyer" : "Vendor"}
                                                </Badge>
                                            </TableCell>

                                            <TableCell>
                                                <div className="flex items-center gap-2">
                                                    <FileText className="h-4 w-4 text-muted-foreground" />
                                                    <span className="font-medium">{doc.documentName}</span>
                                                </div>
                                            </TableCell>

                                            <TableCell>
                                                <span className="text-sm">{doc.documentType}</span>
                                            </TableCell>

                                            <TableCell>
                                                {doc.documentSource === "vendor" && doc.reviewStatus ? (
                                                    <div className="flex items-center gap-1">
                                                        {(() => {
                                                            switch (doc.reviewStatus) {
                                                                case "승인": return <CheckCircle className="h-4 w-4 text-green-600" />
                                                                case "반려": return <XCircle className="h-4 w-4 text-red-600" />
                                                                case "보류": return <AlertCircle className="h-4 w-4 text-yellow-600" />
                                                                default: return <Clock className="h-4 w-4 text-gray-400" />
                                                            }
                                                        })()}
                                                        <span className="text-sm">{doc.reviewStatus}</span>
                                                    </div>
                                                ) : (
                                                    <span className="text-sm text-muted-foreground">-</span>
                                                )}
                                            </TableCell>

                                            <TableCell>
                                                {(() => {
                                                    const id = Number(doc.documentReviewId)
                                                    const counts = Number.isFinite(id) ? commentCounts[id] : undefined
                                                    if (countLoading && !counts) {
                                                        return <span className="text-xs text-muted-foreground">Loading…</span>
                                                    }
                                                    if (!counts || counts.totalCount === 0) {
                                                        return <span className="text-muted-foreground text-xs">-</span>
                                                    }
                                                    return (
                                                        <div className="flex items-center gap-1">
                                                            <MessageSquare className="h-3 w-3" />
                                                            <span className="text-xs">
                                                                {counts.totalCount}
                                                                {counts.openCount > 0 && (
                                                                    <span className="text-orange-600 ml-1">
                                                                        ({counts.openCount} open)
                                                                    </span>
                                                                )}
                                                            </span>
                                                        </div>
                                                    )
                                                })()}
                                            </TableCell>

                                            <TableCell>
                                                <span className="text-xs text-muted-foreground">
                                                    {doc.uploadedAt
                                                        ? formatDate(doc.uploadedAt, "KR")
                                                        : doc.submittedAt
                                                            ? formatDate(doc.submittedAt, "KR")
                                                            : "-"}
                                                </span>
                                            </TableCell>

                                            <TableCell className="text-right">
                                                <div className="flex items-center justify-end gap-1">
                                                    {canOpenInPDFTron(doc.filePath) && (
                                                        <Button
                                                            size="sm"
                                                            variant="ghost"
                                                            onClick={() => handleOpenPDFTron(doc)}
                                                            className="h-8 px-2"
                                                            title={"View & Comment"}
                                                        >
                                                            <Eye className="h-4 w-4" />
                                                        </Button>
                                                    )}

                                                    <Button
                                                        size="sm"
                                                        variant="ghost"
                                                        onClick={() => handleDownload(doc)}
                                                        className="h-8 px-2"
                                                        title="Download document"
                                                    >
                                                        <Download className="h-4 w-4" />
                                                    </Button>
                                                </div>
                                            </TableCell>
                                        </TableRow>
                                    ))
                                )}
                            </TableBody>
                        </Table>
                    </ScrollArea>
                )}
            </SheetContent>
        </Sheet>
    )
}
