"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Checkbox } from "@/components/ui/checkbox";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { ChevronDown, ChevronUp, Plus, Trash2, RefreshCw } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { generateNumberingCode } from "@/lib/api/numberingRule";

import {
  UniversalFormModalComponentProps,
  UniversalFormModalConfig,
  FormSectionConfig,
  FormFieldConfig,
  FormDataState,
  RepeatSectionItem,
  SelectOptionConfig,
} from "./types";
import { defaultConfig, generateUniqueId } from "./config";

/**
 * 범용 폼 모달 컴포넌트
 *
 * 섹션 기반 폼 레이아웃, 채번규칙, 다중 행 저장을 지원합니다.
 */
export function UniversalFormModalComponent({
  component,
  config: propConfig,
  isDesignMode = false,
  isSelected = false,
  className,
  style,
  initialData,
  onSave,
  onCancel,
  onChange,
}: UniversalFormModalComponentProps) {
  // 설정 병합
  const config: UniversalFormModalConfig = useMemo(() => {
    const componentConfig = component?.config || {};
    return {
      ...defaultConfig,
      ...propConfig,
      ...componentConfig,
      modal: {
        ...defaultConfig.modal,
        ...propConfig?.modal,
        ...componentConfig.modal,
      },
      saveConfig: {
        ...defaultConfig.saveConfig,
        ...propConfig?.saveConfig,
        ...componentConfig.saveConfig,
        multiRowSave: {
          ...defaultConfig.saveConfig.multiRowSave,
          ...propConfig?.saveConfig?.multiRowSave,
          ...componentConfig.saveConfig?.multiRowSave,
        },
        afterSave: {
          ...defaultConfig.saveConfig.afterSave,
          ...propConfig?.saveConfig?.afterSave,
          ...componentConfig.saveConfig?.afterSave,
        },
      },
    };
  }, [component?.config, propConfig]);

  // 폼 데이터 상태
  const [formData, setFormData] = useState<FormDataState>({});
  const [, setOriginalData] = useState<Record<string, any>>({});

  // 반복 섹션 데이터
  const [repeatSections, setRepeatSections] = useState<{
    [sectionId: string]: RepeatSectionItem[];
  }>({});

  // 섹션 접힘 상태
  const [collapsedSections, setCollapsedSections] = useState<Set<string>>(new Set());

  // Select 옵션 캐시
  const [selectOptionsCache, setSelectOptionsCache] = useState<{
    [key: string]: { value: string; label: string }[];
  }>({});

  // 로딩 상태
  const [saving, setSaving] = useState(false);

  // 삭제 확인 다이얼로그
  const [deleteDialog, setDeleteDialog] = useState<{
    open: boolean;
    sectionId: string;
    itemId: string;
  }>({ open: false, sectionId: "", itemId: "" });

  // 초기화
  useEffect(() => {
    initializeForm();
  }, [config, initialData]);

  // 폼 초기화
  const initializeForm = useCallback(async () => {
    const newFormData: FormDataState = {};
    const newRepeatSections: { [sectionId: string]: RepeatSectionItem[] } = {};
    const newCollapsed = new Set<string>();

    // 섹션별 초기화
    for (const section of config.sections) {
      // 접힘 상태 초기화
      if (section.defaultCollapsed) {
        newCollapsed.add(section.id);
      }

      if (section.repeatable) {
        // 반복 섹션 초기화
        const minItems = section.repeatConfig?.minItems || 0;
        const items: RepeatSectionItem[] = [];
        for (let i = 0; i < minItems; i++) {
          items.push(createRepeatItem(section, i));
        }
        newRepeatSections[section.id] = items;
      } else {
        // 일반 섹션 필드 초기화
        for (const field of section.fields) {
          // 기본값 설정
          let value = field.defaultValue ?? "";

          // 부모에서 전달받은 값 적용
          if (field.receiveFromParent && initialData) {
            const parentField = field.parentFieldName || field.columnName;
            if (initialData[parentField] !== undefined) {
              value = initialData[parentField];
            }
          }

          newFormData[field.columnName] = value;
        }
      }
    }

    setFormData(newFormData);
    setRepeatSections(newRepeatSections);
    setCollapsedSections(newCollapsed);
    setOriginalData(initialData || {});

    // 채번규칙 자동 생성
    await generateNumberingValues(newFormData);
  }, [config, initialData]);

  // 반복 섹션 아이템 생성
  const createRepeatItem = (section: FormSectionConfig, index: number): RepeatSectionItem => {
    const item: RepeatSectionItem = {
      _id: generateUniqueId("repeat"),
      _index: index,
    };

    for (const field of section.fields) {
      item[field.columnName] = field.defaultValue ?? "";
    }

    return item;
  };

  // 채번규칙 자동 생성
  const generateNumberingValues = useCallback(
    async (currentFormData: FormDataState) => {
      const updatedData = { ...currentFormData };
      let hasChanges = false;

      for (const section of config.sections) {
        if (section.repeatable) continue;

        for (const field of section.fields) {
          if (
            field.numberingRule?.enabled &&
            field.numberingRule?.generateOnOpen &&
            field.numberingRule?.ruleId &&
            !updatedData[field.columnName]
          ) {
            try {
              const response = await generateNumberingCode(field.numberingRule.ruleId);
              if (response.success && response.data?.generatedCode) {
                updatedData[field.columnName] = response.data.generatedCode;
                hasChanges = true;
              }
            } catch (error) {
              console.error(`채번규칙 생성 실패 (${field.columnName}):`, error);
            }
          }
        }
      }

      if (hasChanges) {
        setFormData(updatedData);
      }
    },
    [config],
  );

  // 필드 값 변경 핸들러
  const handleFieldChange = useCallback(
    (columnName: string, value: any) => {
      setFormData((prev) => {
        const newData = { ...prev, [columnName]: value };
        // onChange는 렌더링 외부에서 호출해야 함 (setTimeout 사용)
        if (onChange) {
          setTimeout(() => onChange(newData), 0);
        }
        return newData;
      });
    },
    [onChange],
  );

  // 반복 섹션 필드 값 변경 핸들러
  const handleRepeatFieldChange = useCallback((sectionId: string, itemId: string, columnName: string, value: any) => {
    setRepeatSections((prev) => {
      const items = prev[sectionId] || [];
      const newItems = items.map((item) => (item._id === itemId ? { ...item, [columnName]: value } : item));
      return { ...prev, [sectionId]: newItems };
    });
  }, []);

  // 반복 섹션 아이템 추가
  const handleAddRepeatItem = useCallback(
    (sectionId: string) => {
      const section = config.sections.find((s) => s.id === sectionId);
      if (!section) return;

      const maxItems = section.repeatConfig?.maxItems || 10;

      setRepeatSections((prev) => {
        const items = prev[sectionId] || [];
        if (items.length >= maxItems) {
          toast.error(`최대 ${maxItems}개까지만 추가할 수 있습니다.`);
          return prev;
        }

        const newItem = createRepeatItem(section, items.length);
        return { ...prev, [sectionId]: [...items, newItem] };
      });
    },
    [config],
  );

  // 반복 섹션 아이템 삭제
  const handleRemoveRepeatItem = useCallback(
    (sectionId: string, itemId: string) => {
      const section = config.sections.find((s) => s.id === sectionId);
      if (!section) return;

      const minItems = section.repeatConfig?.minItems || 0;

      setRepeatSections((prev) => {
        const items = prev[sectionId] || [];
        if (items.length <= minItems) {
          toast.error(`최소 ${minItems}개는 유지해야 합니다.`);
          return prev;
        }

        const newItems = items.filter((item) => item._id !== itemId).map((item, index) => ({ ...item, _index: index }));

        return { ...prev, [sectionId]: newItems };
      });

      setDeleteDialog({ open: false, sectionId: "", itemId: "" });
    },
    [config],
  );

  // 섹션 접힘 토글
  const toggleSectionCollapse = useCallback((sectionId: string) => {
    setCollapsedSections((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(sectionId)) {
        newSet.delete(sectionId);
      } else {
        newSet.add(sectionId);
      }
      return newSet;
    });
  }, []);

  // Select 옵션 로드
  const loadSelectOptions = useCallback(
    async (fieldId: string, optionConfig: SelectOptionConfig): Promise<{ value: string; label: string }[]> => {
      // 캐시 확인
      if (selectOptionsCache[fieldId]) {
        return selectOptionsCache[fieldId];
      }

      let options: { value: string; label: string }[] = [];

      try {
        if (optionConfig.type === "static") {
          options = optionConfig.staticOptions || [];
        } else if (optionConfig.type === "table" && optionConfig.tableName) {
          const response = await apiClient.get(`/table-management/tables/${optionConfig.tableName}/data`, {
            params: { limit: 1000 },
          });
          if (response.data?.success && response.data?.data) {
            options = response.data.data.map((row: any) => ({
              value: String(row[optionConfig.valueColumn || "id"]),
              label: String(row[optionConfig.labelColumn || "name"]),
            }));
          }
        } else if (optionConfig.type === "code" && optionConfig.codeCategory) {
          const response = await apiClient.get(`/common-code/${optionConfig.codeCategory}`);
          if (response.data?.success && response.data?.data) {
            options = response.data.data.map((code: any) => ({
              value: code.code_value || code.codeValue,
              label: code.code_name || code.codeName,
            }));
          }
        }

        // 캐시 저장
        setSelectOptionsCache((prev) => ({ ...prev, [fieldId]: options }));
      } catch (error) {
        console.error(`Select 옵션 로드 실패 (${fieldId}):`, error);
      }

      return options;
    },
    [selectOptionsCache],
  );

  // 필수 필드 검증
  const validateRequiredFields = useCallback((): { valid: boolean; missingFields: string[] } => {
    const missingFields: string[] = [];

    for (const section of config.sections) {
      if (section.repeatable) continue; // 반복 섹션은 별도 검증

      for (const field of section.fields) {
        if (field.required && !field.hidden && !field.numberingRule?.hidden) {
          const value = formData[field.columnName];
          if (value === undefined || value === null || value === "") {
            missingFields.push(field.label || field.columnName);
          }
        }
      }
    }

    return { valid: missingFields.length === 0, missingFields };
  }, [config.sections, formData]);

  // 저장 처리
  const handleSave = useCallback(async () => {
    if (!config.saveConfig.tableName) {
      toast.error("저장할 테이블이 설정되지 않았습니다.");
      return;
    }

    // 필수 필드 검증
    const { valid, missingFields } = validateRequiredFields();
    if (!valid) {
      toast.error(`필수 항목을 입력해주세요: ${missingFields.join(", ")}`);
      return;
    }

    setSaving(true);

    try {
      const { multiRowSave } = config.saveConfig;

      if (multiRowSave?.enabled) {
        // 다중 행 저장
        await saveMultipleRows();
      } else {
        // 단일 행 저장
        await saveSingleRow();
      }

      // 저장 후 동작
      if (config.saveConfig.afterSave?.showToast) {
        toast.success("저장되었습니다.");
      }

      if (config.saveConfig.afterSave?.refreshParent) {
        window.dispatchEvent(new CustomEvent("refreshParentData"));
      }

      // onSave 콜백은 저장 완료 알림용으로만 사용
      // 실제 저장은 이미 위에서 완료됨 (saveSingleRow 또는 saveMultipleRows)
      // EditModal 등 부모 컴포넌트의 저장 로직이 다시 실행되지 않도록
      // _saveCompleted 플래그를 포함하여 전달
      if (onSave) {
        onSave({ ...formData, _saveCompleted: true });
      }
    } catch (error: any) {
      console.error("저장 실패:", error);
      toast.error(error.message || "저장에 실패했습니다.");
    } finally {
      setSaving(false);
    }
  }, [config, formData, repeatSections, onSave, validateRequiredFields]);

  // 단일 행 저장
  const saveSingleRow = async () => {
    const dataToSave = { ...formData };

    // 메타데이터 필드 제거
    Object.keys(dataToSave).forEach((key) => {
      if (key.startsWith("_")) {
        delete dataToSave[key];
      }
    });

    // 저장 시점 채번규칙 처리
    for (const section of config.sections) {
      for (const field of section.fields) {
        if (
          field.numberingRule?.enabled &&
          field.numberingRule?.generateOnSave &&
          field.numberingRule?.ruleId &&
          !dataToSave[field.columnName]
        ) {
          const response = await generateNumberingCode(field.numberingRule.ruleId);
          if (response.success && response.data?.generatedCode) {
            dataToSave[field.columnName] = response.data.generatedCode;
          }
        }
      }
    }

    const response = await apiClient.post(`/table-management/tables/${config.saveConfig.tableName}/add`, dataToSave);

    if (!response.data?.success) {
      throw new Error(response.data?.message || "저장 실패");
    }
  };

  // 다중 행 저장 (겸직 등)
  const saveMultipleRows = async () => {
    const { multiRowSave } = config.saveConfig;
    if (!multiRowSave) return;

    let { commonFields = [], repeatSectionId = "", typeColumn, mainTypeValue, subTypeValue, mainSectionFields = [] } =
      multiRowSave;

    // 공통 필드가 설정되지 않은 경우, 기본정보 섹션의 모든 필드를 공통 필드로 사용
    if (commonFields.length === 0) {
      const nonRepeatableSections = config.sections.filter((s) => !s.repeatable);
      commonFields = nonRepeatableSections.flatMap((s) => s.fields.map((f) => f.columnName));
      console.log("[UniversalFormModal] 공통 필드 자동 설정:", commonFields);
    }

    // 반복 섹션 ID가 설정되지 않은 경우, 첫 번째 반복 섹션 사용
    if (!repeatSectionId) {
      const repeatableSection = config.sections.find((s) => s.repeatable);
      if (repeatableSection) {
        repeatSectionId = repeatableSection.id;
        console.log("[UniversalFormModal] 반복 섹션 자동 설정:", repeatSectionId);
      }
    }

    // 디버깅: 설정 확인
    console.log("[UniversalFormModal] 다중 행 저장 설정:", {
      commonFields,
      mainSectionFields,
      repeatSectionId,
      typeColumn,
      mainTypeValue,
      subTypeValue,
    });
    console.log("[UniversalFormModal] 현재 formData:", formData);

    // 공통 필드 데이터 추출
    const commonData: Record<string, any> = {};
    for (const fieldName of commonFields) {
      if (formData[fieldName] !== undefined) {
        commonData[fieldName] = formData[fieldName];
      }
    }
    console.log("[UniversalFormModal] 추출된 공통 데이터:", commonData);

    // 메인 섹션 필드 데이터 추출
    const mainSectionData: Record<string, any> = {};
    if (mainSectionFields && mainSectionFields.length > 0) {
      for (const fieldName of mainSectionFields) {
        if (formData[fieldName] !== undefined) {
          mainSectionData[fieldName] = formData[fieldName];
        }
      }
    }
    console.log("[UniversalFormModal] 추출된 메인 섹션 데이터:", mainSectionData);

    // 저장할 행들 준비
    const rowsToSave: Record<string, any>[] = [];

    // 1. 메인 행 생성
    const mainRow: Record<string, any> = {
      ...commonData,
      ...mainSectionData,
    };
    if (typeColumn) {
      mainRow[typeColumn] = mainTypeValue || "main";
    }
    rowsToSave.push(mainRow);

    // 2. 반복 섹션 행들 생성 (겸직 등)
    const repeatItems = repeatSections[repeatSectionId] || [];
    for (const item of repeatItems) {
      const subRow: Record<string, any> = { ...commonData };

      // 반복 섹션 필드 복사
      Object.keys(item).forEach((key) => {
        if (!key.startsWith("_")) {
          subRow[key] = item[key];
        }
      });

      if (typeColumn) {
        subRow[typeColumn] = subTypeValue || "concurrent";
      }

      rowsToSave.push(subRow);
    }

    // 저장 시점 채번규칙 처리 (메인 행만)
    for (const section of config.sections) {
      if (section.repeatable) continue;

      for (const field of section.fields) {
        if (field.numberingRule?.enabled && field.numberingRule?.generateOnSave && field.numberingRule?.ruleId) {
          const response = await generateNumberingCode(field.numberingRule.ruleId);
          if (response.success && response.data?.generatedCode) {
            // 모든 행에 동일한 채번 값 적용 (공통 필드인 경우)
            if (commonFields.includes(field.columnName)) {
              rowsToSave.forEach((row) => {
                row[field.columnName] = response.data?.generatedCode;
              });
            } else {
              rowsToSave[0][field.columnName] = response.data?.generatedCode;
            }
          }
        }
      }
    }

    // 모든 행 저장
    console.log("[UniversalFormModal] 저장할 행들:", rowsToSave);
    console.log("[UniversalFormModal] 저장 테이블:", config.saveConfig.tableName);

    for (let i = 0; i < rowsToSave.length; i++) {
      const row = rowsToSave[i];
      console.log(`[UniversalFormModal] ${i + 1}번째 행 저장 시도:`, row);

      // 빈 객체 체크
      if (Object.keys(row).length === 0) {
        console.warn(`[UniversalFormModal] ${i + 1}번째 행이 비어있습니다. 건너뜁니다.`);
        continue;
      }

      const response = await apiClient.post(`/table-management/tables/${config.saveConfig.tableName}/add`, row);

      if (!response.data?.success) {
        throw new Error(response.data?.message || `${i + 1}번째 행 저장 실패`);
      }
    }

    console.log(`[UniversalFormModal] ${rowsToSave.length}개 행 저장 완료`);
  };

  // 폼 초기화
  const handleReset = useCallback(() => {
    initializeForm();
    toast.info("폼이 초기화되었습니다.");
  }, [initializeForm]);

  // 필드 요소 렌더링 (입력 컴포넌트만)
  const renderFieldElement = (
    field: FormFieldConfig,
    value: any,
    onChangeHandler: (value: any) => void,
    fieldKey: string,
    isDisabled: boolean,
  ) => {
    return (() => {
      switch (field.fieldType) {
        case "textarea":
          return (
            <Textarea
              id={fieldKey}
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              placeholder={field.placeholder}
              disabled={isDisabled}
              readOnly={field.readOnly}
              className="min-h-[80px]"
            />
          );

        case "checkbox":
          return (
            <div className="flex items-center space-x-2 pt-2">
              <Checkbox
                id={fieldKey}
                checked={!!value}
                onCheckedChange={(checked) => onChangeHandler(checked)}
                disabled={isDisabled}
              />
              <Label htmlFor={fieldKey} className="text-sm font-normal">
                {field.placeholder || field.label}
              </Label>
            </div>
          );

        case "select":
          return (
            <SelectField
              fieldId={fieldKey}
              value={value}
              onChange={onChangeHandler}
              optionConfig={field.selectOptions}
              placeholder={field.placeholder || "선택하세요"}
              disabled={isDisabled}
              loadOptions={loadSelectOptions}
            />
          );

        case "date":
          return (
            <Input
              id={fieldKey}
              type="date"
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );

        case "datetime":
          return (
            <Input
              id={fieldKey}
              type="datetime-local"
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );

        case "number":
          return (
            <Input
              id={fieldKey}
              type="number"
              value={value ?? ""}
              onChange={(e) => onChangeHandler(e.target.value ? Number(e.target.value) : "")}
              placeholder={field.placeholder}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );

        case "password":
          return (
            <Input
              id={fieldKey}
              type="password"
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              placeholder={field.placeholder}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );

        case "email":
          return (
            <Input
              id={fieldKey}
              type="email"
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              placeholder={field.placeholder}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );

        case "tel":
          return (
            <Input
              id={fieldKey}
              type="tel"
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              placeholder={field.placeholder}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );

        default:
          return (
            <Input
              id={fieldKey}
              type="text"
              value={value || ""}
              onChange={(e) => onChangeHandler(e.target.value)}
              placeholder={field.placeholder}
              disabled={isDisabled}
              readOnly={field.readOnly}
            />
          );
      }
    })();
  };

  // 섹션의 열 수에 따른 기본 gridSpan 계산
  const getDefaultGridSpan = (sectionColumns: number = 2): number => {
    // 12칸 그리드 기준: 1열=12, 2열=6, 3열=4, 4열=3
    return Math.floor(12 / sectionColumns);
  };

  // 필드 렌더링 (섹션 열 수 적용)
  const renderFieldWithColumns = (
    field: FormFieldConfig,
    value: any,
    onChangeHandler: (value: any) => void,
    fieldKey: string,
    sectionColumns: number = 2,
  ) => {
    // 섹션 열 수에 따른 기본 gridSpan 계산 (섹션 열 수가 우선)
    const defaultSpan = getDefaultGridSpan(sectionColumns);
    // 섹션이 1열이면 무조건 12(전체 너비), 그 외에는 필드 설정 또는 기본값 사용
    const actualGridSpan = sectionColumns === 1 ? 12 : field.gridSpan || defaultSpan;

    const isDisabled = !!(field.disabled || (field.numberingRule?.enabled && !field.numberingRule?.editable));
    const isHidden = field.hidden || field.numberingRule?.hidden;

    if (isHidden) {
      return null;
    }

    const fieldElement = renderFieldElement(field, value, onChangeHandler, fieldKey, isDisabled);

    if (field.fieldType === "checkbox") {
      return (
        <div key={fieldKey} className="space-y-1" style={{ gridColumn: `span ${actualGridSpan}` }}>
          {fieldElement}
        </div>
      );
    }

    return (
      <div key={fieldKey} className="space-y-1" style={{ gridColumn: `span ${actualGridSpan}` }}>
        <Label htmlFor={fieldKey} className="text-sm font-medium">
          {field.label}
          {field.required && <span className="text-destructive ml-1">*</span>}
          {field.numberingRule?.enabled && <span className="text-muted-foreground ml-1 text-xs">(자동생성)</span>}
        </Label>
        {fieldElement}
      </div>
    );
  };

  // 섹션 렌더링
  const renderSection = (section: FormSectionConfig) => {
    const isCollapsed = collapsedSections.has(section.id);
    const sectionColumns = section.columns || 2;

    if (section.repeatable) {
      return renderRepeatableSection(section, isCollapsed);
    }

    return (
      <Card key={section.id} className="mb-4">
        {section.collapsible ? (
          <Collapsible open={!isCollapsed} onOpenChange={() => toggleSectionCollapse(section.id)}>
            <CollapsibleTrigger asChild>
              <CardHeader className="hover:bg-muted/50 cursor-pointer transition-colors">
                <div className="flex items-center justify-between">
                  <div>
                    <CardTitle className="text-base">{section.title}</CardTitle>
                    {section.description && (
                      <CardDescription className="mt-1 text-xs">{section.description}</CardDescription>
                    )}
                  </div>
                  {isCollapsed ? <ChevronDown className="h-4 w-4" /> : <ChevronUp className="h-4 w-4" />}
                </div>
              </CardHeader>
            </CollapsibleTrigger>
            <CollapsibleContent>
              <CardContent>
                <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(12, 1fr)` }}>
                  {section.fields.map((field) =>
                    renderFieldWithColumns(
                      field,
                      formData[field.columnName],
                      (value) => handleFieldChange(field.columnName, value),
                      `${section.id}-${field.id}`,
                      sectionColumns,
                    ),
                  )}
                </div>
              </CardContent>
            </CollapsibleContent>
          </Collapsible>
        ) : (
          <>
            <CardHeader className="pb-3">
              <CardTitle className="text-base">{section.title}</CardTitle>
              {section.description && <CardDescription className="text-xs">{section.description}</CardDescription>}
            </CardHeader>
            <CardContent>
              <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(12, 1fr)` }}>
                {section.fields.map((field) =>
                  renderFieldWithColumns(
                    field,
                    formData[field.columnName],
                    (value) => handleFieldChange(field.columnName, value),
                    `${section.id}-${field.id}`,
                    sectionColumns,
                  ),
                )}
              </div>
            </CardContent>
          </>
        )}
      </Card>
    );
  };

  // 반복 섹션 렌더링
  const renderRepeatableSection = (section: FormSectionConfig, isCollapsed: boolean) => {
    const items = repeatSections[section.id] || [];
    const maxItems = section.repeatConfig?.maxItems || 10;
    const canAdd = items.length < maxItems;
    const sectionColumns = section.columns || 2;

    const content = (
      <>
        {items.length === 0 ? (
          <div className="text-muted-foreground py-8 text-center">
            <p className="text-sm">등록된 항목이 없습니다.</p>
            <Button variant="outline" size="sm" className="mt-2" onClick={() => handleAddRepeatItem(section.id)}>
              <Plus className="mr-1 h-4 w-4" />
              {section.repeatConfig?.addButtonText || "+ 추가"}
            </Button>
          </div>
        ) : (
          <div className="space-y-4">
            {items.map((item, index) => (
              <div key={item._id} className="bg-muted/30 relative rounded-lg border p-4">
                <div className="mb-3 flex items-center justify-between">
                  <span className="text-muted-foreground text-sm font-medium">
                    {(section.repeatConfig?.itemTitle || "항목 {index}").replace("{index}", String(index + 1))}
                  </span>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="text-destructive hover:text-destructive h-8 w-8 p-0"
                    onClick={() => {
                      if (section.repeatConfig?.confirmRemove) {
                        setDeleteDialog({ open: true, sectionId: section.id, itemId: item._id });
                      } else {
                        handleRemoveRepeatItem(section.id, item._id);
                      }
                    }}
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </div>
                <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(12, 1fr)` }}>
                  {section.fields.map((field) =>
                    renderFieldWithColumns(
                      field,
                      item[field.columnName],
                      (value) => handleRepeatFieldChange(section.id, item._id, field.columnName, value),
                      `${section.id}-${item._id}-${field.id}`,
                      sectionColumns,
                    ),
                  )}
                </div>
              </div>
            ))}

            {canAdd && (
              <Button variant="outline" size="sm" className="w-full" onClick={() => handleAddRepeatItem(section.id)}>
                <Plus className="mr-1 h-4 w-4" />
                {section.repeatConfig?.addButtonText || "+ 추가"}
              </Button>
            )}
          </div>
        )}
      </>
    );

    return (
      <Card key={section.id} className="mb-4">
        {section.collapsible ? (
          <Collapsible open={!isCollapsed} onOpenChange={() => toggleSectionCollapse(section.id)}>
            <CollapsibleTrigger asChild>
              <CardHeader className="hover:bg-muted/50 cursor-pointer transition-colors">
                <div className="flex items-center justify-between">
                  <div>
                    <CardTitle className="text-base">
                      {section.title}
                      <span className="text-muted-foreground ml-2 text-sm font-normal">({items.length}개)</span>
                    </CardTitle>
                    {section.description && (
                      <CardDescription className="mt-1 text-xs">{section.description}</CardDescription>
                    )}
                  </div>
                  {isCollapsed ? <ChevronDown className="h-4 w-4" /> : <ChevronUp className="h-4 w-4" />}
                </div>
              </CardHeader>
            </CollapsibleTrigger>
            <CollapsibleContent>
              <CardContent>{content}</CardContent>
            </CollapsibleContent>
          </Collapsible>
        ) : (
          <>
            <CardHeader className="pb-3">
              <CardTitle className="text-base">
                {section.title}
                <span className="text-muted-foreground ml-2 text-sm font-normal">({items.length}개)</span>
              </CardTitle>
              {section.description && <CardDescription className="text-xs">{section.description}</CardDescription>}
            </CardHeader>
            <CardContent>{content}</CardContent>
          </>
        )}
      </Card>
    );
  };

  // 디자인 모드 렌더링
  if (isDesignMode) {
    return (
      <div
        className={cn(
          "min-h-[200px] rounded-lg border-2 border-dashed p-4",
          isSelected ? "border-primary bg-primary/5" : "border-muted",
          className,
        )}
        style={style}
      >
        <div className="text-muted-foreground text-center">
          <p className="font-medium">{config.modal.title || "범용 폼 모달"}</p>
          <p className="mt-1 text-xs">
            {config.sections.length}개 섹션 |{config.sections.reduce((acc, s) => acc + s.fields.length, 0)}개 필드
          </p>
          <p className="mt-1 text-xs">저장 테이블: {config.saveConfig.tableName || "(미설정)"}</p>
        </div>
      </div>
    );
  }

  return (
    <div className={cn("w-full", className)} style={style}>
      {/* 섹션들 */}
      <div className="space-y-4">{config.sections.map((section) => renderSection(section))}</div>

      {/* 버튼 영역 */}
      <div className="mt-6 flex justify-end gap-2 border-t pt-4">
        {config.modal.showResetButton && (
          <Button
            type="button"
            variant="outline"
            onClick={(e) => {
              e.preventDefault();
              e.stopPropagation();
              handleReset();
            }}
            disabled={saving}
          >
            <RefreshCw className="mr-1 h-4 w-4" />
            {config.modal.resetButtonText || "초기화"}
          </Button>
        )}
        <Button
          type="button"
          variant="outline"
          onClick={(e) => {
            e.preventDefault();
            e.stopPropagation();
            onCancel?.();
          }}
          disabled={saving}
        >
          {config.modal.cancelButtonText || "취소"}
        </Button>
        <Button
          type="button"
          onClick={(e) => {
            e.preventDefault();
            e.stopPropagation();
            handleSave();
          }}
          disabled={saving || !config.saveConfig.tableName}
        >
          {saving ? "저장 중..." : config.modal.saveButtonText || "저장"}
        </Button>
      </div>

      {/* 삭제 확인 다이얼로그 */}
      <AlertDialog
        open={deleteDialog.open}
        onOpenChange={(open) => !open && setDeleteDialog({ open: false, sectionId: "", itemId: "" })}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>항목 삭제</AlertDialogTitle>
            <AlertDialogDescription>이 항목을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.</AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>취소</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => handleRemoveRepeatItem(deleteDialog.sectionId, deleteDialog.itemId)}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              삭제
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}

// Select 필드 컴포넌트 (옵션 로딩 포함)
interface SelectFieldProps {
  fieldId: string;
  value: any;
  onChange: (value: any) => void;
  optionConfig?: SelectOptionConfig;
  placeholder?: string;
  disabled?: boolean;
  loadOptions: (fieldId: string, config: SelectOptionConfig) => Promise<{ value: string; label: string }[]>;
}

function SelectField({ fieldId, value, onChange, optionConfig, placeholder, disabled, loadOptions }: SelectFieldProps) {
  const [options, setOptions] = useState<{ value: string; label: string }[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (optionConfig) {
      setLoading(true);
      loadOptions(fieldId, optionConfig)
        .then(setOptions)
        .finally(() => setLoading(false));
    }
  }, [fieldId, optionConfig, loadOptions]);

  return (
    <Select value={value || ""} onValueChange={onChange} disabled={disabled || loading}>
      <SelectTrigger>
        <SelectValue placeholder={loading ? "로딩 중..." : placeholder} />
      </SelectTrigger>
      <SelectContent>
        {options.map((option) => (
          <SelectItem key={option.value} value={option.value}>
            {option.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

export default UniversalFormModalComponent;
