"use client";

/**
 * V2StatusCount 설정 패널
 * 토스식 단계별 UX: 데이터 소스 -> 컬럼 매핑 -> 상태 항목 관리 -> 표시 설정(접힘)
 * 기존 StatusCountConfigPanel의 모든 기능을 자체 UI로 완전 구현
 */

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Separator } from "@/components/ui/separator";
import {
  Table2,
  Columns3,
  Check,
  ChevronsUpDown,
  Loader2,
  Link2,
  Plus,
  Trash2,
  BarChart3,
  Type,
  Maximize2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { tableTypeApi } from "@/lib/api/screen";
import { entityJoinApi, type EntityJoinConfig } from "@/lib/api/entityJoin";
import { apiClient } from "@/lib/api/client";
import type { StatusCountConfig, StatusCountItem } from "@/lib/registry/components/v2-status-count/types";
import { STATUS_COLOR_MAP } from "@/lib/registry/components/v2-status-count/types";

const COLOR_OPTIONS = Object.keys(STATUS_COLOR_MAP);

// ─── 카드 크기 선택 카드 ───
const SIZE_CARDS = [
  { value: "sm", title: "작게", description: "컴팩트" },
  { value: "md", title: "보통", description: "기본 크기" },
  { value: "lg", title: "크게", description: "넓은 카드" },
] as const;

// ─── 섹션 헤더 컴포넌트 ───
function SectionHeader({ icon: Icon, title, description }: {
  icon: React.ComponentType<{ className?: string }>;
  title: string;
  description?: string;
}) {
  return (
    <div className="space-y-1">
      <div className="flex items-center gap-2">
        <Icon className="h-4 w-4 text-muted-foreground" />
        <h3 className="text-sm font-semibold">{title}</h3>
      </div>
      {description && <p className="text-muted-foreground text-[10px]">{description}</p>}
    </div>
  );
}

// ─── 수평 라벨 + 컨트롤 Row ───
function LabeledRow({ label, description, children }: {
  label: string;
  description?: string;
  children: React.ReactNode;
}) {
  return (
    <div className="flex items-center justify-between py-1">
      <div className="space-y-0.5">
        <p className="text-xs text-muted-foreground">{label}</p>
        {description && <p className="text-[10px] text-muted-foreground">{description}</p>}
      </div>
      {children}
    </div>
  );
}

interface V2StatusCountConfigPanelProps {
  config: StatusCountConfig;
  onChange: (config: Partial<StatusCountConfig>) => void;
}

export const V2StatusCountConfigPanel: React.FC<V2StatusCountConfigPanelProps> = ({
  config,
  onChange,
}) => {
  // componentConfigChanged 이벤트 발행 래퍼
  const handleChange = useCallback((newConfig: Partial<StatusCountConfig>) => {
    onChange(newConfig);
    if (typeof window !== "undefined") {
      window.dispatchEvent(
        new CustomEvent("componentConfigChanged", {
          detail: { config: { ...config, ...newConfig } },
        })
      );
    }
  }, [onChange, config]);

  const updateField = useCallback((key: keyof StatusCountConfig, value: any) => {
    handleChange({ [key]: value });
  }, [handleChange]);

  // ─── 상태 ───
  const [tables, setTables] = useState<Array<{ tableName: string; displayName: string }>>([]);
  const [columns, setColumns] = useState<Array<{ columnName: string; columnLabel: string }>>([]);
  const [entityJoins, setEntityJoins] = useState<EntityJoinConfig[]>([]);
  const [loadingTables, setLoadingTables] = useState(false);
  const [loadingColumns, setLoadingColumns] = useState(false);
  const [loadingJoins, setLoadingJoins] = useState(false);

  const [statusCategoryValues, setStatusCategoryValues] = useState<Array<{ value: string; label: string }>>([]);
  const [loadingCategoryValues, setLoadingCategoryValues] = useState(false);

  const [tableComboboxOpen, setTableComboboxOpen] = useState(false);
  const [statusColumnOpen, setStatusColumnOpen] = useState(false);
  const [relationOpen, setRelationOpen] = useState(false);
  const items = config.items || [];

  // ─── 테이블 목록 로드 ───
  useEffect(() => {
    const loadTables = async () => {
      setLoadingTables(true);
      try {
        const result = await tableTypeApi.getTables();
        setTables(
          (result || []).map((t: any) => ({
            tableName: t.tableName || t.table_name,
            displayName: t.displayName || t.tableName || t.table_name,
          }))
        );
      } catch (err) {
        console.error("테이블 목록 로드 실패:", err);
      } finally {
        setLoadingTables(false);
      }
    };
    loadTables();
  }, []);

  // ─── 선택된 테이블의 컬럼 + 엔티티 조인 로드 ───
  useEffect(() => {
    if (!config.tableName) {
      setColumns([]);
      setEntityJoins([]);
      return;
    }

    const loadColumns = async () => {
      setLoadingColumns(true);
      try {
        const result = await tableTypeApi.getColumns(config.tableName);
        setColumns(
          (result || []).map((c: any) => ({
            columnName: c.columnName || c.column_name,
            columnLabel: c.columnLabel || c.column_label || c.displayName || c.columnName || c.column_name,
          }))
        );
      } catch (err) {
        console.error("컬럼 목록 로드 실패:", err);
      } finally {
        setLoadingColumns(false);
      }
    };

    const loadEntityJoins = async () => {
      setLoadingJoins(true);
      try {
        const result = await entityJoinApi.getEntityJoinConfigs(config.tableName);
        setEntityJoins(result?.joinConfigs || []);
      } catch (err) {
        console.error("엔티티 조인 설정 로드 실패:", err);
        setEntityJoins([]);
      } finally {
        setLoadingJoins(false);
      }
    };

    loadColumns();
    loadEntityJoins();
  }, [config.tableName]);

  // ─── 상태 컬럼의 카테고리 값 로드 ───
  useEffect(() => {
    if (!config.tableName || !config.statusColumn) {
      setStatusCategoryValues([]);
      return;
    }

    const loadCategoryValues = async () => {
      setLoadingCategoryValues(true);
      try {
        const response = await apiClient.get(
          `/table-categories/${config.tableName}/${config.statusColumn}/values`
        );
        if (response.data?.success && response.data?.data) {
          const flatValues: Array<{ value: string; label: string }> = [];
          const flatten = (categoryItems: any[]) => {
            for (const item of categoryItems) {
              flatValues.push({
                value: item.valueCode || item.value_code,
                label: item.valueLabel || item.value_label,
              });
              if (item.children?.length > 0) flatten(item.children);
            }
          };
          flatten(response.data.data);
          setStatusCategoryValues(flatValues);
        }
      } catch {
        setStatusCategoryValues([]);
      } finally {
        setLoadingCategoryValues(false);
      }
    };

    loadCategoryValues();
  }, [config.tableName, config.statusColumn]);

  // ─── 엔티티 관계 Combobox 아이템 ───
  const relationComboItems = useMemo(() => {
    return entityJoins.map((ej) => {
      const refTableLabel = tables.find((t) => t.tableName === ej.referenceTable)?.displayName || ej.referenceTable;
      return {
        value: `${ej.sourceColumn}::${ej.referenceTable}.${ej.referenceColumn}`,
        label: `${ej.sourceColumn} -> ${refTableLabel}`,
        sublabel: `${ej.referenceTable}.${ej.referenceColumn}`,
      };
    });
  }, [entityJoins, tables]);

  const currentRelationValue = useMemo(() => {
    if (!config.relationColumn) return "";
    return relationComboItems.find((item) => {
      const [srcCol] = item.value.split("::");
      return srcCol === config.relationColumn;
    })?.value || "";
  }, [config.relationColumn, relationComboItems]);

  // ─── 상태 항목 관리 ───
  const addItem = useCallback(() => {
    updateField("items", [...items, { value: "", label: "새 상태", color: "gray" }]);
  }, [items, updateField]);

  const removeItem = useCallback((index: number) => {
    updateField("items", items.filter((_: StatusCountItem, i: number) => i !== index));
  }, [items, updateField]);

  const updateItem = useCallback((index: number, key: keyof StatusCountItem, value: string) => {
    const newItems = [...items];
    newItems[index] = { ...newItems[index], [key]: value };
    updateField("items", newItems);
  }, [items, updateField]);

  // ─── 테이블 변경 핸들러 ───
  const handleTableChange = useCallback((newTableName: string) => {
    handleChange({ tableName: newTableName, statusColumn: "", relationColumn: "", parentColumn: "" });
    setTableComboboxOpen(false);
  }, [handleChange]);

  // ─── 렌더링 ───
  return (
    <div className="space-y-4">
      {/* ═══════════════════════════════════════ */}
      {/* 1단계: 데이터 소스 (테이블 선택)         */}
      {/* ═══════════════════════════════════════ */}
      <div className="space-y-3">
        <SectionHeader icon={Table2} title="데이터 소스" description="상태를 집계할 테이블을 선택하세요" />
        <Separator />

        {/* 제목 */}
        <div className="space-y-1">
          <div className="flex items-center gap-2">
            <Type className="h-3.5 w-3.5 text-muted-foreground" />
            <span className="text-xs font-medium">제목</span>
          </div>
          <Input
            value={config.title || ""}
            onChange={(e) => updateField("title", e.target.value)}
            placeholder="예: 일련번호 현황"
            className="h-7 text-xs"
          />
        </div>

        {/* 테이블 선택 */}
        <Popover open={tableComboboxOpen} onOpenChange={setTableComboboxOpen}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={tableComboboxOpen}
              className="h-8 w-full justify-between text-xs"
              disabled={loadingTables}
            >
              <div className="flex items-center gap-2 truncate">
                <Table2 className="h-3 w-3 shrink-0" />
                <span className="truncate">
                  {loadingTables
                    ? "테이블 로딩 중..."
                    : config.tableName
                      ? tables.find((t) => t.tableName === config.tableName)?.displayName || config.tableName
                      : "테이블 선택"}
                </span>
              </div>
              <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
            <Command>
              <CommandInput placeholder="테이블 검색..." className="text-xs" />
              <CommandList>
                <CommandEmpty className="text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
                <CommandGroup>
                  {tables.map((table) => (
                    <CommandItem
                      key={table.tableName}
                      value={`${table.displayName} ${table.tableName}`}
                      onSelect={() => handleTableChange(table.tableName)}
                      className="text-xs"
                    >
                      <Check
                        className={cn("mr-2 h-3 w-3", config.tableName === table.tableName ? "opacity-100" : "opacity-0")}
                      />
                      <div className="flex flex-col">
                        <span>{table.displayName}</span>
                        {table.displayName !== table.tableName && (
                          <span className="text-[10px] text-muted-foreground/70">{table.tableName}</span>
                        )}
                      </div>
                    </CommandItem>
                  ))}
                </CommandGroup>
              </CommandList>
            </Command>
          </PopoverContent>
        </Popover>
      </div>

      {/* ═══════════════════════════════════════ */}
      {/* 2단계: 컬럼 매핑                         */}
      {/* ═══════════════════════════════════════ */}
      {config.tableName && (
        <div className="space-y-3">
          <SectionHeader icon={Columns3} title="컬럼 매핑" description="상태 컬럼과 부모 관계를 설정하세요" />
          <Separator />

          {/* 상태 컬럼 */}
          <div className="space-y-1">
            <span className="text-xs font-medium">상태 컬럼 *</span>
            <Popover open={statusColumnOpen} onOpenChange={setStatusColumnOpen}>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  role="combobox"
                  aria-expanded={statusColumnOpen}
                  className="h-8 w-full justify-between text-xs"
                  disabled={loadingColumns}
                >
                  <span className="truncate">
                    {loadingColumns
                      ? "컬럼 로딩 중..."
                      : config.statusColumn
                        ? columns.find((c) => c.columnName === config.statusColumn)?.columnLabel || config.statusColumn
                        : "상태 컬럼 선택"}
                  </span>
                  <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
                </Button>
              </PopoverTrigger>
              <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
                <Command>
                  <CommandInput placeholder="컬럼 검색..." className="text-xs" />
                  <CommandList>
                    <CommandEmpty className="text-xs">컬럼을 찾을 수 없습니다.</CommandEmpty>
                    <CommandGroup>
                      {columns.map((col) => (
                        <CommandItem
                          key={col.columnName}
                          value={`${col.columnLabel} ${col.columnName}`}
                          onSelect={() => {
                            updateField("statusColumn", col.columnName);
                            setStatusColumnOpen(false);
                          }}
                          className="text-xs"
                        >
                          <Check
                            className={cn("mr-2 h-3 w-3", config.statusColumn === col.columnName ? "opacity-100" : "opacity-0")}
                          />
                          <div className="flex flex-col">
                            <span>{col.columnLabel}</span>
                            {col.columnLabel !== col.columnName && (
                              <span className="text-[10px] text-muted-foreground/70">{col.columnName}</span>
                            )}
                          </div>
                        </CommandItem>
                      ))}
                    </CommandGroup>
                  </CommandList>
                </Command>
              </PopoverContent>
            </Popover>
          </div>

          {/* 엔티티 관계 */}
          <div className="space-y-1">
            <div className="flex items-center gap-2">
              <Link2 className="h-3.5 w-3.5 text-muted-foreground" />
              <span className="text-xs font-medium">엔티티 관계</span>
            </div>

            {loadingJoins ? (
              <div className="flex items-center gap-1 text-xs text-muted-foreground">
                <Loader2 className="h-3 w-3 animate-spin" /> 로딩중...
              </div>
            ) : entityJoins.length > 0 ? (
              <Popover open={relationOpen} onOpenChange={setRelationOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={relationOpen}
                    className="h-8 w-full justify-between text-xs"
                  >
                    <span className="truncate">
                      {currentRelationValue
                        ? relationComboItems.find((r) => r.value === currentRelationValue)?.label || "관계 선택"
                        : "엔티티 관계 선택"}
                    </span>
                    <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
                  <Command>
                    <CommandInput placeholder="관계 검색..." className="text-xs" />
                    <CommandList>
                      <CommandEmpty className="text-xs">엔티티 관계가 없습니다.</CommandEmpty>
                      <CommandGroup>
                        {relationComboItems.map((item) => (
                          <CommandItem
                            key={item.value}
                            value={`${item.label} ${item.sublabel}`}
                            onSelect={() => {
                              if (item.value === currentRelationValue) {
                                handleChange({ relationColumn: "", parentColumn: "" });
                              } else {
                                const [sourceCol, refPart] = item.value.split("::");
                                const [, refCol] = refPart.split(".");
                                handleChange({ relationColumn: sourceCol, parentColumn: refCol });
                              }
                              setRelationOpen(false);
                            }}
                            className="text-xs"
                          >
                            <Check
                              className={cn("mr-2 h-3 w-3", currentRelationValue === item.value ? "opacity-100" : "opacity-0")}
                            />
                            <div className="flex flex-col">
                              <span>{item.label}</span>
                              <span className="text-[10px] text-muted-foreground/70">{item.sublabel}</span>
                            </div>
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            ) : (
              <div className="rounded-lg border-2 border-dashed py-3 text-center">
                <p className="text-[10px] text-muted-foreground">설정된 엔티티 관계가 없습니다</p>
              </div>
            )}

            {config.relationColumn && config.parentColumn && (
              <div className="rounded bg-muted/50 px-2 py-1.5 text-[10px] text-muted-foreground">
                자식 FK: <span className="font-medium text-foreground">{config.relationColumn}</span>
                {" -> "}
                부모 매칭: <span className="font-medium text-foreground">{config.parentColumn}</span>
              </div>
            )}
          </div>
        </div>
      )}

      {/* 테이블 미선택 안내 */}
      {!config.tableName && (
        <div className="rounded-lg border-2 border-dashed p-6 text-center">
          <Table2 className="mx-auto mb-2 h-8 w-8 text-muted-foreground opacity-30" />
          <p className="text-sm text-muted-foreground">테이블이 선택되지 않았습니다</p>
          <p className="text-xs text-muted-foreground">위 데이터 소스에서 테이블을 선택하세요</p>
        </div>
      )}

      {/* ═══════════════════════════════════════ */}
      {/* 3단계: 카드 크기 (카드 선택 UI)           */}
      {/* ═══════════════════════════════════════ */}
      <div className="space-y-3">
        <SectionHeader icon={Maximize2} title="카드 크기" description="상태 카드의 크기를 선택하세요" />
        <Separator />

        <div className="grid grid-cols-3 gap-2">
          {SIZE_CARDS.map((card) => {
            const isSelected = (config.cardSize || "md") === card.value;
            return (
              <button
                key={card.value}
                type="button"
                onClick={() => updateField("cardSize", card.value)}
                className={cn(
                  "flex min-h-[60px] flex-col items-center justify-center rounded-lg border p-2 text-center transition-all",
                  isSelected
                    ? "border-primary bg-primary/5 ring-1 ring-primary/20"
                    : "border-border hover:border-primary/50 hover:bg-muted/50"
                )}
              >
                <span className="text-xs font-medium leading-tight">{card.title}</span>
                <span className="mt-0.5 text-[10px] leading-tight text-muted-foreground">{card.description}</span>
              </button>
            );
          })}
        </div>
      </div>

      {/* ═══════════════════════════════════════ */}
      {/* 4단계: 상태 항목 관리                     */}
      {/* ═══════════════════════════════════════ */}
      <div className="space-y-3">
        <div className="flex items-center justify-between">
          <SectionHeader icon={BarChart3} title="상태 항목" description="집계할 상태 값과 표시 스타일을 설정하세요" />
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={addItem}
            className="h-6 shrink-0 px-2 text-xs"
          >
            <Plus className="mr-1 h-3 w-3" />
            추가
          </Button>
        </div>
        <Separator />

        {loadingCategoryValues && (
          <div className="flex items-center gap-1 text-xs text-muted-foreground">
            <Loader2 className="h-3 w-3 animate-spin" /> 카테고리 값 로딩...
          </div>
        )}

        {items.length === 0 ? (
          <div className="rounded-lg border-2 border-dashed py-6 text-center">
            <BarChart3 className="mx-auto mb-2 h-8 w-8 text-muted-foreground opacity-30" />
            <p className="text-sm text-muted-foreground">아직 상태 항목이 없어요</p>
            <p className="text-xs text-muted-foreground">위의 추가 버튼으로 항목을 만들어보세요</p>
          </div>
        ) : (
          <div className="space-y-2">
            {items.map((item: StatusCountItem, i: number) => (
              <div key={i} className="space-y-1.5 rounded-md border p-2.5">
                {/* 첫 번째 줄: 상태값 + 삭제 */}
                <div className="flex items-center gap-1">
                  {statusCategoryValues.length > 0 ? (
                    <Select
                      value={item.value || ""}
                      onValueChange={(v) => {
                        updateItem(i, "value", v);
                        if (v === "__ALL__" && !item.label) {
                          updateItem(i, "label", "전체");
                        } else {
                          const catVal = statusCategoryValues.find((cv) => cv.value === v);
                          if (catVal && !item.label) {
                            updateItem(i, "label", catVal.label);
                          }
                        }
                      }}
                    >
                      <SelectTrigger className="h-7 flex-1 text-xs">
                        <SelectValue placeholder="카테고리 값 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="__ALL__" className="text-xs font-medium">
                          전체
                        </SelectItem>
                        {statusCategoryValues.map((cv) => (
                          <SelectItem key={cv.value} value={cv.value} className="text-xs">
                            {cv.label} ({cv.value})
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  ) : (
                    <Input
                      value={item.value}
                      onChange={(e) => updateItem(i, "value", e.target.value)}
                      placeholder="상태값 (예: IN_USE)"
                      className="h-7 text-xs"
                    />
                  )}
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => removeItem(i)}
                    className="h-6 w-6 shrink-0 p-0 text-muted-foreground hover:text-destructive"
                  >
                    <Trash2 className="h-3 w-3" />
                  </Button>
                </div>

                {/* 두 번째 줄: 라벨 + 색상 */}
                <div className="flex gap-1">
                  <Input
                    value={item.label}
                    onChange={(e) => updateItem(i, "label", e.target.value)}
                    placeholder="표시 라벨"
                    className="h-7 text-xs"
                  />
                  <Select
                    value={item.color}
                    onValueChange={(v) => updateItem(i, "color", v)}
                  >
                    <SelectTrigger className="h-7 w-24 shrink-0 text-xs">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {COLOR_OPTIONS.map((c) => (
                        <SelectItem key={c} value={c} className="text-xs">
                          <div className="flex items-center gap-1.5">
                            <div
                              className={cn("h-3 w-3 rounded-full border", STATUS_COLOR_MAP[c].bg, STATUS_COLOR_MAP[c].border)}
                            />
                            {c}
                          </div>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>
            ))}
          </div>
        )}

        {!loadingCategoryValues && statusCategoryValues.length === 0 && config.tableName && config.statusColumn && (
          <div className="rounded bg-amber-50 px-2 py-1.5 text-[10px] text-amber-700 dark:bg-amber-950/30 dark:text-amber-400">
            카테고리 값이 없습니다. 옵션설정 &gt; 카테고리설정에서 값을 추가하거나 직접 입력하세요.
          </div>
        )}

        {/* 미리보기 */}
        {items.length > 0 && (
          <div className="space-y-1.5">
            <span className="text-xs text-muted-foreground">미리보기</span>
            <div className="flex gap-1.5 rounded-md bg-muted/30 p-2">
              {items.map((item, i) => {
                const colors = STATUS_COLOR_MAP[item.color] || STATUS_COLOR_MAP.gray;
                return (
                  <div
                    key={i}
                    className={cn("flex flex-1 flex-col items-center rounded-md border p-1.5", colors.bg, colors.border)}
                  >
                    <span className={cn("text-sm font-bold", colors.text)}>0</span>
                    <span className={cn("text-[10px]", colors.text)}>{item.label || "라벨"}</span>
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

V2StatusCountConfigPanel.displayName = "V2StatusCountConfigPanel";

export default V2StatusCountConfigPanel;
