"use client";

/**
 * ComponentSettingsModal.tsx
 *
 * 인캔버스 설정 모달 — 기능 설정 / 표시 조건 / 미리보기 3탭 구조.
 * SettingsModalShell 모듈을 사용하여 모든 컴포넌트가 동일한 모달 형식을 유지.
 * card 타입은 Draft 기반 저장/취소 지원.
 */

import { useState, useCallback, useEffect, useRef } from "react";
import { Eye as EyeIcon, Sliders, Layers } from "lucide-react";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
import { SettingsModalShell, useModalAlert } from "./SettingsModalShell";
import type { ModalTabDef } from "./SettingsModalShell";
import { useUnsavedChangesGuard, UnsavedChangesDialog } from "@/components/common/UnsavedChangesGuard";

import { ConditionalSettingsTab } from "./ConditionalSettingsTab";
import { ComponentPreviewPanel } from "./ComponentPreviewPanel";

import { TextProperties } from "../properties/TextProperties";
import { ImageProperties } from "../properties/ImageProperties";
import { TableProperties } from "../properties/TableProperties";
import { CardProperties } from "../properties/CardProperties";
import { CalculationProperties } from "../properties/CalculationProperties";
import { BarcodeProperties } from "../properties/BarcodeProperties";
import { CheckboxProperties } from "../properties/CheckboxProperties";
import { SignatureProperties } from "../properties/SignatureProperties";
import { PageNumberProperties } from "../properties/PageNumberProperties";
import type { ComponentConfig } from "@/types/report";

const TYPE_LABELS: Record<string, string> = {
  text: "텍스트",
  label: "레이블",
  table: "테이블",
  image: "이미지",
  divider: "구분선",
  signature: "서명",
  stamp: "도장",
  pageNumber: "페이지 번호",
  card: "카드",
  calculation: "계산",
  barcode: "바코드",
  checkbox: "체크박스",
};

interface DataTabProps {
  component: ComponentConfig;
  onConfigChange?: (updates: Partial<ComponentConfig>) => void;
}

function DataTab({ component, onConfigChange }: DataTabProps) {
  switch (component.type) {
    case "text":
    case "label":
      return <TextProperties component={component} section="data" />;
    case "table":
      return <TableProperties component={component} section="data" />;
    case "image":
      return <ImageProperties component={component} section="data" />;
    case "signature":
    case "stamp":
      return <SignatureProperties component={component} section="data" />;
    case "pageNumber":
      return <PageNumberProperties component={component} />;
    case "card":
      return (
        <CardProperties
          component={component}
          section="data"
          onConfigChange={onConfigChange}
        />
      );
    case "calculation":
      return <CalculationProperties component={component} section="data" />;
    case "barcode":
      return <BarcodeProperties component={component} section="data" />;
    case "checkbox":
      return <CheckboxProperties component={component} section="data" />;
    default:
      return <p className="p-4 text-sm text-gray-500">이 타입은 추가 기능 설정이 없습니다.</p>;
  }
}

const TYPES_WITH_DATA_TAB = new Set([
  "text",
  "label",
  "table",
  "image",
  "signature",
  "stamp",
  "pageNumber",
  "card",
  "calculation",
  "barcode",
  "checkbox",
]);

export function ComponentSettingsModal() {
  const { componentModalTargetId, closeComponentModal, components, updateComponent } = useReportDesigner();

  const component = components.find((c) => c.id === componentModalTargetId) ?? null;
  const isDivider = component?.type === "divider";
  const isOpen = componentModalTargetId !== null && component !== null && !isDivider;

  const [activeTab, setActiveTab] = useState("content");
  const [localDraft, setLocalDraft] = useState<ComponentConfig | null>(null);
  const { alert, clearAlert } = useModalAlert();
  const initialSnapshotRef = useRef<string>("");

  useEffect(() => {
    if (component) {
      setLocalDraft(component);
      initialSnapshotRef.current = JSON.stringify(component);
      clearAlert();
      const hasData = TYPES_WITH_DATA_TAB.has(component.type);
      setActiveTab(hasData ? "content" : "preview");
    }
  }, [componentModalTargetId, clearAlert]);

  const hasChanges = useCallback(() => {
    if (component?.type === "card") {
      if (!localDraft) return false;
      return JSON.stringify(localDraft) !== initialSnapshotRef.current;
    }
    if (!component) return false;
    return JSON.stringify(component) !== initialSnapshotRef.current;
  }, [localDraft, component]);

  const isSavingRef = useRef(false);

  const guard = useUnsavedChangesGuard({
    hasChanges,
    onClose: () => {
      if (!isSavingRef.current && initialSnapshotRef.current && component) {
        const original = JSON.parse(initialSnapshotRef.current) as ComponentConfig;
        updateComponent(component.id, original);
      }
      isSavingRef.current = false;
      setLocalDraft(null);
      clearAlert();
      closeComponentModal();
    },
  });

  const handleSave = useCallback(() => {
    if (component?.type === "card" && localDraft) {
      updateComponent(localDraft.id, localDraft);
    }
    isSavingRef.current = true;
    initialSnapshotRef.current = component?.type === "card" && localDraft
      ? JSON.stringify(localDraft)
      : JSON.stringify(component);
    guard.doClose();
  }, [component, localDraft, updateComponent, guard]);

  const handleDraftChange = useCallback(
    (updates: Partial<ComponentConfig>) => {
      setLocalDraft((prev) => {
        if (!prev && component) return { ...component, ...updates };
        if (!prev) return null;
        return { ...prev, ...updates };
      });
    },
    [component],
  );

  if (!component) return null;

  const hasDataTab = TYPES_WITH_DATA_TAB.has(component.type);
  const typeLabel = TYPE_LABELS[component.type] ?? component.type;
  const isCard = component.type === "card";
  const isTable = component.type === "table";
  const isText = component.type === "text" || component.type === "label";
  const isImage = component.type === "image";
  const hideConditionTab = isText || isImage || isDivider;
  const hasInternalConditionTab = isCard || isTable || hideConditionTab;
  const displayComponent = isCard && localDraft ? localDraft : component;

  const tabs: ModalTabDef[] = [
    hasDataTab && {
      key: "content",
      icon: <Sliders className="h-4 w-4" />,
      label: "기능 설정",
    },
    !hasInternalConditionTab && {
      key: "conditional",
      icon: <EyeIcon className="h-4 w-4" />,
      label: "표시 조건",
    },
    {
      key: "preview",
      icon: <EyeIcon className="h-4 w-4" />,
      label: "미리보기",
    },
  ].filter(Boolean) as ModalTabDef[];

  return (
    <>
      <SettingsModalShell
        open={isOpen}
        onOpenChange={guard.handleOpenChange}
        title={`${typeLabel} 설정`}
        icon={<Layers className="h-5 w-5" />}
        tabs={tabs}
        activeTab={activeTab}
        onTabChange={setActiveTab}
        onSave={handleSave}
        onClose={guard.tryClose}
        alert={alert}
      >
        {activeTab === "content" && hasDataTab && (
          <DataTab
            component={displayComponent}
            onConfigChange={isCard ? handleDraftChange : undefined}
          />
        )}

        {activeTab === "conditional" && !hasInternalConditionTab && (
          <ConditionalSettingsTab component={component} />
        )}

        {activeTab === "preview" && (
          <ComponentPreviewPanel component={displayComponent} />
        )}
      </SettingsModalShell>
      <UnsavedChangesDialog guard={guard} />
    </>
  );
}
