"use client";

/**
 * PivotGrid 설정 패널
 * 화면 관리에서 PivotGrid 컴포넌트를 설정하는 UI
 */

import React, { useState, useEffect, useCallback } from "react";
import { cn } from "@/lib/utils";
import {
  PivotGridComponentConfig,
  PivotFieldConfig,
  PivotAreaType,
  AggregationType,
  DateGroupInterval,
  FieldDataType,
} from "./types";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Separator } from "@/components/ui/separator";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import {
  Plus,
  Trash2,
  GripVertical,
  Settings2,
  Rows,
  Columns,
  Database,
  Filter,
  ChevronUp,
  ChevronDown,
} from "lucide-react";
import { apiClient } from "@/lib/api/client";

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

interface TableInfo {
  table_name: string;
  table_comment?: string;
}

interface ColumnInfo {
  column_name: string;
  data_type: string;
  column_comment?: string;
  is_nullable: string;
}

interface PivotGridConfigPanelProps {
  config: PivotGridComponentConfig;
  onChange: (config: PivotGridComponentConfig) => void;
}

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

const AREA_LABELS: Record<PivotAreaType, { label: string; icon: React.ReactNode }> = {
  row: { label: "행 영역", icon: <Rows className="h-4 w-4" /> },
  column: { label: "열 영역", icon: <Columns className="h-4 w-4" /> },
  data: { label: "데이터 영역", icon: <Database className="h-4 w-4" /> },
  filter: { label: "필터 영역", icon: <Filter className="h-4 w-4" /> },
};

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

const DATE_GROUP_OPTIONS: { value: DateGroupInterval; label: string }[] = [
  { value: "year", label: "연도" },
  { value: "quarter", label: "분기" },
  { value: "month", label: "월" },
  { value: "week", label: "주" },
  { value: "day", label: "일" },
];

const DATA_TYPE_OPTIONS: { value: FieldDataType; label: string }[] = [
  { value: "string", label: "문자열" },
  { value: "number", label: "숫자" },
  { value: "date", label: "날짜" },
  { value: "boolean", label: "부울" },
];

// DB 타입을 FieldDataType으로 변환
function mapDbTypeToFieldType(dbType: string): FieldDataType {
  const type = dbType.toLowerCase();
  if (
    type.includes("int") ||
    type.includes("numeric") ||
    type.includes("decimal") ||
    type.includes("float") ||
    type.includes("double") ||
    type.includes("real")
  ) {
    return "number";
  }
  if (
    type.includes("date") ||
    type.includes("time") ||
    type.includes("timestamp")
  ) {
    return "date";
  }
  if (type.includes("bool")) {
    return "boolean";
  }
  return "string";
}

// ==================== 필드 설정 컴포넌트 ====================

interface FieldConfigItemProps {
  field: PivotFieldConfig;
  index: number;
  onChange: (field: PivotFieldConfig) => void;
  onRemove: () => void;
  onMoveUp: () => void;
  onMoveDown: () => void;
  isFirst: boolean;
  isLast: boolean;
}

const FieldConfigItem: React.FC<FieldConfigItemProps> = ({
  field,
  index,
  onChange,
  onRemove,
  onMoveUp,
  onMoveDown,
  isFirst,
  isLast,
}) => {
  return (
    <div className="flex items-start gap-2 p-2 rounded border border-border bg-background">
      {/* 드래그 핸들 & 순서 버튼 */}
      <div className="flex flex-col items-center gap-0.5 pt-1">
        <Button
          variant="ghost"
          size="icon"
          className="h-5 w-5"
          onClick={onMoveUp}
          disabled={isFirst}
        >
          <ChevronUp className="h-3 w-3" />
        </Button>
        <GripVertical className="h-4 w-4 text-muted-foreground" />
        <Button
          variant="ghost"
          size="icon"
          className="h-5 w-5"
          onClick={onMoveDown}
          disabled={isLast}
        >
          <ChevronDown className="h-3 w-3" />
        </Button>
      </div>

      {/* 필드 설정 */}
      <div className="flex-1 space-y-2">
        {/* 필드명 & 라벨 */}
        <div className="flex gap-2">
          <div className="flex-1">
            <Label className="text-xs">필드명</Label>
            <Input
              value={field.field}
              onChange={(e) => onChange({ ...field, field: e.target.value })}
              placeholder="column_name"
              className="h-8 text-xs"
            />
          </div>
          <div className="flex-1">
            <Label className="text-xs">표시 라벨</Label>
            <Input
              value={field.caption}
              onChange={(e) => onChange({ ...field, caption: e.target.value })}
              placeholder="표시명"
              className="h-8 text-xs"
            />
          </div>
        </div>

        {/* 데이터 타입 & 집계 함수 */}
        <div className="flex gap-2">
          <div className="flex-1">
            <Label className="text-xs">데이터 타입</Label>
            <Select
              value={field.dataType || "string"}
              onValueChange={(v) =>
                onChange({ ...field, dataType: v as FieldDataType })
              }
            >
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {DATA_TYPE_OPTIONS.map((opt) => (
                  <SelectItem key={opt.value} value={opt.value}>
                    {opt.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {field.area === "data" && (
            <div className="flex-1">
              <Label className="text-xs">집계 함수</Label>
              <Select
                value={field.summaryType || "sum"}
                onValueChange={(v) =>
                  onChange({ ...field, summaryType: v as AggregationType })
                }
              >
                <SelectTrigger className="h-8 text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {AGGREGATION_OPTIONS.map((opt) => (
                    <SelectItem key={opt.value} value={opt.value}>
                      {opt.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          )}

          {field.dataType === "date" &&
            (field.area === "row" || field.area === "column") && (
              <div className="flex-1">
                <Label className="text-xs">그룹 단위</Label>
                <Select
                  value={field.groupInterval || "__none__"}
                  onValueChange={(v) =>
                    onChange({
                      ...field,
                      groupInterval:
                        v === "__none__" ? undefined : (v as DateGroupInterval),
                    })
                  }
                >
                  <SelectTrigger className="h-8 text-xs">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="__none__">원본값</SelectItem>
                    {DATE_GROUP_OPTIONS.map((opt) => (
                      <SelectItem key={opt.value} value={opt.value}>
                        {opt.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            )}
        </div>
      </div>

      {/* 삭제 버튼 */}
      <Button
        variant="ghost"
        size="icon"
        className="h-8 w-8 text-destructive hover:text-destructive"
        onClick={onRemove}
      >
        <Trash2 className="h-4 w-4" />
      </Button>
    </div>
  );
};

// ==================== 영역별 필드 목록 ====================

interface AreaFieldListProps {
  area: PivotAreaType;
  fields: PivotFieldConfig[];
  allColumns: ColumnInfo[];
  onFieldsChange: (fields: PivotFieldConfig[]) => void;
}

const AreaFieldList: React.FC<AreaFieldListProps> = ({
  area,
  fields,
  allColumns,
  onFieldsChange,
}) => {
  const areaFields = fields.filter((f) => f.area === area);
  const { label, icon } = AREA_LABELS[area];

  const handleAddField = () => {
    const newField: PivotFieldConfig = {
      field: "",
      caption: "",
      area,
      areaIndex: areaFields.length,
      dataType: "string",
      visible: true,
    };
    if (area === "data") {
      newField.summaryType = "sum";
    }
    onFieldsChange([...fields, newField]);
  };

  const handleAddFromColumn = (column: ColumnInfo) => {
    const dataType = mapDbTypeToFieldType(column.data_type);
    const newField: PivotFieldConfig = {
      field: column.column_name,
      caption: column.column_comment || column.column_name,
      area,
      areaIndex: areaFields.length,
      dataType,
      visible: true,
    };
    if (area === "data") {
      newField.summaryType = "sum";
    }
    onFieldsChange([...fields, newField]);
  };

  const handleFieldChange = (index: number, updatedField: PivotFieldConfig) => {
    const newFields = [...fields];
    const globalIndex = fields.findIndex(
      (f) => f.area === area && f.areaIndex === index
    );
    if (globalIndex >= 0) {
      newFields[globalIndex] = updatedField;
      onFieldsChange(newFields);
    }
  };

  const handleRemoveField = (index: number) => {
    const newFields = fields.filter(
      (f) => !(f.area === area && f.areaIndex === index)
    );
    // 인덱스 재정렬
    let idx = 0;
    newFields.forEach((f) => {
      if (f.area === area) {
        f.areaIndex = idx++;
      }
    });
    onFieldsChange(newFields);
  };

  const handleMoveField = (fromIndex: number, direction: "up" | "down") => {
    const toIndex = direction === "up" ? fromIndex - 1 : fromIndex + 1;
    if (toIndex < 0 || toIndex >= areaFields.length) return;

    const newAreaFields = [...areaFields];
    const [moved] = newAreaFields.splice(fromIndex, 1);
    newAreaFields.splice(toIndex, 0, moved);

    // 인덱스 재정렬
    newAreaFields.forEach((f, idx) => {
      f.areaIndex = idx;
    });

    // 전체 필드 업데이트
    const newFields = fields.filter((f) => f.area !== area);
    onFieldsChange([...newFields, ...newAreaFields]);
  };

  // 이미 추가된 컬럼 제외
  const availableColumns = allColumns.filter(
    (col) => !fields.some((f) => f.field === col.column_name)
  );

  return (
    <AccordionItem value={area}>
      <AccordionTrigger className="py-2">
        <div className="flex items-center gap-2">
          {icon}
          <span>{label}</span>
          <Badge variant="secondary" className="ml-2">
            {areaFields.length}
          </Badge>
        </div>
      </AccordionTrigger>
      <AccordionContent className="space-y-2 pt-2">
        {/* 필드 목록 */}
        {areaFields
          .sort((a, b) => (a.areaIndex || 0) - (b.areaIndex || 0))
          .map((field, idx) => (
            <FieldConfigItem
              key={`${field.field}-${idx}`}
              field={field}
              index={field.areaIndex || idx}
              onChange={(f) => handleFieldChange(field.areaIndex || idx, f)}
              onRemove={() => handleRemoveField(field.areaIndex || idx)}
              onMoveUp={() => handleMoveField(idx, "up")}
              onMoveDown={() => handleMoveField(idx, "down")}
              isFirst={idx === 0}
              isLast={idx === areaFields.length - 1}
            />
          ))}

        {/* 필드 추가 */}
        <div className="flex gap-2">
          <Select onValueChange={(v) => {
            const col = allColumns.find(c => c.column_name === v);
            if (col) handleAddFromColumn(col);
          }}>
            <SelectTrigger className="h-8 text-xs flex-1">
              <SelectValue placeholder="컬럼 선택" />
            </SelectTrigger>
            <SelectContent>
              {availableColumns.length === 0 ? (
                <SelectItem value="__none__" disabled>
                  추가 가능한 컬럼이 없습니다
                </SelectItem>
              ) : (
                availableColumns.map((col) => (
                  <SelectItem key={col.column_name} value={col.column_name}>
                    <div className="flex items-center gap-2">
                      <span>{col.column_name}</span>
                      {col.column_comment && (
                        <span className="text-muted-foreground">
                          ({col.column_comment})
                        </span>
                      )}
                    </div>
                  </SelectItem>
                ))
              )}
            </SelectContent>
          </Select>

          <Button
            variant="outline"
            size="sm"
            className="h-8"
            onClick={handleAddField}
          >
            <Plus className="h-4 w-4 mr-1" />
            직접 추가
          </Button>
        </div>
      </AccordionContent>
    </AccordionItem>
  );
};

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

export const PivotGridConfigPanel: React.FC<PivotGridConfigPanelProps> = ({
  config,
  onChange,
}) => {
  const [tables, setTables] = useState<TableInfo[]>([]);
  const [columns, setColumns] = useState<ColumnInfo[]>([]);
  const [loadingTables, setLoadingTables] = useState(false);
  const [loadingColumns, setLoadingColumns] = useState(false);

  // 테이블 목록 로드
  useEffect(() => {
    const loadTables = async () => {
      setLoadingTables(true);
      try {
        const response = await apiClient.get("/api/table-management/list");
        if (response.data.success) {
          setTables(response.data.data || []);
        }
      } catch (error) {
        console.error("테이블 목록 로드 실패:", error);
      } finally {
        setLoadingTables(false);
      }
    };
    loadTables();
  }, []);

  // 테이블 선택 시 컬럼 로드
  useEffect(() => {
    const loadColumns = async () => {
      if (!config.dataSource?.tableName) {
        setColumns([]);
        return;
      }

      setLoadingColumns(true);
      try {
        const response = await apiClient.get(
          `/api/table-management/columns/${config.dataSource.tableName}`
        );
        if (response.data.success) {
          setColumns(response.data.data || []);
        }
      } catch (error) {
        console.error("컬럼 목록 로드 실패:", error);
      } finally {
        setLoadingColumns(false);
      }
    };
    loadColumns();
  }, [config.dataSource?.tableName]);

  // 설정 업데이트 헬퍼
  const updateConfig = useCallback(
    (updates: Partial<PivotGridComponentConfig>) => {
      onChange({ ...config, ...updates });
    },
    [config, onChange]
  );

  return (
    <div className="space-y-4">
      {/* 데이터 소스 설정 */}
      <div className="space-y-3">
        <Label className="text-sm font-medium">데이터 소스</Label>

        <div className="space-y-2">
          <Label className="text-xs">테이블 선택</Label>
          <Select
            value={config.dataSource?.tableName || "__none__"}
            onValueChange={(v) =>
              updateConfig({
                dataSource: {
                  ...config.dataSource,
                  type: "table",
                  tableName: v === "__none__" ? undefined : v,
                },
                fields: [], // 테이블 변경 시 필드 초기화
              })
            }
          >
            <SelectTrigger className="h-9">
              <SelectValue placeholder="테이블 선택" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="__none__">선택 안 함</SelectItem>
              {tables.map((table) => (
                <SelectItem key={table.table_name} value={table.table_name}>
                  <div className="flex items-center gap-2">
                    <span>{table.table_name}</span>
                    {table.table_comment && (
                      <span className="text-muted-foreground">
                        ({table.table_comment})
                      </span>
                    )}
                  </div>
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>

      <Separator />

      {/* 필드 설정 */}
      {config.dataSource?.tableName && (
        <div className="space-y-3">
          <div className="flex items-center justify-between">
            <Label className="text-sm font-medium">필드 설정</Label>
            <Badge variant="outline">
              {columns.length}개 컬럼
            </Badge>
          </div>

          {loadingColumns ? (
            <div className="text-sm text-muted-foreground">
              컬럼 로딩 중...
            </div>
          ) : (
            <Accordion
              type="multiple"
              defaultValue={["row", "column", "data"]}
              className="w-full"
            >
              {(["row", "column", "data", "filter"] as PivotAreaType[]).map(
                (area) => (
                  <AreaFieldList
                    key={area}
                    area={area}
                    fields={config.fields || []}
                    allColumns={columns}
                    onFieldsChange={(fields) => updateConfig({ fields })}
                  />
                )
              )}
            </Accordion>
          )}
        </div>
      )}

      <Separator />

      {/* 표시 설정 */}
      <div className="space-y-3">
        <Label className="text-sm font-medium">표시 설정</Label>

        <div className="grid grid-cols-2 gap-3">
          <div className="flex items-center justify-between">
            <Label className="text-xs">행 총계</Label>
            <Switch
              checked={config.totals?.showRowGrandTotals !== false}
              onCheckedChange={(v) =>
                updateConfig({
                  totals: { ...config.totals, showRowGrandTotals: v },
                })
              }
            />
          </div>

          <div className="flex items-center justify-between">
            <Label className="text-xs">열 총계</Label>
            <Switch
              checked={config.totals?.showColumnGrandTotals !== false}
              onCheckedChange={(v) =>
                updateConfig({
                  totals: { ...config.totals, showColumnGrandTotals: v },
                })
              }
            />
          </div>

          <div className="flex items-center justify-between">
            <Label className="text-xs">행 소계</Label>
            <Switch
              checked={config.totals?.showRowTotals !== false}
              onCheckedChange={(v) =>
                updateConfig({
                  totals: { ...config.totals, showRowTotals: v },
                })
              }
            />
          </div>

          <div className="flex items-center justify-between">
            <Label className="text-xs">열 소계</Label>
            <Switch
              checked={config.totals?.showColumnTotals !== false}
              onCheckedChange={(v) =>
                updateConfig({
                  totals: { ...config.totals, showColumnTotals: v },
                })
              }
            />
          </div>
        </div>

        <div className="flex items-center justify-between">
          <Label className="text-xs">줄 교차 색상</Label>
          <Switch
            checked={config.style?.alternateRowColors !== false}
            onCheckedChange={(v) =>
              updateConfig({
                style: { ...config.style, alternateRowColors: v },
              })
            }
          />
        </div>

        <div className="flex items-center justify-between">
          <Label className="text-xs">총계 강조</Label>
          <Switch
            checked={config.style?.highlightTotals !== false}
            onCheckedChange={(v) =>
              updateConfig({
                style: { ...config.style, highlightTotals: v },
              })
            }
          />
        </div>
      </div>

      <Separator />

      {/* 기능 설정 */}
      <div className="space-y-3">
        <Label className="text-sm font-medium">기능 설정</Label>

        <div className="space-y-2">
          <div className="flex items-center justify-between">
            <Label className="text-xs">전체 확장/축소 버튼</Label>
            <Switch
              checked={config.allowExpandAll !== false}
              onCheckedChange={(v) =>
                updateConfig({ allowExpandAll: v })
              }
            />
          </div>

          <div className="flex items-center justify-between">
            <Label className="text-xs">CSV 내보내기</Label>
            <Switch
              checked={config.exportConfig?.excel === true}
              onCheckedChange={(v) =>
                updateConfig({
                  exportConfig: { ...config.exportConfig, excel: v },
                })
              }
            />
          </div>
        </div>
      </div>

      <Separator />

      {/* 크기 설정 */}
      <div className="space-y-3">
        <Label className="text-sm font-medium">크기 설정</Label>

        <div className="grid grid-cols-2 gap-3">
          <div>
            <Label className="text-xs">높이</Label>
            <Input
              value={config.height || ""}
              onChange={(e) => updateConfig({ height: e.target.value })}
              placeholder="auto 또는 400px"
              className="h-8 text-xs"
            />
          </div>

          <div>
            <Label className="text-xs">최대 높이</Label>
            <Input
              value={config.maxHeight || ""}
              onChange={(e) => updateConfig({ maxHeight: e.target.value })}
              placeholder="600px"
              className="h-8 text-xs"
            />
          </div>
        </div>
      </div>
    </div>
  );
};

export default PivotGridConfigPanel;

