"use client";

/**
 * DrillDownModal 컴포넌트
 * 피벗 셀 클릭 시 해당 셀의 상세 원본 데이터를 표시하는 모달
 */

import React, { useState, useMemo } from "react";
import { cn } from "@/lib/utils";
import { PivotCellData, PivotFieldConfig } from "../types";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Search,
  Download,
  ChevronLeft,
  ChevronRight,
  ChevronsLeft,
  ChevronsRight,
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
} from "lucide-react";

// ==================== 타입 ====================

interface DrillDownModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  cellData: PivotCellData | null;
  data: any[]; // 전체 원본 데이터
  fields: PivotFieldConfig[];
  rowFields: PivotFieldConfig[];
  columnFields: PivotFieldConfig[];
}

interface SortConfig {
  field: string;
  direction: "asc" | "desc";
}

// ==================== 메인 컴포넌트 ====================

export const DrillDownModal: React.FC<DrillDownModalProps> = ({
  open,
  onOpenChange,
  cellData,
  data,
  fields,
  rowFields,
  columnFields,
}) => {
  const [searchQuery, setSearchQuery] = useState("");
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [sortConfig, setSortConfig] = useState<SortConfig | null>(null);

  // 드릴다운 데이터 필터링
  const filteredData = useMemo(() => {
    if (!cellData || !data) return [];

    // 행/열 경로에 해당하는 데이터 필터링
    let result = data.filter((row) => {
      // 행 경로 매칭
      for (let i = 0; i < cellData.rowPath.length; i++) {
        const field = rowFields[i];
        if (field && String(row[field.field]) !== cellData.rowPath[i]) {
          return false;
        }
      }

      // 열 경로 매칭
      for (let i = 0; i < cellData.columnPath.length; i++) {
        const field = columnFields[i];
        if (field && String(row[field.field]) !== cellData.columnPath[i]) {
          return false;
        }
      }

      return true;
    });

    // 검색 필터
    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      result = result.filter((row) =>
        Object.values(row).some((val) =>
          String(val).toLowerCase().includes(query)
        )
      );
    }

    // 정렬
    if (sortConfig) {
      result = [...result].sort((a, b) => {
        const aVal = a[sortConfig.field];
        const bVal = b[sortConfig.field];

        if (aVal === null || aVal === undefined) return 1;
        if (bVal === null || bVal === undefined) return -1;

        let comparison = 0;
        if (typeof aVal === "number" && typeof bVal === "number") {
          comparison = aVal - bVal;
        } else {
          comparison = String(aVal).localeCompare(String(bVal));
        }

        return sortConfig.direction === "asc" ? comparison : -comparison;
      });
    }

    return result;
  }, [cellData, data, rowFields, columnFields, searchQuery, sortConfig]);

  // 페이지네이션
  const totalPages = Math.ceil(filteredData.length / pageSize);
  const paginatedData = useMemo(() => {
    const start = (currentPage - 1) * pageSize;
    return filteredData.slice(start, start + pageSize);
  }, [filteredData, currentPage, pageSize]);

  // 표시할 컬럼 결정
  const displayColumns = useMemo(() => {
    // 모든 필드의 field명 수집
    const fieldNames = new Set<string>();
    
    // fields에서 가져오기
    fields.forEach((f) => fieldNames.add(f.field));
    
    // 데이터에서 추가 컬럼 가져오기
    if (data.length > 0) {
      Object.keys(data[0]).forEach((key) => fieldNames.add(key));
    }

    return Array.from(fieldNames).map((fieldName) => {
      const fieldConfig = fields.find((f) => f.field === fieldName);
      return {
        field: fieldName,
        caption: fieldConfig?.caption || fieldName,
        dataType: fieldConfig?.dataType || "string",
      };
    });
  }, [fields, data]);

  // 정렬 토글
  const handleSort = (field: string) => {
    setSortConfig((prev) => {
      if (!prev || prev.field !== field) {
        return { field, direction: "asc" };
      }
      if (prev.direction === "asc") {
        return { field, direction: "desc" };
      }
      return null;
    });
  };

  // CSV 내보내기
  const handleExportCSV = () => {
    if (filteredData.length === 0) return;

    const headers = displayColumns.map((c) => c.caption);
    const rows = filteredData.map((row) =>
      displayColumns.map((c) => {
        const val = row[c.field];
        if (val === null || val === undefined) return "";
        if (typeof val === "string" && val.includes(",")) {
          return `"${val}"`;
        }
        return String(val);
      })
    );

    const csv = [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");

    const blob = new Blob(["\uFEFF" + csv], {
      type: "text/csv;charset=utf-8;",
    });
    const link = document.createElement("a");
    link.href = URL.createObjectURL(blob);
    link.download = `drilldown_${cellData?.rowPath.join("_") || "data"}.csv`;
    link.click();
  };

  // 페이지 변경
  const goToPage = (page: number) => {
    setCurrentPage(Math.max(1, Math.min(page, totalPages)));
  };

  // 경로 표시
  const pathDisplay = cellData
    ? [
        ...(cellData.rowPath.length > 0
          ? [`행: ${cellData.rowPath.join(" > ")}`]
          : []),
        ...(cellData.columnPath.length > 0
          ? [`열: ${cellData.columnPath.join(" > ")}`]
          : []),
      ].join(" | ")
    : "";

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-5xl max-h-[85vh] flex flex-col">
        <DialogHeader>
          <DialogTitle>상세 데이터</DialogTitle>
          <DialogDescription>
            {pathDisplay || "선택한 셀의 원본 데이터"}
            <span className="ml-2 text-primary font-medium">
              ({filteredData.length}건)
            </span>
          </DialogDescription>
        </DialogHeader>

        {/* 툴바 */}
        <div className="flex items-center gap-2 py-2 border-b border-border">
          <div className="relative flex-1">
            <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="검색..."
              value={searchQuery}
              onChange={(e) => {
                setSearchQuery(e.target.value);
                setCurrentPage(1);
              }}
              className="pl-9 h-9"
            />
          </div>

          <Select
            value={String(pageSize)}
            onValueChange={(v) => {
              setPageSize(Number(v));
              setCurrentPage(1);
            }}
          >
            <SelectTrigger className="w-28 h-9">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="10">10개씩</SelectItem>
              <SelectItem value="20">20개씩</SelectItem>
              <SelectItem value="50">50개씩</SelectItem>
              <SelectItem value="100">100개씩</SelectItem>
            </SelectContent>
          </Select>

          <Button
            variant="outline"
            size="sm"
            onClick={handleExportCSV}
            disabled={filteredData.length === 0}
            className="h-9"
          >
            <Download className="h-4 w-4 mr-1" />
            CSV
          </Button>
        </div>

        {/* 테이블 */}
        <ScrollArea className="flex-1 -mx-6">
          <div className="px-6">
            <Table>
              <TableHeader>
                <TableRow>
                  {displayColumns.map((col) => (
                    <TableHead
                      key={col.field}
                      className="whitespace-nowrap cursor-pointer hover:bg-muted/50"
                      onClick={() => handleSort(col.field)}
                    >
                      <div className="flex items-center gap-1">
                        <span>{col.caption}</span>
                        {sortConfig?.field === col.field ? (
                          sortConfig.direction === "asc" ? (
                            <ArrowUp className="h-3 w-3" />
                          ) : (
                            <ArrowDown className="h-3 w-3" />
                          )
                        ) : (
                          <ArrowUpDown className="h-3 w-3 opacity-30" />
                        )}
                      </div>
                    </TableHead>
                  ))}
                </TableRow>
              </TableHeader>
              <TableBody>
                {paginatedData.length === 0 ? (
                  <TableRow>
                    <TableCell
                      colSpan={displayColumns.length}
                      className="text-center py-8 text-muted-foreground"
                    >
                      데이터가 없습니다.
                    </TableCell>
                  </TableRow>
                ) : (
                  paginatedData.map((row, idx) => (
                    <TableRow key={idx}>
                      {displayColumns.map((col) => (
                        <TableCell
                          key={col.field}
                          className={cn(
                            "whitespace-nowrap",
                            col.dataType === "number" && "text-right tabular-nums"
                          )}
                        >
                          {formatCellValue(row[col.field], col.dataType)}
                        </TableCell>
                      ))}
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>
        </ScrollArea>

        {/* 페이지네이션 */}
        {totalPages > 1 && (
          <div className="flex items-center justify-between pt-4 border-t border-border">
            <div className="text-sm text-muted-foreground">
              {(currentPage - 1) * pageSize + 1} -{" "}
              {Math.min(currentPage * pageSize, filteredData.length)} /{" "}
              {filteredData.length}건
            </div>

            <div className="flex items-center gap-1">
              <Button
                variant="outline"
                size="icon"
                className="h-8 w-8"
                onClick={() => goToPage(1)}
                disabled={currentPage === 1}
              >
                <ChevronsLeft className="h-4 w-4" />
              </Button>
              <Button
                variant="outline"
                size="icon"
                className="h-8 w-8"
                onClick={() => goToPage(currentPage - 1)}
                disabled={currentPage === 1}
              >
                <ChevronLeft className="h-4 w-4" />
              </Button>

              <span className="px-3 text-sm">
                {currentPage} / {totalPages}
              </span>

              <Button
                variant="outline"
                size="icon"
                className="h-8 w-8"
                onClick={() => goToPage(currentPage + 1)}
                disabled={currentPage === totalPages}
              >
                <ChevronRight className="h-4 w-4" />
              </Button>
              <Button
                variant="outline"
                size="icon"
                className="h-8 w-8"
                onClick={() => goToPage(totalPages)}
                disabled={currentPage === totalPages}
              >
                <ChevronsRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
};

// ==================== 유틸리티 ====================

function formatCellValue(value: any, dataType: string): string {
  if (value === null || value === undefined) return "-";

  if (dataType === "number") {
    const num = Number(value);
    if (isNaN(num)) return String(value);
    return num.toLocaleString();
  }

  if (dataType === "date") {
    try {
      const date = new Date(value);
      if (!isNaN(date.getTime())) {
        return date.toLocaleDateString("ko-KR");
      }
    } catch {
      // 변환 실패 시 원본 반환
    }
  }

  return String(value);
}

export default DrillDownModal;

