"use client";

import React, { useEffect, useState } from "react";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
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 { StatusCountConfig, StatusCountItem, STATUS_COLOR_MAP } from "./types";
import { tableTypeApi } from "@/lib/api/screen";
import { entityJoinApi, EntityJoinConfig } from "@/lib/api/entityJoin";
import { Plus, Trash2, Loader2, Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";

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

const COLOR_OPTIONS = Object.keys(STATUS_COLOR_MAP);

interface SearchableComboboxProps {
  value: string;
  onSelect: (value: string) => void;
  items: Array<{ value: string; label: string; sublabel?: string }>;
  placeholder: string;
  searchPlaceholder: string;
  emptyText: string;
  disabled?: boolean;
  loading?: boolean;
}

const SearchableCombobox: React.FC<SearchableComboboxProps> = ({
  value,
  onSelect,
  items,
  placeholder,
  searchPlaceholder,
  emptyText,
  disabled,
  loading,
}) => {
  const [open, setOpen] = useState(false);

  if (loading) {
    return (
      <div className="flex h-8 items-center gap-1 text-xs text-muted-foreground">
        <Loader2 className="h-3 w-3 animate-spin" /> 로딩중...
      </div>
    );
  }

  const selectedItem = items.find((item) => item.value === value);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled}
          className="h-8 w-full justify-between text-xs font-normal"
        >
          <span className="truncate">
            {selectedItem
              ? selectedItem.sublabel
                ? `${selectedItem.label} (${selectedItem.sublabel})`
                : selectedItem.label
              : placeholder}
          </span>
          <ChevronsUpDown className="ml-1 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={searchPlaceholder} className="text-xs" />
          <CommandList>
            <CommandEmpty className="py-3 text-center text-xs">
              {emptyText}
            </CommandEmpty>
            <CommandGroup>
              {items.map((item) => (
                <CommandItem
                  key={item.value}
                  value={`${item.label} ${item.sublabel || ""} ${item.value}`}
                  onSelect={() => {
                    onSelect(item.value === value ? "" : item.value);
                    setOpen(false);
                  }}
                  className="text-xs"
                >
                  <Check
                    className={cn(
                      "mr-2 h-3 w-3",
                      value === item.value ? "opacity-100" : "opacity-0"
                    )}
                  />
                  <div className="flex flex-col">
                    <span>{item.label}</span>
                    {item.sublabel && (
                      <span className="text-[10px] text-muted-foreground">
                        {item.sublabel}
                      </span>
                    )}
                  </div>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
};

export const StatusCountConfigPanel: React.FC<StatusCountConfigPanelProps> = ({
  config,
  onChange,
}) => {
  const items = config.items || [];
  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);

  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]);

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

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

  const addItem = () => {
    handleChange("items", [
      ...items,
      { value: "", label: "새 상태", color: "gray" },
    ]);
  };

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

  // 상태 컬럼의 카테고리 값 로드
  const [statusCategoryValues, setStatusCategoryValues] = useState<Array<{ value: string; label: string }>>([]);
  const [loadingCategoryValues, setLoadingCategoryValues] = useState(false);

  useEffect(() => {
    if (!config.tableName || !config.statusColumn) {
      setStatusCategoryValues([]);
      return;
    }

    const loadCategoryValues = async () => {
      setLoadingCategoryValues(true);
      try {
        const { apiClient } = await import("@/lib/api/client");
        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 = (items: any[]) => {
            for (const item of items) {
              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]);

  const tableComboItems = tables.map((t) => ({
    value: t.tableName,
    label: t.displayName,
    sublabel: t.displayName !== t.tableName ? t.tableName : undefined,
  }));

  const columnComboItems = columns.map((c) => ({
    value: c.columnName,
    label: c.columnLabel,
    sublabel: c.columnLabel !== c.columnName ? c.columnName : undefined,
  }));

  const relationComboItems = 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}`,
    };
  });

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

  return (
    <div className="space-y-4">
      <div className="text-sm font-medium">상태별 카운트 설정</div>

      <div className="space-y-2">
        <Label className="text-xs">제목</Label>
        <Input
          value={config.title || ""}
          onChange={(e) => handleChange("title", e.target.value)}
          placeholder="일련번호 현황"
          className="h-8 text-xs"
        />
      </div>

      <div className="space-y-2">
        <Label className="text-xs">테이블</Label>
        <SearchableCombobox
          value={config.tableName || ""}
          onSelect={(v) => {
            onChange({ tableName: v, statusColumn: "", relationColumn: "", parentColumn: "" });
          }}
          items={tableComboItems}
          placeholder="테이블 선택"
          searchPlaceholder="테이블명 또는 라벨 검색..."
          emptyText="테이블을 찾을 수 없습니다"
          loading={loadingTables}
        />
      </div>

      <div className="space-y-2">
        <Label className="text-xs">상태 컬럼</Label>
        <SearchableCombobox
          value={config.statusColumn || ""}
          onSelect={(v) => handleChange("statusColumn", v)}
          items={columnComboItems}
          placeholder={config.tableName ? "상태 컬럼 선택" : "테이블을 먼저 선택"}
          searchPlaceholder="컬럼명 또는 라벨 검색..."
          emptyText="컬럼을 찾을 수 없습니다"
          disabled={!config.tableName}
          loading={loadingColumns}
        />
      </div>

      <div className="space-y-2">
        <Label className="text-xs">엔티티 관계</Label>
        {loadingJoins ? (
          <div className="flex h-8 items-center gap-1 text-xs text-muted-foreground">
            <Loader2 className="h-3 w-3 animate-spin" /> 로딩중...
          </div>
        ) : entityJoins.length > 0 ? (
          <SearchableCombobox
            value={currentRelationValue}
            onSelect={(v) => {
              if (!v) {
                onChange({ relationColumn: "", parentColumn: "" });
                return;
              }
              const [sourceCol, refPart] = v.split("::");
              const [refTable, refCol] = refPart.split(".");
              onChange({ relationColumn: sourceCol, parentColumn: refCol });
            }}
            items={relationComboItems}
            placeholder="엔티티 관계 선택"
            searchPlaceholder="관계 검색..."
            emptyText="엔티티 관계가 없습니다"
            disabled={!config.tableName}
          />
        ) : (
          <div className="rounded-md border border-dashed p-2">
            <p className="text-center text-[10px] text-muted-foreground">
              {config.tableName ? "설정된 엔티티 관계가 없습니다" : "테이블을 먼저 선택하세요"}
            </p>
          </div>
        )}
        {config.relationColumn && config.parentColumn && (
          <p className="text-[10px] text-muted-foreground">
            자식 FK: <span className="font-medium">{config.relationColumn}</span>
            {" -> "}
            부모 매칭: <span className="font-medium">{config.parentColumn}</span>
          </p>
        )}
      </div>

      <div className="space-y-2">
        <Label className="text-xs">카드 크기</Label>
        <Select
          value={config.cardSize || "md"}
          onValueChange={(v) => handleChange("cardSize", v)}
        >
          <SelectTrigger className="h-8 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="sm" className="text-xs">작게</SelectItem>
            <SelectItem value="md" className="text-xs">보통</SelectItem>
            <SelectItem value="lg" className="text-xs">크게</SelectItem>
          </SelectContent>
        </Select>
      </div>

      <div className="space-y-2">
        <div className="flex items-center justify-between">
          <Label className="text-xs">상태 항목</Label>
          <Button variant="ghost" size="sm" onClick={addItem} className="h-6 px-2 text-xs">
            <Plus className="mr-1 h-3 w-3" />
            추가
          </Button>
        </div>

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

        {items.map((item: StatusCountItem, i: number) => (
          <div key={i} className="space-y-1 rounded-md border p-2">
            <div className="flex items-center gap-1">
              {statusCategoryValues.length > 0 ? (
                <Select
                  value={item.value || ""}
                  onValueChange={(v) => {
                    handleItemChange(i, "value", v);
                    if (v === "__ALL__" && !item.label) {
                      handleItemChange(i, "label", "전체");
                    } else {
                      const catVal = statusCategoryValues.find((cv) => cv.value === v);
                      if (catVal && !item.label) {
                        handleItemChange(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) => handleItemChange(i, "value", e.target.value)}
                  placeholder="상태값 (예: IN_USE)"
                  className="h-7 text-xs"
                />
              )}
              <Button
                variant="ghost"
                size="sm"
                onClick={() => removeItem(i)}
                className="h-7 w-7 shrink-0 p-0"
              >
                <Trash2 className="h-3 w-3 text-destructive" />
              </Button>
            </div>
            <div className="flex gap-1">
              <Input
                value={item.label}
                onChange={(e) => handleItemChange(i, "label", e.target.value)}
                placeholder="표시 라벨"
                className="h-7 text-xs"
              />
              <Select
                value={item.color}
                onValueChange={(v) => handleItemChange(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">
                        <div
                          className={`h-3 w-3 rounded-full ${STATUS_COLOR_MAP[c].bg} border ${STATUS_COLOR_MAP[c].border}`}
                        />
                        {c}
                      </div>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
        ))}

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