"use client";

import React, { useState, useCallback, useEffect } from "react";
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 { Plus, Save, Edit2, FolderTree } from "lucide-react";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { NumberingRuleConfig, NumberingRulePart, SEPARATOR_OPTIONS, SeparatorType } from "@/types/numbering-rule";
import { NumberingRuleCard } from "./NumberingRuleCard";
import { NumberingRulePreview } from "./NumberingRulePreview";
import { saveNumberingRuleToTest } from "@/lib/api/numberingRule";
import { apiClient } from "@/lib/api/client";
import { cn } from "@/lib/utils";

interface NumberingColumn {
  tableName: string;
  tableLabel: string;
  columnName: string;
  columnLabel: string;
}

interface GroupedColumns {
  tableLabel: string;
  columns: NumberingColumn[];
}

interface NumberingRuleDesignerProps {
  initialConfig?: NumberingRuleConfig;
  onSave?: (config: NumberingRuleConfig) => void;
  onChange?: (config: NumberingRuleConfig) => void;
  maxRules?: number;
  isPreview?: boolean;
  className?: string;
  currentTableName?: string; // 현재 화면의 테이블명 (자동 감지용)
  menuObjid?: number; // 현재 메뉴 OBJID (메뉴 스코프)
}

export const NumberingRuleDesigner: React.FC<NumberingRuleDesignerProps> = ({
  initialConfig,
  onSave,
  onChange,
  maxRules = 6,
  isPreview = false,
  className = "",
  currentTableName,
  menuObjid,
}) => {
  const [numberingColumns, setNumberingColumns] = useState<NumberingColumn[]>([]);
  const [selectedColumn, setSelectedColumn] = useState<{ tableName: string; columnName: string } | null>(null);
  const [currentRule, setCurrentRule] = useState<NumberingRuleConfig | null>(null);
  const [loading, setLoading] = useState(false);
  const [columnSearch, setColumnSearch] = useState("");
  const [rightTitle, setRightTitle] = useState("규칙 편집");
  const [editingRightTitle, setEditingRightTitle] = useState(false);
  
  // 구분자 관련 상태 (개별 파트 사이 구분자)
  const [separatorTypes, setSeparatorTypes] = useState<Record<number, SeparatorType>>({});
  const [customSeparators, setCustomSeparators] = useState<Record<number, string>>({});

  // 좌측: 채번 타입 컬럼 목록 로드
  useEffect(() => {
    loadNumberingColumns();
  }, []);

  const loadNumberingColumns = async () => {
    setLoading(true);
    try {
      const response = await apiClient.get("/table-management/numbering-columns");
      if (response.data.success && response.data.data) {
        setNumberingColumns(response.data.data);
      }
    } catch (error: any) {
      console.error("채번 컬럼 목록 로드 실패:", error);
    } finally {
      setLoading(false);
    }
  };

  // 컬럼 선택 시 해당 컬럼의 채번 규칙 로드
  const handleSelectColumn = async (tableName: string, columnName: string) => {
    setSelectedColumn({ tableName, columnName });
    setLoading(true);
    try {
      const response = await apiClient.get(`/numbering-rules/by-column/${tableName}/${columnName}`);
      if (response.data.success && response.data.data) {
        const rule = response.data.data as NumberingRuleConfig;
        setCurrentRule(JSON.parse(JSON.stringify(rule)));
      } else {
        // 규칙 없으면 신규 생성 모드
        const newRule: NumberingRuleConfig = {
          ruleId: `rule-${Date.now()}`,
          ruleName: `${columnName} 채번`,
          parts: [],
          separator: "-",
          resetPeriod: "none",
          currentSequence: 1,
          scopeType: "table",
          tableName,
          columnName,
        };
        setCurrentRule(newRule);
      }
    } catch {
      const newRule: NumberingRuleConfig = {
        ruleId: `rule-${Date.now()}`,
        ruleName: `${columnName} 채번`,
        parts: [],
        separator: "-",
        resetPeriod: "none",
        currentSequence: 1,
        scopeType: "table",
        tableName,
        columnName,
      };
      setCurrentRule(newRule);
    } finally {
      setLoading(false);
    }
  };

  // 테이블별로 그룹화
  const groupedColumns = numberingColumns.reduce<Record<string, GroupedColumns>>((acc, col) => {
    if (!acc[col.tableName]) {
      acc[col.tableName] = { tableLabel: col.tableLabel, columns: [] };
    }
    acc[col.tableName].columns.push(col);
    return acc;
  }, {});

  // 검색 필터 적용
  const filteredGroups = Object.entries(groupedColumns).filter(([tableName, group]) => {
    if (!columnSearch) return true;
    const search = columnSearch.toLowerCase();
    return (
      tableName.toLowerCase().includes(search) ||
      group.tableLabel.toLowerCase().includes(search) ||
      group.columns.some(
        (c) => c.columnName.toLowerCase().includes(search) || c.columnLabel.toLowerCase().includes(search)
      )
    );
  });

  useEffect(() => {
    if (currentRule) {
      onChange?.(currentRule);
    }
  }, [currentRule, onChange]);

  // currentRule이 변경될 때 파트별 구분자 상태 동기화
  useEffect(() => {
    if (currentRule && currentRule.parts.length > 0) {
      const newSepTypes: Record<number, SeparatorType> = {};
      const newCustomSeps: Record<number, string> = {};
      
      currentRule.parts.forEach((part) => {
        const sep = part.separatorAfter ?? currentRule.separator ?? "-";
        if (sep === "") {
          newSepTypes[part.order] = "none";
          newCustomSeps[part.order] = "";
        } else {
          const predefinedOption = SEPARATOR_OPTIONS.find(
            opt => opt.value !== "custom" && opt.value !== "none" && opt.displayValue === sep
          );
          if (predefinedOption) {
            newSepTypes[part.order] = predefinedOption.value;
            newCustomSeps[part.order] = "";
          } else {
            newSepTypes[part.order] = "custom";
            newCustomSeps[part.order] = sep;
          }
        }
      });
      
      setSeparatorTypes(newSepTypes);
      setCustomSeparators(newCustomSeps);
    }
  }, [currentRule?.ruleId]);

  // 개별 파트 구분자 변경 핸들러
  const handlePartSeparatorChange = useCallback((partOrder: number, type: SeparatorType) => {
    setSeparatorTypes(prev => ({ ...prev, [partOrder]: type }));
    if (type !== "custom") {
      const option = SEPARATOR_OPTIONS.find(opt => opt.value === type);
      const newSeparator = option?.displayValue ?? "";
      setCustomSeparators(prev => ({ ...prev, [partOrder]: "" }));
      setCurrentRule((prev) => {
        if (!prev) return null;
        return {
          ...prev,
          parts: prev.parts.map((part) =>
            part.order === partOrder ? { ...part, separatorAfter: newSeparator } : part
          ),
        };
      });
    }
  }, []);

  // 개별 파트 직접 입력 구분자 변경 핸들러
  const handlePartCustomSeparatorChange = useCallback((partOrder: number, value: string) => {
    const trimmedValue = value.slice(0, 2);
    setCustomSeparators(prev => ({ ...prev, [partOrder]: trimmedValue }));
    setCurrentRule((prev) => {
      if (!prev) return null;
      return {
        ...prev,
        parts: prev.parts.map((part) =>
          part.order === partOrder ? { ...part, separatorAfter: trimmedValue } : part
        ),
      };
    });
  }, []);

  const handleAddPart = useCallback(() => {
    if (!currentRule) return;

    if (currentRule.parts.length >= maxRules) {
      toast.error(`최대 ${maxRules}개까지 추가할 수 있습니다`);
      return;
    }

    const newPart: NumberingRulePart = {
      id: `part-${Date.now()}`,
      order: currentRule.parts.length + 1,
      partType: "text",
      generationMethod: "auto",
      autoConfig: { textValue: "CODE" },
      separatorAfter: "-",
    };

    setCurrentRule((prev) => {
      if (!prev) return null;
      return { ...prev, parts: [...prev.parts, newPart] };
    });

    // 새 파트의 구분자 상태 초기화
    setSeparatorTypes(prev => ({ ...prev, [newPart.order]: "-" }));
    setCustomSeparators(prev => ({ ...prev, [newPart.order]: "" }));

    toast.success(`규칙 ${newPart.order}가 추가되었습니다`);
  }, [currentRule, maxRules]);

  // partOrder 기반으로 파트 업데이트 (id가 null일 수 있으므로 order 사용)
  const handleUpdatePart = useCallback((partOrder: number, updates: Partial<NumberingRulePart>) => {
    setCurrentRule((prev) => {
      if (!prev) return null;
      return {
        ...prev,
        parts: prev.parts.map((part) => (part.order === partOrder ? { ...part, ...updates } : part)),
      };
    });
  }, []);

  // partOrder 기반으로 파트 삭제 (id가 null일 수 있으므로 order 사용)
  const handleDeletePart = useCallback((partOrder: number) => {
    setCurrentRule((prev) => {
      if (!prev) return null;
      return {
        ...prev,
        parts: prev.parts.filter((part) => part.order !== partOrder).map((part, index) => ({ ...part, order: index + 1 })),
      };
    });

    toast.success("규칙이 삭제되었습니다");
  }, []);

  const handleSave = useCallback(async () => {
    if (!currentRule) {
      toast.error("저장할 규칙이 없습니다");
      return;
    }

    if (currentRule.parts.length === 0) {
      toast.error("최소 1개 이상의 규칙을 추가해주세요");
      return;
    }

    setLoading(true);
    try {
      // 파트별 기본 autoConfig 정의
      const defaultAutoConfigs: Record<string, any> = {
        sequence: { sequenceLength: 3, startFrom: 1 },
        number: { numberLength: 4, numberValue: 1 },
        date: { dateFormat: "YYYYMMDD" },
        text: { textValue: "" },
      };

      // 저장 전에 각 파트의 autoConfig에 기본값 채우기
      const partsWithDefaults = currentRule.parts.map((part) => {
        if (part.generationMethod === "auto") {
          const defaults = defaultAutoConfigs[part.partType] || {};
          return {
            ...part,
            autoConfig: { ...defaults, ...part.autoConfig },
          };
        }
        return part;
      });

      const ruleToSave = {
        ...currentRule,
        parts: partsWithDefaults,
        scopeType: "table" as const,
        tableName: selectedColumn?.tableName || currentRule.tableName || "",
        columnName: selectedColumn?.columnName || currentRule.columnName || "",
      };

      // 테스트 테이블에 저장 (numbering_rules)
      const response = await saveNumberingRuleToTest(ruleToSave);

      if (response.success && response.data) {
        const currentData = JSON.parse(JSON.stringify(response.data)) as NumberingRuleConfig;
        setCurrentRule(currentData);
        await onSave?.(response.data);
        toast.success("채번 규칙이 저장되었습니다");
      } else {
        showErrorToast("채번 규칙 저장에 실패했습니다", response.error, { guidance: "설정을 확인하고 다시 시도해 주세요." });
      }
    } catch (error: any) {
      showErrorToast("채번 규칙 저장에 실패했습니다", error, { guidance: "설정을 확인하고 다시 시도해 주세요." });
    } finally {
      setLoading(false);
    }
  }, [currentRule, onSave, selectedColumn]);

  return (
    <div className={`flex h-full gap-4 ${className}`}>
      {/* 좌측: 채번 컬럼 목록 (카테고리 패턴) */}
      <div className="flex w-72 flex-shrink-0 flex-col gap-3">
        <h2 className="text-sm font-semibold sm:text-base">채번 컬럼</h2>

        <Input
          value={columnSearch}
          onChange={(e) => setColumnSearch(e.target.value)}
          placeholder="검색..."
          className="h-8 text-xs"
        />

        <div className="flex-1 space-y-1 overflow-y-auto">
          {loading && numberingColumns.length === 0 ? (
            <div className="flex h-32 items-center justify-center">
              <p className="text-muted-foreground text-xs">로딩 중...</p>
            </div>
          ) : filteredGroups.length === 0 ? (
            <div className="border-border bg-muted/50 flex h-32 items-center justify-center rounded-lg border border-dashed">
              <p className="text-muted-foreground text-xs">
                {numberingColumns.length === 0
                  ? "채번 타입 컬럼이 없습니다"
                  : "검색 결과가 없습니다"}
              </p>
            </div>
          ) : (
            filteredGroups.map(([tableName, group]) => (
              <div key={tableName} className="mb-2">
                <div className="text-muted-foreground mb-1 flex items-center gap-1 px-1 text-[11px] font-medium">
                  <FolderTree className="h-3 w-3" />
                  <span>{group.tableLabel}</span>
                  <span className="text-muted-foreground/60">({group.columns.length})</span>
                </div>
                {group.columns.map((col) => {
                  const isSelected =
                    selectedColumn?.tableName === col.tableName &&
                    selectedColumn?.columnName === col.columnName;
                  return (
                    <div
                      key={`${col.tableName}.${col.columnName}`}
                      className={cn(
                        "cursor-pointer rounded-md px-3 py-1.5 text-xs transition-colors",
                        isSelected
                          ? "bg-primary/10 text-primary border-primary border font-medium"
                          : "hover:bg-accent"
                      )}
                      onClick={() => handleSelectColumn(col.tableName, col.columnName)}
                    >
                      {col.columnLabel}
                    </div>
                  );
                })}
              </div>
            ))
          )}
        </div>
      </div>

      {/* 구분선 */}
      <div className="bg-border h-full w-px"></div>

      {/* 우측: 편집 영역 */}
      <div className="flex flex-1 flex-col gap-4">
        {!currentRule ? (
          <div className="flex h-full flex-col items-center justify-center">
            <div className="text-center">
              <FolderTree className="text-muted-foreground mx-auto mb-3 h-10 w-10" />
              <p className="text-muted-foreground mb-2 text-lg font-medium">컬럼을 선택해주세요</p>
              <p className="text-muted-foreground text-sm">좌측에서 채번 컬럼을 선택하면 규칙을 편집할 수 있습니다</p>
            </div>
          </div>
        ) : (
          <>
            <div className="flex items-center justify-between">
              {editingRightTitle ? (
                <Input
                  value={rightTitle}
                  onChange={(e) => setRightTitle(e.target.value)}
                  onBlur={() => setEditingRightTitle(false)}
                  onKeyDown={(e) => e.key === "Enter" && setEditingRightTitle(false)}
                  className="h-8 text-sm font-semibold"
                  autoFocus
                />
              ) : (
                <h2 className="text-sm font-semibold sm:text-base">{rightTitle}</h2>
              )}
              <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setEditingRightTitle(true)}>
                <Edit2 className="h-3 w-3" />
              </Button>
            </div>

            <div className="space-y-3">
              {/* 첫 번째 줄: 규칙명 + 미리보기 */}
              <div className="flex items-center gap-3">
                <div className="flex-1 space-y-2">
                  <Label className="text-sm font-medium">규칙명</Label>
                  <Input
                    value={currentRule.ruleName}
                    onChange={(e) => setCurrentRule((prev) => ({ ...prev!, ruleName: e.target.value }))}
                    className="h-9"
                    placeholder="예: 프로젝트 코드"
                  />
                </div>
                <div className="flex-1 space-y-2">
                  <Label className="text-sm font-medium">미리보기</Label>
                  <NumberingRulePreview config={currentRule} />
                </div>
              </div>


            </div>

            <div className="flex-1 overflow-y-auto">
              <div className="mb-3 flex items-center justify-between">
                <h3 className="text-sm font-semibold">코드 구성</h3>
                <span className="text-muted-foreground text-xs">
                  {currentRule.parts.length}/{maxRules}
                </span>
              </div>

              {currentRule.parts.length === 0 ? (
                <div className="border-border bg-muted/50 flex h-32 items-center justify-center rounded-lg border border-dashed">
                  <p className="text-muted-foreground text-xs sm:text-sm">규칙을 추가하여 코드를 구성하세요</p>
                </div>
              ) : (
                <div className="flex flex-wrap items-stretch gap-3">
                  {currentRule.parts.map((part, index) => (
                    <React.Fragment key={`part-${part.order}-${index}`}>
                      <div className="flex w-[200px] flex-col">
                        <NumberingRuleCard
                          part={part}
                          onUpdate={(updates) => handleUpdatePart(part.order, updates)}
                          onDelete={() => handleDeletePart(part.order)}
                          isPreview={isPreview}
                        />
                        {/* 카드 하단에 구분자 설정 (마지막 파트 제외) */}
                        {index < currentRule.parts.length - 1 && (
                          <div className="mt-2 flex items-center gap-1">
                            <span className="text-muted-foreground text-[10px] whitespace-nowrap">뒤 구분자</span>
                            <Select
                              value={separatorTypes[part.order] || "-"}
                              onValueChange={(value) => handlePartSeparatorChange(part.order, value as SeparatorType)}
                            >
                              <SelectTrigger className="h-6 flex-1 text-[10px]">
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                {SEPARATOR_OPTIONS.map((option) => (
                                  <SelectItem key={option.value} value={option.value} className="text-xs">
                                    {option.label}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                            {separatorTypes[part.order] === "custom" && (
                              <Input
                                value={customSeparators[part.order] || ""}
                                onChange={(e) => handlePartCustomSeparatorChange(part.order, e.target.value)}
                                className="h-6 w-14 text-center text-[10px]"
                                placeholder="2자"
                                maxLength={2}
                              />
                            )}
                          </div>
                        )}
                      </div>
                    </React.Fragment>
                  ))}
                </div>
              )}
            </div>

            <div className="flex gap-2">
              <Button
                onClick={handleAddPart}
                disabled={currentRule.parts.length >= maxRules || isPreview || loading}
                variant="outline"
                className="h-9 flex-1 text-sm"
              >
                <Plus className="mr-2 h-4 w-4" />
                규칙 추가
              </Button>
              <Button onClick={handleSave} disabled={isPreview || loading} className="h-9 flex-1 text-sm">
                <Save className="mr-2 h-4 w-4" />
                {loading ? "저장 중..." : "저장"}
              </Button>
            </div>
          </>
        )}
      </div>
    </div>
  );
};
