'use client';

/**
 * Form Popup — 등록/수정 팝업 창 (window.open 으로 열리는 별도 브라우저 창).
 *
 * URL: /form-popup?templateId={id}&mode={create|edit}&key={uniqueKey}
 *
 * 초기 데이터는 부모 창(DashboardCard)이 localStorage 에 임시 저장하고,
 * 팝업이 mount 시 key 로 읽어 즉시 삭제한다. 저장 성공 시 부모 창에
 * postMessage({ type: 'form-popup-saved', key, mode }) 를 보내고 자동 닫힘.
 *
 * (main) 레이아웃 바깥이라 헤더/사이드바 없이 깔끔한 팝업 UI.
 */

import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useSearchParams } from 'next/navigation';
import { toast } from 'sonner';
import { X } from 'lucide-react';
import { FcForm } from '@/components/fc';
import { getTemplateInfo } from '@/lib/api/template';
import { fcInsert, fcUpdate } from '@/lib/api/fcData';
import type { TemplateRenderContext } from '@/components/dash/TemplateRenderer';
import { PopupTemplateRenderer } from '@/components/dash/PopupTemplateRenderer';
import type { FieldConfig, Template } from '@/types/invyone-component';

export default function FormPopupPage() {
  return (
    <Suspense
      fallback={
        <div className="bg-background flex h-screen flex-col">
          <div className="border-border flex items-center justify-between border-b px-4 py-2">
            <span className="text-sm font-semibold">불러오는 중...</span>
          </div>
          <div className="flex-1 overflow-hidden p-6">
            <div className="grid animate-pulse grid-cols-2 gap-6">
              {Array.from({ length: 8 }).map((_, i) => (
                <div key={i} className="flex flex-col gap-2">
                  <div className="h-3 w-16 rounded bg-muted" />
                  <div className="h-9 w-full rounded bg-muted" />
                </div>
              ))}
            </div>
          </div>
        </div>
      }
    >
      <FormPopupContent />
    </Suspense>
  );
}

function FormPopupContent() {
  const params = useSearchParams();
  const templateId = params.get('templateId') ?? '';
  const mode = (params.get('mode') ?? 'create') as 'create' | 'edit';
  const key = params.get('key') ?? '';

  const [template, setTemplate] = useState<Template | null>(null);
  const [fields, setFields] = useState<FieldConfig[]>([]);
  const [primaryTable, setPrimaryTable] = useState('');
  const [templateName, setTemplateName] = useState('');
  const [formRow, setFormRow] = useState<Record<string, any> | null>(null);
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState<string | null>(null);
  // 사용자가 폼을 편집하기 시작했는지 플래그 — 백그라운드 재검증이
  // template 을 교체해 현재 입력 UX 를 깨뜨리지 않도록 보호.
  const formRowDirtyRef = useRef(false);

  useEffect(() => {
    if (!templateId) {
      setError('templateId 가 없습니다');
      setLoaded(true);
      return;
    }

    // localStorage 에서 부모가 넘겨준 seed 읽기 + 즉시 삭제 (1회성).
    // template 이 함께 넘어오면 즉시 렌더 후 백그라운드에서 재검증.
    let seededName = '';
    let seededTable = '';
    let seededTemplate: any = null;
    try {
      const raw = localStorage.getItem(`form-popup:${key}`);
      if (raw) {
        const data = JSON.parse(raw);
        setFormRow(data.initialRow ?? {});
        if (data.primaryTable) {
          seededTable = String(data.primaryTable);
          setPrimaryTable(seededTable);
        }
        if (data.templateName) {
          seededName = String(data.templateName);
          setTemplateName(seededName);
        }
        if (data.template) seededTemplate = data.template;
        localStorage.removeItem(`form-popup:${key}`);
      } else {
        setFormRow({});
      }
    } catch {
      setFormRow({});
    }

    // 1) seed 가 있으면 즉시 렌더 상태로 전환 (로딩 플래시 제거)
    if (seededTemplate) {
      setTemplate(seededTemplate as Template);
      if (Array.isArray(seededTemplate.fields)) {
        setFields(seededTemplate.fields as FieldConfig[]);
      }
      if (!seededName) setTemplateName(seededTemplate.name ?? '');
      if (!seededTable) {
        setPrimaryTable(
          seededTemplate.primary_table ?? seededTemplate.PRIMARY_TABLE ?? '',
        );
      }
      setLoaded(true);
    }

    // 2) 항상 백그라운드 재검증 — seed 가 stale 일 수 있으므로. 사용자가
    //    폼을 편집하기 시작했으면(dirty) 조용히 skip 해서 UX 깨지지 않게.
    getTemplateInfo(templateId)
      .then((tpl) => {
        if (!tpl) {
          if (!seededTemplate) setLoaded(true);
          return;
        }
        // dirty 면 교체하지 않고 skip — 사용자가 이미 폼 편집 중
        if (formRowDirtyRef.current && seededTemplate) return;
        setTemplate(tpl as Template);
        if (Array.isArray((tpl as any).fields)) {
          setFields((tpl as any).fields as FieldConfig[]);
        }
        if (!seededName) setTemplateName((tpl as any).name ?? '');
        if (!seededTable) {
          const pt =
            (tpl as any).primary_table ?? (tpl as any).PRIMARY_TABLE ?? '';
          setPrimaryTable(pt);
        }
        setLoaded(true);
      })
      .catch((err: any) => {
        // seed 로 이미 렌더됐으면 에러는 무시. seed 없었으면 에러 표시.
        if (!seededTemplate) {
          setError(err?.message ?? '템플릿 로드 실패');
          setLoaded(true);
        }
      });
  }, [templateId, key]);

  const pkColumn = useMemo(() => {
    const pkField = fields.find((f) => f.pk);
    return pkField?.column ?? '';
  }, [fields]);

  const handleFormRowChange = useCallback((patch: Record<string, any>) => {
    formRowDirtyRef.current = true;
    setFormRow((prev) => ({ ...(prev ?? {}), ...patch }));
  }, []);

  const handleSubmit = useCallback(
    async (rowOverride?: Record<string, any>) => {
      const row = rowOverride ?? formRow;
      if (!row || !primaryTable) return;
      try {
        if (mode === 'create') {
          await fcInsert(primaryTable, row);
        } else {
          if (!pkColumn) throw new Error('PK 컬럼이 없습니다');
          const id = String(row[pkColumn] ?? '');
          if (!id) throw new Error('PK 값이 비어있습니다');
          await fcUpdate(primaryTable, id, row);
        }
        try {
          window.opener?.postMessage(
            { type: 'form-popup-saved', key, mode },
            window.location.origin,
          );
        } catch {
          /* opener 접근 실패해도 팝업은 닫음 */
        }
        window.close();
      } catch (err: any) {
        console.error('[FormPopup] 저장 실패:', err);
        toast.error(err?.message ?? '저장 실패');
      }
    },
    [formRow, primaryTable, pkColumn, mode, key],
  );

  const handleCancel = useCallback(() => {
    window.close();
  }, []);

  const hasCustomView = useMemo(() => {
    const view = (template?.views as any)?.[mode];
    if (!view) return false;
    if (Array.isArray(view)) return view.length > 0;
    if (Array.isArray(view.blocks)) return view.blocks.length > 0;
    if (Array.isArray(view.components)) return view.components.length > 0;
    return false;
  }, [template, mode]);

  // canvas 크기 resolve / resizeTo / scale fit 은 모두 PopupTemplateRenderer
  // 내부에서 처리. 여기서는 데이터만 준비한다.

  const context: TemplateRenderContext = useMemo(
    () => ({
      fields,
      data: [],
      loading: false,
      primaryTable,
      selectedRow: formRow ?? null,
      totalCount: 0,
      page: 1,
      pageSize: 20,
      searchParams: {},
      onSearch: () => {},
      onRowSelect: () => {},
      onPageChange: () => {},
      onAdd: () => {},
      onEdit: () => {},
      onDelete: () => {},
      formRow: formRow ?? undefined,
      onFormRowChange: handleFormRowChange,
      onFormSubmit: () => handleSubmit(),
      onFormCancel: handleCancel,
    }),
    [
      fields,
      primaryTable,
      formRow,
      handleFormRowChange,
      handleSubmit,
      handleCancel,
    ],
  );

  // 로딩 상태에서도 dev 모드 JIT 컴파일 시간 동안 빈 화면 대신 헤더 + 스켈레톤
  // 을 즉시 표시해서 사용자 체감 반응성을 개선. (dev 모드는 첫 진입에 번들
  // 컴파일로 수초 걸릴 수 있음)
  if (!loaded) {
    return (
      <div className="bg-background flex h-screen flex-col">
        <div className="border-border flex items-center justify-between border-b px-4 py-2">
          <span className="text-sm font-semibold">
            {templateName
              ? `${templateName} ${mode === 'create' ? '등록' : '수정'}`
              : '불러오는 중...'}
          </span>
          <button
            type="button"
            onClick={handleCancel}
            className="hover:bg-muted flex h-7 w-7 items-center justify-center rounded"
            title="닫기 (Esc)"
          >
            <X size={14} />
          </button>
        </div>
        <div className="flex-1 overflow-hidden p-6">
          <div className="grid animate-pulse grid-cols-2 gap-6">
            {Array.from({ length: 8 }).map((_, i) => (
              <div key={i} className="flex flex-col gap-2">
                <div className="h-3 w-16 rounded bg-muted" />
                <div className="h-9 w-full rounded bg-muted" />
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }
  if (error)
    return (
      <div className="p-6 text-sm text-destructive">⚠ {error}</div>
    );
  if (!template)
    return (
      <div className="p-6 text-sm text-destructive">
        템플릿을 찾을 수 없습니다
      </div>
    );

  const title = `${templateName || '템플릿'} ${mode === 'create' ? '등록' : '수정'}`;

  return (
    <div className="bg-background flex h-screen flex-col">
      <div className="border-border flex items-center justify-between border-b px-4 py-2">
        <span className="text-sm font-semibold">{title}</span>
        <button
          type="button"
          onClick={handleCancel}
          className="hover:bg-muted flex h-7 w-7 items-center justify-center rounded"
          title="닫기 (Esc)"
        >
          <X size={14} />
        </button>
      </div>
      <div className="flex-1 overflow-hidden">
        {hasCustomView ? (
          // 전용 렌더러가 canvas × scale 로 창을 꽉 채운다. 내부에서 scale/resize
          // 전부 처리하므로 여기는 뷰포트만 넘겨주면 됨.
          <PopupTemplateRenderer
            template={template}
            context={context}
            view={mode}
          />
        ) : (
          <div className="p-4 w-full h-full overflow-auto">
            <FcForm
              fields={fields}
              loadRow={formRow ?? {}}
              onSubmit={(row) => handleSubmit(row)}
              config={{ columns: 2 }}
            />
          </div>
        )}
      </div>
    </div>
  );
}
