'use client';

import { useMemo, useEffect, useState, useCallback } from 'react';
import { FieldRenderer } from './fields/FieldRenderer';
import type { FieldConfig, FormConfig } from '@/types/invyone-component';

const DEFAULT_CONFIG: FormConfig = {
  columns: 2,
  saveAction: {
    method: 'UPSERT',
    refreshAfterSave: true,
  },
};

interface FcFormProps {
  fields: FieldConfig[];
  config?: Partial<FormConfig>;
  initialData?: Record<string, any>;
  onSubmit?: (data: Record<string, any>) => void;
  onSaved?: (data: Record<string, any>) => void;
  loadRow?: Record<string, any>;
}

/** required 검증: null, undefined, '' 만 empty. 0, false는 유효. */
function isFieldEmpty(value: any): boolean {
  return value === null || value === undefined || value === '';
}

export function FcForm({
  fields,
  config: configOverride,
  initialData,
  onSubmit,
  loadRow,
}: FcFormProps) {
  const config = useMemo(() => ({ ...DEFAULT_CONFIG, ...configOverride }), [configOverride]);

  // 표시할 필드: system이 아니고 visible인 것, order 순
  const formFields = useMemo(
    () => fields
      .filter((f) => !f.system && f.visible)
      .sort((a, b) => a.order - b.order),
    [fields],
  );

  // 폼 데이터 상태
  const [formData, setFormData] = useState<Record<string, any>>({});
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [isModified, setIsModified] = useState(false);

  // initialData 또는 loadRow가 변경되면 폼 데이터 갱신
  useEffect(() => {
    const source = loadRow ?? initialData ?? {};
    setFormData({ ...source });
    setErrors({});
    setIsModified(false);
  }, [loadRow, initialData]);

  // 필드 값 변경
  const handleChange = useCallback((column: string, value: any) => {
    setFormData((prev) => ({ ...prev, [column]: value }));
    setErrors((prev) => {
      const next = { ...prev };
      delete next[column];
      return next;
    });
    setIsModified(true);
  }, []);

  // 제출
  const handleSubmit = useCallback((e: React.FormEvent) => {
    e.preventDefault();

    // required 검증
    const newErrors: Record<string, string> = {};
    for (const field of formFields) {
      if (field.required && isFieldEmpty(formData[field.column])) {
        newErrors[field.column] = `${field.label}은(는) 필수입니다`;
      }
    }

    if (Object.keys(newErrors).length > 0) {
      setErrors(newErrors);
      return;
    }

    onSubmit?.(formData);
  }, [formData, formFields, onSubmit]);

  // 초기화
  const handleReset = useCallback(() => {
    const source = loadRow ?? initialData ?? {};
    setFormData({ ...source });
    setErrors({});
    setIsModified(false);
  }, [loadRow, initialData]);

  const gridCols = config.columns === 3 ? 'grid-cols-3' : config.columns === 1 ? 'grid-cols-1' : 'grid-cols-2';

  // 섹션이 있으면 섹션별로 그룹핑
  const sections = config.sections;

  const renderField = (field: FieldConfig) => {
    const isDisabled = !field.editable || (field.pk && field.type === 'code');
    return (
      <div key={field.column} className="space-y-0.5">
        <label className="flex items-center gap-0.5 text-xs font-medium text-[var(--v5-text-sec)]">
          {field.label}
          {field.required && <span className="text-[var(--v5-red)]">*</span>}
        </label>
        <FieldRenderer
          field={field}
          value={formData[field.column]}
          onChange={(v) => handleChange(field.column, v)}
          mode="form"
          disabled={isDisabled}
          error={errors[field.column]}
        />
        {errors[field.column] && (
          <p className="text-[0.65rem] text-[var(--v5-red)]">{errors[field.column]}</p>
        )}
      </div>
    );
  };

  return (
    <form
      onSubmit={handleSubmit}
      className="fc-form rounded-md border border-[var(--v5-glass-border)] p-3
        bg-[var(--v5-glass)] backdrop-blur-[20px]"
    >
      {sections && sections.length > 0 ? (
        // 섹션별 렌더링
        sections.map((section) => {
          const sectionFields = formFields.filter((f) => section.fields.includes(f.column));
          if (sectionFields.length === 0) return null;
          return (
            <div key={section.label} className="mb-3">
              <h4 className="text-xs font-semibold text-[var(--v5-primary)] mb-2 pb-1
                border-b border-[var(--v5-border-subtle)]">
                {section.label}
              </h4>
              <div className={`grid ${gridCols} gap-x-3 gap-y-2`}>
                {sectionFields.map(renderField)}
              </div>
            </div>
          );
        })
      ) : (
        // 단일 섹션
        <div className={`grid ${gridCols} gap-x-3 gap-y-2`}>
          {formFields.map(renderField)}
        </div>
      )}

      {/* 버튼 영역 */}
      <div className="flex items-center justify-end gap-2 mt-3 pt-2 border-t border-[var(--v5-border-subtle)]">
        <button
          type="button"
          onClick={handleReset}
          disabled={!isModified}
          className="px-3 py-1 rounded text-xs border border-[var(--v5-border)]
            text-[var(--v5-text-sec)] bg-[var(--v5-surface)]
            hover:border-[var(--v5-primary)] hover:text-[var(--v5-primary)]
            disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
        >
          초기화
        </button>
        <button
          type="submit"
          className="px-3 py-1 rounded text-xs font-medium text-white
            bg-[var(--v5-primary)] hover:opacity-90
            shadow-[var(--v5-glow-sm)] transition-all"
        >
          {config.saveAction.method === 'INSERT' ? '등록' : '저장'}
        </button>
      </div>
    </form>
  );
}
