"use client";

/**
 * FieldChooser 컴포넌트
 * 사용 가능한 필드 목록을 표시하고 영역에 배치할 수 있는 모달
 */

import React, { useState, useMemo } from "react";
import { cn } from "@/lib/utils";
import { PivotFieldConfig, PivotAreaType, AggregationType, SummaryDisplayMode } 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 { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Search,
  Filter,
  Columns,
  Rows,
  BarChart3,
  GripVertical,
  Plus,
  Minus,
  Type,
  Hash,
  Calendar,
  ToggleLeft,
} from "lucide-react";

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

interface AvailableField {
  field: string;
  caption: string;
  dataType: "string" | "number" | "date" | "boolean";
  isSelected: boolean;
  currentArea?: PivotAreaType;
}

interface FieldChooserProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  availableFields: AvailableField[];
  selectedFields: PivotFieldConfig[];
  onFieldsChange: (fields: PivotFieldConfig[]) => void;
}

// ==================== 영역 설정 ====================

const AREA_OPTIONS: {
  value: PivotAreaType | "none";
  label: string;
  icon: React.ReactNode;
}[] = [
  { value: "none", label: "사용 안함", icon: <Minus className="h-3.5 w-3.5" /> },
  { value: "filter", label: "필터", icon: <Filter className="h-3.5 w-3.5" /> },
  { value: "row", label: "행", icon: <Rows className="h-3.5 w-3.5" /> },
  { value: "column", label: "열", icon: <Columns className="h-3.5 w-3.5" /> },
  { value: "data", label: "데이터", icon: <BarChart3 className="h-3.5 w-3.5" /> },
];

const SUMMARY_OPTIONS: { value: AggregationType; label: string }[] = [
  { value: "sum", label: "합계" },
  { value: "count", label: "개수" },
  { value: "avg", label: "평균" },
  { value: "min", label: "최소" },
  { value: "max", label: "최대" },
  { value: "countDistinct", label: "고유 개수" },
];

const DISPLAY_MODE_OPTIONS: { value: SummaryDisplayMode; label: string }[] = [
  { value: "absoluteValue", label: "절대값" },
  { value: "percentOfRowTotal", label: "행 총계 %" },
  { value: "percentOfColumnTotal", label: "열 총계 %" },
  { value: "percentOfGrandTotal", label: "전체 총계 %" },
  { value: "runningTotalByRow", label: "행 누계" },
  { value: "runningTotalByColumn", label: "열 누계" },
  { value: "differenceFromPrevious", label: "이전 대비 차이" },
  { value: "percentDifferenceFromPrevious", label: "이전 대비 % 차이" },
];

const DATE_GROUP_OPTIONS: { value: string; label: string }[] = [
  { value: "none", label: "그룹 없음" },
  { value: "year", label: "년" },
  { value: "quarter", label: "분기" },
  { value: "month", label: "월" },
  { value: "week", label: "주" },
  { value: "day", label: "일" },
];

const DATA_TYPE_ICONS: Record<string, React.ReactNode> = {
  string: <Type className="h-3.5 w-3.5" />,
  number: <Hash className="h-3.5 w-3.5" />,
  date: <Calendar className="h-3.5 w-3.5" />,
  boolean: <ToggleLeft className="h-3.5 w-3.5" />,
};

// ==================== 필드 아이템 ====================

interface FieldItemProps {
  field: AvailableField;
  config?: PivotFieldConfig;
  onAreaChange: (area: PivotAreaType | "none") => void;
  onSummaryChange?: (summary: AggregationType) => void;
  onDisplayModeChange?: (displayMode: SummaryDisplayMode) => void;
}

const FieldItem: React.FC<FieldItemProps> = ({
  field,
  config,
  onAreaChange,
  onSummaryChange,
  onDisplayModeChange,
}) => {
  const currentArea = config?.area || "none";
  const isSelected = currentArea !== "none";

  return (
    <div
      className={cn(
        "flex items-center gap-3 p-2 rounded-md border",
        "transition-colors",
        isSelected
          ? "bg-primary/5 border-primary/30"
          : "bg-background border-border hover:bg-muted/50"
      )}
    >
      {/* 데이터 타입 아이콘 */}
      <div className="text-muted-foreground">
        {DATA_TYPE_ICONS[field.dataType] || <Type className="h-3.5 w-3.5" />}
      </div>

      {/* 필드명 */}
      <div className="flex-1 min-w-0">
        <div className="text-sm font-medium truncate">{field.caption}</div>
        <div className="text-xs text-muted-foreground truncate">
          {field.field}
        </div>
      </div>

      {/* 영역 선택 */}
      <Select
        value={currentArea}
        onValueChange={(value) => onAreaChange(value as PivotAreaType | "none")}
      >
        <SelectTrigger className="w-28 h-8 text-xs">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          {AREA_OPTIONS.map((option) => (
            <SelectItem key={option.value} value={option.value}>
              <div className="flex items-center gap-2">
                {option.icon}
                <span>{option.label}</span>
              </div>
            </SelectItem>
          ))}
        </SelectContent>
      </Select>

      {/* 집계 함수 선택 (데이터 영역인 경우) */}
      {currentArea === "data" && onSummaryChange && (
        <Select
          value={config?.summaryType || "sum"}
          onValueChange={(value) => onSummaryChange(value as AggregationType)}
        >
          <SelectTrigger className="w-24 h-8 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            {SUMMARY_OPTIONS.map((option) => (
              <SelectItem key={option.value} value={option.value}>
                {option.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      )}

      {/* 표시 모드 선택 (데이터 영역인 경우) */}
      {currentArea === "data" && onDisplayModeChange && (
        <Select
          value={config?.summaryDisplayMode || "absoluteValue"}
          onValueChange={(value) => onDisplayModeChange(value as SummaryDisplayMode)}
        >
          <SelectTrigger className="w-28 h-8 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            {DISPLAY_MODE_OPTIONS.map((option) => (
              <SelectItem key={option.value} value={option.value}>
                {option.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      )}
    </div>
  );
};

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

export const FieldChooser: React.FC<FieldChooserProps> = ({
  open,
  onOpenChange,
  availableFields,
  selectedFields,
  onFieldsChange,
}) => {
  const [searchQuery, setSearchQuery] = useState("");
  const [filterType, setFilterType] = useState<"all" | "selected" | "unselected">(
    "all"
  );

  // 필터링된 필드 목록
  const filteredFields = useMemo(() => {
    let result = availableFields;

    // 검색어 필터
    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      result = result.filter(
        (f) =>
          f.caption.toLowerCase().includes(query) ||
          f.field.toLowerCase().includes(query)
      );
    }

    // 선택 상태 필터
    if (filterType === "selected") {
      result = result.filter((f) =>
        selectedFields.some((sf) => sf.field === f.field && sf.visible !== false)
      );
    } else if (filterType === "unselected") {
      result = result.filter(
        (f) =>
          !selectedFields.some(
            (sf) => sf.field === f.field && sf.visible !== false
          )
      );
    }

    return result;
  }, [availableFields, selectedFields, searchQuery, filterType]);

  // 필드 영역 변경
  const handleAreaChange = (
    field: AvailableField,
    area: PivotAreaType | "none"
  ) => {
    const existingConfig = selectedFields.find((f) => f.field === field.field);

    if (area === "none") {
      // 필드 완전 제거 (visible: false 대신 배열에서 제거)
      if (existingConfig) {
        const newFields = selectedFields.filter((f) => f.field !== field.field);
        onFieldsChange(newFields);
      }
    } else {
      // 필드 추가 또는 영역 변경
      if (existingConfig) {
        const newFields = selectedFields.map((f) =>
          f.field === field.field
            ? { ...f, area, visible: true }
            : f
        );
        onFieldsChange(newFields);
      } else {
        // 새 필드 추가
        const newField: PivotFieldConfig = {
          field: field.field,
          caption: field.caption,
          area,
          dataType: field.dataType,
          visible: true,
          summaryType: area === "data" ? "sum" : undefined,
          areaIndex: selectedFields.filter((f) => f.area === area).length,
        };
        onFieldsChange([...selectedFields, newField]);
      }
    }
  };

  // 집계 함수 변경
  const handleSummaryChange = (
    field: AvailableField,
    summaryType: AggregationType
  ) => {
    const newFields = selectedFields.map((f) =>
      f.field === field.field ? { ...f, summaryType } : f
    );
    onFieldsChange(newFields);
  };

  // 표시 모드 변경
  const handleDisplayModeChange = (
    field: AvailableField,
    displayMode: SummaryDisplayMode
  ) => {
    const newFields = selectedFields.map((f) =>
      f.field === field.field ? { ...f, summaryDisplayMode: displayMode } : f
    );
    onFieldsChange(newFields);
  };

  // 모든 필드 선택 해제
  const handleClearAll = () => {
    const newFields = selectedFields.map((f) => ({ ...f, visible: false }));
    onFieldsChange(newFields);
  };

  // 통계
  const stats = useMemo(() => {
    const visible = selectedFields.filter((f) => f.visible !== false);
    return {
      total: availableFields.length,
      selected: visible.length,
      filter: visible.filter((f) => f.area === "filter").length,
      row: visible.filter((f) => f.area === "row").length,
      column: visible.filter((f) => f.area === "column").length,
      data: visible.filter((f) => f.area === "data").length,
    };
  }, [availableFields, selectedFields]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl max-h-[80vh] flex flex-col">
        <DialogHeader>
          <DialogTitle>필드 선택기</DialogTitle>
          <DialogDescription>
            피벗 테이블에 표시할 필드를 선택하고 영역을 지정하세요.
          </DialogDescription>
        </DialogHeader>

        {/* 통계 */}
        <div className="flex items-center gap-4 py-2 px-1 text-xs text-muted-foreground border-b border-border">
          <span>전체: {stats.total}</span>
          <span className="text-primary font-medium">
            선택됨: {stats.selected}
          </span>
          <span>필터: {stats.filter}</span>
          <span>행: {stats.row}</span>
          <span>열: {stats.column}</span>
          <span>데이터: {stats.data}</span>
        </div>

        {/* 검색 및 필터 */}
        <div className="flex items-center gap-2 py-2">
          <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)}
              className="pl-9 h-9"
            />
          </div>

          <Select
            value={filterType}
            onValueChange={(v) =>
              setFilterType(v as "all" | "selected" | "unselected")
            }
          >
            <SelectTrigger className="w-32 h-9">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">전체</SelectItem>
              <SelectItem value="selected">선택됨</SelectItem>
              <SelectItem value="unselected">미선택</SelectItem>
            </SelectContent>
          </Select>

          <Button
            variant="outline"
            size="sm"
            onClick={handleClearAll}
            className="h-9"
          >
            초기화
          </Button>
        </div>

        {/* 필드 목록 */}
        <ScrollArea className="flex-1 -mx-6 px-6 max-h-[40vh] overflow-y-auto">
          <div className="space-y-2 py-2">
            {filteredFields.length === 0 ? (
              <div className="text-center py-8 text-muted-foreground">
                검색 결과가 없습니다.
              </div>
            ) : (
              filteredFields.map((field) => {
                const config = selectedFields.find(
                  (f) => f.field === field.field && f.visible !== false
                );
                return (
                  <FieldItem
                    key={field.field}
                    field={field}
                    config={config}
                    onAreaChange={(area) => handleAreaChange(field, area)}
                    onSummaryChange={
                      config?.area === "data"
                        ? (summary) => handleSummaryChange(field, summary)
                        : undefined
                    }
                    onDisplayModeChange={
                      config?.area === "data"
                        ? (mode) => handleDisplayModeChange(field, mode)
                        : undefined
                    }
                  />
                );
              })
            )}
          </div>
        </ScrollArea>

        {/* 푸터 */}
        <div className="flex justify-end gap-2 pt-4 border-t border-border">
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            닫기
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
};

export default FieldChooser;

