"use client";

import React, { useState, useEffect, useCallback, useRef } from "react";
import { useAuth } from "@/hooks/useAuth";
import { apiClient } from "@/lib/api/client";
import type { PopSettings } from "@/hooks/pop/usePopSettings";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Checkbox } from "@/components/ui/checkbox";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Save,
  RotateCcw,
  X,
  Plus,
  Trash2,
  Settings2,
  Loader2,
  ChevronRight,
  ChevronDown,
  PackageOpen,
  Truck,
  Factory,
  Home,
  Cpu,
} from "lucide-react";

// ============================================================
// Default Settings (mirrors usePopSettings.ts DEFAULT_SETTINGS)
// ============================================================
const DEFAULT_SETTINGS: PopSettings = {
  version: "hardcoded-1.0",
  screens: {
    processExecution: {
      materialInput: true,
      photoUpload: true,
      plcEnabled: false,
      bomFlexible: true,
      packagingOptions: ["낱개", "박스", "파렛트"],
      defectTypes: ["스크래치", "치수불량", "변색", "크랙", "기포"],
      reworkTargetSelection: true,
      groupPhotoEnabled: false,
      dateFilter: false,
      lastProcessInventory: "manual",
      defaultWarehouse: false,
      inspectionAutoJudge: "off",
      standardTimeDisplay: false,
      progressDisplay: false,
    },
    inbound: {
      inspectionRequired: false,
      photoUpload: false,
      barcodeEnabled: true,
      packagingRecord: false,
      defectSeparation: false,
    },
    outbound: {
      photoUpload: false,
      barcodeEnabled: true,
    },
    home: {
      kpiCarousel: true,
      recentActivity: true,
      bannerEnabled: false,
      bannerText: "",
      iconThemeColor: "#2563eb",
      iconCustomImages: false,
      dashboardLayout: "default",
    },
    plc: {
      connectionType: "db",
      refreshInterval: 5,
      tagMappings: [],
      alarmThresholds: [],
    },
  },
};

// ============================================================
// Screen Groups & Items
// ============================================================
interface ScreenItem {
  id: string;
  name: string;
  url: string;
  settingsKey: string;
  screenId: number;
}

interface ScreenGroup {
  id: string;
  name: string;
  icon: string;
  screens: ScreenItem[];
}

const SCREEN_GROUPS: ScreenGroup[] = [
  {
    id: "inbound",
    name: "입고",
    icon: "PackageOpen",
    screens: [
      { id: "purchase-inbound", name: "구매입고", url: "/pop/inbound/purchase", settingsKey: "inbound", screenId: 6528 },
      { id: "inbound-cart", name: "입고 장바구니", url: "/pop/inbound/cart", settingsKey: "inbound", screenId: 6527 },
      { id: "inbound-type", name: "입고유형선택", url: "/pop/inbound", settingsKey: "inbound", screenId: 6529 },
    ],
  },
  {
    id: "outbound",
    name: "출고",
    icon: "Truck",
    screens: [
      { id: "sales-outbound", name: "판매출고", url: "/pop/outbound/sales", settingsKey: "outbound", screenId: 5 },
      { id: "outbound-type", name: "출고유형선택", url: "/pop/outbound", settingsKey: "outbound", screenId: 6 },
      { id: "outbound-cart", name: "출고 장바구니", url: "/pop/outbound/cart", settingsKey: "outbound", screenId: 7010 },
    ],
  },
  {
    id: "production",
    name: "생산",
    icon: "Factory",
    screens: [
      { id: "process-execution", name: "공정실행", url: "/pop/production/process", settingsKey: "processExecution", screenId: 7 },
      { id: "production-main", name: "생산관리", url: "/pop/production", settingsKey: "processExecution", screenId: 8 },
    ],
  },
  {
    id: "home",
    name: "홈",
    icon: "Home",
    screens: [
      { id: "home-screen", name: "홈 화면", url: "/pop/home", settingsKey: "home", screenId: 6526 },
    ],
  },
  {
    id: "plc",
    name: "PLC",
    icon: "Cpu",
    screens: [
      { id: "plc-settings", name: "PLC 연동", url: "/pop/home", settingsKey: "plc", screenId: 6526 },
    ],
  },
];

const ICON_MAP: Record<string, React.ComponentType<{ className?: string }>> = {
  PackageOpen,
  Truck,
  Factory,
  Home,
  Cpu,
};

// ============================================================
// Settings Schema
// ============================================================
interface SettingField {
  key: string;
  label: string;
  description: string;
  type: "toggle" | "text" | "number" | "select" | "color" | "tags" | "array-object" | "numbering-rule";
  defaultValue?: unknown;
  options?: { value: string; label: string }[];
  fields?: { key: string; label: string; type: string }[];
  tableFilter?: string; // numbering-rule용: inbound/outbound 등
  showOnlyForScreens?: string[]; // 특정 화면 ID에서만 표시 (예: ["inbound-cart"])
}

const SETTINGS_SCHEMA: Record<string, SettingField[]> = {
  inbound: [
    { key: "numberingRuleId", label: "📋 입고번호 채번규칙", description: "입고 확정 시 사용할 채번규칙을 선택합니다", type: "numbering-rule", tableFilter: "inbound", showOnlyForScreens: ["inbound-cart"] },
    { key: "barcodeEnabled", label: "바코드 스캔 (미구현)", description: "바코드/QR 스캔 기능을 사용합니다", type: "toggle" },
    { key: "inspectionRequired", label: "검사 필수 (미구현)", description: "입고 시 검사 항목을 필수로 표시합니다", type: "toggle" },
    { key: "photoUpload", label: "사진 첨부 (미구현)", description: "입고 확정 시 사진 첨부를 허용합니다", type: "toggle" },
    { key: "packagingRecord", label: "포장 기록 (미구현)", description: "포장/적재 상세 기록을 사용합니다", type: "toggle" },
    { key: "defectSeparation", label: "불량 분리 (미구현)", description: "양품/불량 수량을 분리 입력합니다", type: "toggle" },
  ],
  outbound: [
    { key: "numberingRuleId", label: "📋 출고번호 채번규칙", description: "출고 확정 시 사용할 채번규칙을 선택합니다", type: "numbering-rule", tableFilter: "outbound", showOnlyForScreens: ["outbound-cart"] },
    { key: "barcodeEnabled", label: "바코드 스캔 (미구현)", description: "바코드/QR 스캔 기능을 사용합니다", type: "toggle" },
    { key: "photoUpload", label: "사진 첨부 (미구현)", description: "출고 시 사진 첨부를 허용합니다", type: "toggle" },
  ],
  processExecution: [
    { key: "materialInput", label: "자재 투입", description: "BOM 기반 자재 투입 탭을 표시합니다", type: "toggle" },
    { key: "bomFlexible", label: "BOM 유동 투입 (미구현)", description: "기준과 다른 수량 투입을 허용합니다", type: "toggle" },
    { key: "photoUpload", label: "사진 첨부 (미구현)", description: "실적 입력 시 사진 첨부를 허용합니다", type: "toggle" },
    { key: "groupPhotoEnabled", label: "그룹별 사진", description: "체크리스트 그룹마다 사진을 첨부합니다", type: "toggle" },
    { key: "plcEnabled", label: "PLC 연동 (미구현)", description: "설비 PLC 데이터를 자동 연동합니다", type: "toggle" },
    { key: "reworkTargetSelection", label: "재작업 공정 지정 (미구현)", description: "불량 처리 시 특정 공정을 선택할 수 있습니다", type: "toggle" },
    { key: "dateFilter", label: "날짜 필터 (미구현)", description: "작업지시 목록에 날짜 필터를 표시합니다", type: "toggle" },
    {
      key: "lastProcessInventory", label: "마지막 공정 입고 (미구현)", description: "마지막 공정 완료 시 재고 입고 방식", type: "select", options: [
        { value: "auto", label: "자동 입고" },
        { value: "manual", label: "수동 선택" },
        { value: "button", label: "버튼 활성화" },
      ],
    },
    { key: "defaultWarehouse", label: "기본 창고 기억 (미구현)", description: "선택한 창고를 다음에도 자동 선택합니다", type: "toggle" },
    {
      key: "inspectionAutoJudge", label: "검사 자동 판정 (미구현)", description: "수치 검사 시 상/하한 초과 처리 방식", type: "select", options: [
        { value: "off", label: "사용 안 함" },
        { value: "warn", label: "경고만 표시" },
        { value: "fail", label: "자동 불량" },
      ],
    },
    { key: "standardTimeDisplay", label: "표준시간 비교 (미구현)", description: "표준시간 대비 실제시간을 표시합니다", type: "toggle" },
    { key: "progressDisplay", label: "진행률 표시 (미구현)", description: "작업지시 전체 진행률을 표시합니다", type: "toggle" },
    { key: "packagingOptions", label: "포장 옵션 (미구현)", description: "포장 단위 선택지를 관리합니다", type: "tags" },
    { key: "defectTypes", label: "불량 유형 (미구현)", description: "불량 유형 선택지를 관리합니다", type: "tags" },
  ],
  home: [
    { key: "kpiCarousel", label: "KPI 캐러셀 (미구현)", description: "오늘의 현황 캐러셀을 표시합니다", type: "toggle" },
    { key: "recentActivity", label: "최근 활동 (미구현)", description: "최근 입출고 활동을 표시합니다", type: "toggle" },
    { key: "bannerEnabled", label: "공지 배너", description: "상단에 공지 배너를 표시합니다", type: "toggle" },
    { key: "bannerText", label: "배너 텍스트", description: "공지 배너에 표시할 텍스트", type: "text" },
    { key: "iconThemeColor", label: "아이콘 테마색 (미구현)", description: "메뉴 아이콘의 테마 색상", type: "color" },
    { key: "iconCustomImages", label: "아이콘 커스텀 (미구현)", description: "메뉴 아이콘 이미지를 커스터마이즈합니다", type: "toggle" },
    {
      key: "dashboardLayout", label: "대시보드 구성 (미구현)", description: "홈 대시보드 레이아웃", type: "select", options: [
        { value: "default", label: "기본" },
        { value: "compact", label: "컴팩트" },
        { value: "detailed", label: "상세" },
      ],
    },
  ],
  plc: [
    {
      key: "connectionType", label: "연결 방식", description: "PLC 데이터 연동 방식", type: "select", options: [
        { value: "db", label: "DB 직접 연결" },
        { value: "opcua", label: "OPC-UA" },
        { value: "rest", label: "REST API" },
      ],
    },
    { key: "refreshInterval", label: "갱신 주기(초)", description: "PLC 데이터 갱신 주기", type: "number" },
    {
      key: "tagMappings", label: "태그 매핑", description: "PLC 태그와 공정/체크리스트 연결", type: "array-object", fields: [
        { key: "tagName", label: "태그명", type: "text" },
        { key: "processCode", label: "공정코드", type: "text" },
        { key: "checklistItemId", label: "체크리스트 항목", type: "text" },
        { key: "unit", label: "단위", type: "text" },
      ],
    },
    {
      key: "alarmThresholds", label: "알람 임계값", description: "PLC 값 임계치 경고 설정", type: "array-object", fields: [
        { key: "tagName", label: "태그명", type: "text" },
        { key: "lowerLimit", label: "하한", type: "number" },
        { key: "upperLimit", label: "상한", type: "number" },
        { key: "action", label: "동작", type: "select" },
      ],
    },
  ],
};

// ============================================================
// 채번규칙 셀렉트 컴포넌트
// ============================================================

function NumberingRuleSelect({
  field,
  value,
  onChange,
}: {
  field: SettingField;
  value: unknown;
  onChange: (value: unknown) => void;
}) {
  const { user } = useAuth();
  const [rules, setRules] = useState<{ value: string; label: string }[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const loadRules = async () => {
      setLoading(true);
      try {
        const companyCode = user?.companyCode || "COMPANY_16";
        const res = await apiClient.get(`/numbering-rules?company_code=${companyCode}`);
        const data = res.data?.data || res.data || [];
        const allRules: any[] = Array.isArray(data) ? data : (data.rules || []);
        // tableFilter로 필터링 (inbound/outbound 등)
        const filtered = field.tableFilter
          ? allRules.filter((r: any) => {
              const t = (r.tableName || "").toLowerCase();
              const c = (r.columnName || "").toLowerCase();
              const n = (r.ruleName || "").toLowerCase();
              const f = field.tableFilter!.toLowerCase();
              return t.includes(f) || c.includes(f) || n.includes(f);
            })
          : allRules;
        const finalRules = filtered.length > 0 ? filtered : allRules;
        setRules(
          finalRules.map((r: any) => ({
            value: r.ruleId,
            label: `${r.ruleName || r.tableName + "." + r.columnName}`,
          }))
        );
      } catch {
        setRules([]);
      }
      setLoading(false);
    };
    loadRules();
  }, [user?.companyCode, field.tableFilter]);

  return (
    <div className="py-3 border-b last:border-0 space-y-1.5">
      <Label className="text-sm font-medium">{field.label}</Label>
      <p className="text-xs text-muted-foreground">{field.description}</p>
      {loading ? (
        <p className="text-xs text-muted-foreground">채번규칙 로드 중...</p>
      ) : rules.length === 0 ? (
        <p className="text-xs text-amber-600">등록된 채번규칙이 없습니다. PC에서 먼저 채번규칙을 등록해주세요.</p>
      ) : (
        <Select value={(value as string) || ""} onValueChange={onChange}>
          <SelectTrigger className="w-full h-9">
            <SelectValue placeholder="채번규칙을 선택하세요" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="__none__">선택 안 함 (기본)</SelectItem>
            {rules.map((r) => (
              <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>
            ))}
          </SelectContent>
        </Select>
      )}
    </div>
  );
}

// ============================================================
// Sub-components: TagEditor, ArrayObjectEditor
// ============================================================

function TagEditor({
  label,
  description,
  tags,
  onChange,
}: {
  label: string;
  description: string;
  tags: string[];
  onChange: (tags: string[]) => void;
}) {
  const [input, setInput] = useState("");

  return (
    <div className="py-3 border-b last:border-0">
      <Label className="text-sm font-medium">{label}</Label>
      <p className="text-xs text-muted-foreground mt-0.5 mb-2">{description}</p>
      <div className="flex flex-wrap gap-1.5 mb-2">
        {tags.map((tag, idx) => (
          <Badge key={`${tag}-${idx}`} variant="secondary" className="gap-1 pr-1">
            {tag}
            <button
              onClick={() => onChange(tags.filter((_, i) => i !== idx))}
              className="ml-0.5 hover:text-destructive"
            >
              <X className="h-3 w-3" />
            </button>
          </Badge>
        ))}
      </div>
      <div className="flex gap-2">
        <Input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter" && input.trim()) {
              e.preventDefault();
              onChange([...tags, input.trim()]);
              setInput("");
            }
          }}
          placeholder="추가 후 Enter"
          className="flex-1 h-8 text-sm"
        />
        <Button
          type="button"
          variant="outline"
          size="sm"
          onClick={() => {
            if (input.trim()) {
              onChange([...tags, input.trim()]);
              setInput("");
            }
          }}
        >
          <Plus className="h-3.5 w-3.5" />
        </Button>
      </div>
    </div>
  );
}

function ArrayObjectEditor({
  field,
  items,
  onChange,
}: {
  field: SettingField;
  items: Record<string, unknown>[];
  onChange: (items: Record<string, unknown>[]) => void;
}) {
  const addRow = () => {
    const newRow: Record<string, unknown> = {};
    field.fields?.forEach((f) => {
      newRow[f.key] = f.type === "number" ? 0 : "";
    });
    onChange([...items, newRow]);
  };

  const updateRow = (index: number, key: string, value: unknown) => {
    const updated = items.map((item, i) => (i === index ? { ...item, [key]: value } : item));
    onChange(updated);
  };

  const removeRow = (index: number) => {
    onChange(items.filter((_, i) => i !== index));
  };

  return (
    <div className="py-3 border-b last:border-0">
      <div className="flex items-center justify-between mb-2">
        <div>
          <Label className="text-sm font-medium">{field.label}</Label>
          <p className="text-xs text-muted-foreground mt-0.5">{field.description}</p>
        </div>
        <Button type="button" variant="outline" size="sm" onClick={addRow}>
          <Plus className="h-3.5 w-3.5 mr-1" />
          추가
        </Button>
      </div>
      {items.length === 0 && (
        <p className="text-xs text-muted-foreground py-2">항목이 없습니다. 추가 버튼을 눌러주세요.</p>
      )}
      <div className="space-y-2">
        {items.map((item, index) => (
          <div key={index} className="flex items-start gap-2 p-2 bg-muted/30 rounded-md">
            <div className="flex-1 grid grid-cols-2 gap-2">
              {field.fields?.map((f) => (
                <div key={f.key}>
                  <Label className="text-xs text-muted-foreground">{f.label}</Label>
                  {f.type === "number" ? (
                    <Input
                      type="number"
                      value={item[f.key] as number || 0}
                      onChange={(e) => updateRow(index, f.key, Number(e.target.value))}
                      className="h-7 text-xs"
                    />
                  ) : f.type === "select" ? (
                    <Select
                      value={(item[f.key] as string) || ""}
                      onValueChange={(v) => updateRow(index, f.key, v)}
                    >
                      <SelectTrigger size="sm" className="h-7 text-xs">
                        <SelectValue placeholder="선택" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="warn">경고</SelectItem>
                        <SelectItem value="stop">정지</SelectItem>
                      </SelectContent>
                    </Select>
                  ) : (
                    <Input
                      value={(item[f.key] as string) || ""}
                      onChange={(e) => updateRow(index, f.key, e.target.value)}
                      className="h-7 text-xs"
                    />
                  )}
                </div>
              ))}
            </div>
            <Button
              type="button"
              variant="ghost"
              size="icon"
              className="h-7 w-7 mt-4 text-muted-foreground hover:text-destructive"
              onClick={() => removeRow(index)}
            >
              <Trash2 className="h-3.5 w-3.5" />
            </Button>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// SettingRow — renders a single setting field
// ============================================================
function SettingRow({
  field,
  value,
  onChange,
}: {
  field: SettingField;
  value: unknown;
  onChange: (value: unknown) => void;
}) {
  switch (field.type) {
    case "toggle":
      return (
        <div className="flex items-center justify-between py-3 border-b last:border-0">
          <div className="pr-4">
            <Label className="text-sm font-medium">{field.label}</Label>
            <p className="text-xs text-muted-foreground mt-0.5">{field.description}</p>
          </div>
          <Switch checked={!!value} onCheckedChange={onChange} />
        </div>
      );
    case "text":
      return (
        <div className="py-3 border-b last:border-0 space-y-1.5">
          <Label className="text-sm font-medium">{field.label}</Label>
          <p className="text-xs text-muted-foreground">{field.description}</p>
          <Input
            value={(value as string) || ""}
            onChange={(e) => onChange(e.target.value)}
            placeholder={field.label}
            className="h-9"
          />
        </div>
      );
    case "number":
      return (
        <div className="py-3 border-b last:border-0 space-y-1.5">
          <Label className="text-sm font-medium">{field.label}</Label>
          <p className="text-xs text-muted-foreground">{field.description}</p>
          <Input
            type="number"
            value={(value as number) ?? 0}
            onChange={(e) => onChange(Number(e.target.value))}
            className="h-9 w-32"
          />
        </div>
      );
    case "select":
      return (
        <div className="py-3 border-b last:border-0 space-y-1.5">
          <Label className="text-sm font-medium">{field.label}</Label>
          <p className="text-xs text-muted-foreground">{field.description}</p>
          <Select value={(value as string) || field.options?.[0]?.value || ""} onValueChange={onChange}>
            <SelectTrigger size="sm" className="w-48">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {field.options?.map((o) => (
                <SelectItem key={o.value} value={o.value}>
                  {o.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      );
    case "numbering-rule":
      return <NumberingRuleSelect field={field} value={value} onChange={onChange} />;
    case "color":
      return (
        <div className="py-3 border-b last:border-0 space-y-1.5">
          <Label className="text-sm font-medium">{field.label}</Label>
          <p className="text-xs text-muted-foreground">{field.description}</p>
          <div className="flex items-center gap-2">
            <input
              type="color"
              value={(value as string) || "#2563eb"}
              onChange={(e) => onChange(e.target.value)}
              className="w-9 h-9 rounded-md cursor-pointer border border-input p-0.5"
            />
            <Input
              value={(value as string) || "#2563eb"}
              onChange={(e) => onChange(e.target.value)}
              className="h-9 w-32"
              placeholder="#hex"
            />
          </div>
        </div>
      );
    case "tags":
      return (
        <TagEditor
          label={field.label}
          description={field.description}
          tags={(value as string[]) || []}
          onChange={onChange}
        />
      );
    case "array-object":
      return (
        <ArrayObjectEditor
          field={field}
          items={(value as Record<string, unknown>[]) || []}
          onChange={onChange}
        />
      );
    default:
      return null;
  }
}

// ============================================================
// ScreenNav — top collapsible screen selector (세로 펼침)
// ============================================================
function ScreenNav({
  groups,
  selectedScreen,
  onSelect,
  collapsed,
  onToggleCollapse,
}: {
  groups: ScreenGroup[];
  selectedScreen: ScreenItem | null;
  onSelect: (screen: ScreenItem) => void;
  collapsed: boolean;
  onToggleCollapse: () => void;
}) {
  const [expandedGroup, setExpandedGroup] = useState<string | null>(null);

  const handleGroupClick = (groupId: string) => {
    setExpandedGroup(expandedGroup === groupId ? null : groupId);
  };

  const handleScreenSelect = (screen: ScreenItem) => {
    onSelect(screen);
    setExpandedGroup(null);
    if (!collapsed) onToggleCollapse(); // 선택 후 자동 접기
  };

  if (collapsed) {
    // 접힌 상태: 현재 선택된 화면명 + 펼치기 버튼
    return (
      <div className="border-b bg-muted/20 px-4 py-2 flex items-center gap-3 shrink-0">
        <button
          onClick={onToggleCollapse}
          className="flex items-center gap-2 px-3 py-1.5 rounded-lg hover:bg-muted transition-colors text-sm"
        >
          <ChevronRight className="h-4 w-4 text-muted-foreground rotate-90" />
          <span className="text-muted-foreground">화면 선택</span>
        </button>
        {selectedScreen && (
          <Badge variant="secondary" className="text-xs">
            📍 {selectedScreen.name}
          </Badge>
        )}
      </div>
    );
  }

  // 펼친 상태: 메뉴 그룹 가로 나열 + 클릭 시 하위 화면 드롭
  return (
    <div className="border-b bg-muted/20 shrink-0">
      {/* 상단: 그룹 탭 가로 나열 + 접기 버튼 */}
      <div className="flex items-center gap-1 px-4 py-2 border-b border-border/50">
        <button
          onClick={onToggleCollapse}
          className="p-1.5 rounded-md hover:bg-muted transition-colors mr-2"
          title="접기"
        >
          <ChevronRight className="h-4 w-4 text-muted-foreground -rotate-90" />
        </button>
        {groups.map((group) => {
          const Icon = ICON_MAP[group.icon];
          const isExpanded = expandedGroup === group.id;
          const hasSelected = group.screens.some((s) => s.id === selectedScreen?.id);

          return (
            <button
              key={group.id}
              onClick={() => handleGroupClick(group.id)}
              className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${
                isExpanded
                  ? "bg-primary text-primary-foreground"
                  : hasSelected
                    ? "bg-primary/10 text-primary"
                    : "hover:bg-muted text-foreground/70"
              }`}
            >
              {Icon && <Icon className="h-3.5 w-3.5" />}
              {group.name}
              <ChevronRight
                className={`h-3 w-3 transition-transform ${isExpanded ? "rotate-90" : ""}`}
              />
            </button>
          );
        })}
      </div>

      {/* 하위 화면 목록 (펼쳐진 그룹) */}
      {expandedGroup && (
        <div className="flex items-center gap-2 px-4 py-2 bg-muted/30">
          <span className="text-xs text-muted-foreground mr-2">
            {groups.find((g) => g.id === expandedGroup)?.name}:
          </span>
          {groups
            .find((g) => g.id === expandedGroup)
            ?.screens.map((screen) => {
              const isSelected = selectedScreen?.id === screen.id;
              return (
                <button
                  key={screen.id}
                  onClick={() => handleScreenSelect(screen)}
                  className={`px-3 py-1.5 rounded-lg text-sm transition-colors ${
                    isSelected
                      ? "bg-primary text-primary-foreground font-medium"
                      : "bg-background border hover:bg-muted/50"
                  }`}
                >
                  {screen.name}
                </button>
              );
            })}
        </div>
      )}
    </div>
  );
}

// ============================================================
// SettingsForm — auto-rendered from schema
// ============================================================
function SettingsForm({
  screenName,
  settingsKey,
  fields,
  values,
  onChange,
}: {
  screenName: string;
  settingsKey: string;
  fields: SettingField[];
  values: Record<string, unknown>;
  onChange: (key: string, value: unknown) => void;
}) {
  return (
    <div className="space-y-1">
      <div className="flex items-center gap-2 pb-3 border-b mb-1">
        <Settings2 className="h-5 w-5 text-primary" />
        <h2 className="text-lg font-bold">{screenName} 설정</h2>
        <Badge variant="outline" className="text-xs">
          {settingsKey}
        </Badge>
      </div>
      {fields.map((field) => (
        <SettingRow
          key={field.key}
          field={field}
          value={values[field.key]}
          onChange={(v) => onChange(field.key, v)}
        />
      ))}
    </div>
  );
}

// ============================================================
// Main Page Component
// ============================================================
export default function PopSettingsMngPage() {
  const { user } = useAuth();
  const [settings, setSettings] = useState<PopSettings>(DEFAULT_SETTINGS);
  const [saving, setSaving] = useState(false);
  const [loading, setLoading] = useState(true);
  const [selectedScreen, setSelectedScreen] = useState<ScreenItem | null>(
    SCREEN_GROUPS[0].screens[0],
  );
  const [navCollapsed, setNavCollapsed] = useState(false);
  const [hasChanges, setHasChanges] = useState(false);
  const [syncToAll, setSyncToAll] = useState(false);
  const [lastPath, setLastPath] = useState("");
  const iframeRef = useRef<HTMLIFrameElement>(null);

  // ---- Load settings from screen_layouts_pop per screen ----
  const fetchSettings = useCallback(async () => {
    setLoading(true);
    try {
      // Collect all unique screenIds from SCREEN_GROUPS
      const allScreens: { screenId: number; settingsKey: string }[] = [];
      for (const group of SCREEN_GROUPS) {
        for (const screen of group.screens) {
          if (!allScreens.some((s) => s.screenId === screen.screenId && s.settingsKey === screen.settingsKey)) {
            allScreens.push({ screenId: screen.screenId, settingsKey: screen.settingsKey });
          }
        }
      }

      // Fetch popConfig from each screen's layout-pop
      const merged: PopSettings = JSON.parse(JSON.stringify(DEFAULT_SETTINGS));

      await Promise.all(
        allScreens.map(async ({ screenId, settingsKey }) => {
          try {
            const res = await apiClient.get(`/screen-management/screens/${screenId}/layout-pop`);
            const popConfig = res.data?.data?.settings?.popConfig;
            if (popConfig) {
              const key = settingsKey as keyof PopSettings["screens"];
              (merged.screens as Record<string, Record<string, unknown>>)[key] = {
                ...(merged.screens as Record<string, Record<string, unknown>>)[key],
                ...popConfig,
              };
            }
          } catch {
            // Screen may not have layout-pop yet, use defaults
          }
        }),
      );

      setSettings(merged);
    } catch {
      // Fallback: use defaults
    }
    setLoading(false);
  }, []);

  useEffect(() => {
    fetchSettings();
  }, [fetchSettings]);

  // ---- iframe navigation sync ----
  useEffect(() => {
    const timer = setInterval(() => {
      try {
        const path = iframeRef.current?.contentWindow?.location.pathname;
        if (path && path !== lastPath) {
          setLastPath(path);
          // 1순위: 정확 일치, 2순위: 길이 긴 url부터 startsWith 매칭 (구체적 경로 우선)
          let bestMatch: ScreenItem | null = null;
          let bestUrlLength = -1;
          for (const group of SCREEN_GROUPS) {
            for (const s of group.screens) {
              if (path === s.url) {
                bestMatch = s;
                bestUrlLength = Infinity;
                break;
              }
              if (path.startsWith(s.url + "/") && s.url.length > bestUrlLength) {
                bestMatch = s;
                bestUrlLength = s.url.length;
              }
            }
            if (bestUrlLength === Infinity) break;
          }
          if (bestMatch) setSelectedScreen(bestMatch);
        }
      } catch {
        // cross-origin: silently ignore
      }
    }, 1000);
    return () => clearInterval(timer);
  }, [lastPath]);

  // ---- Screen select handler ----
  const handleScreenSelect = (screen: ScreenItem) => {
    setSelectedScreen(screen);
    if (iframeRef.current) {
      iframeRef.current.src = screen.url;
    }
  };

  // ---- Settings update helper ----
  const updateScreenSetting = (settingsKey: string, fieldKey: string, value: unknown) => {
    setSettings((prev) => ({
      ...prev,
      screens: {
        ...prev.screens,
        [settingsKey]: {
          ...(prev.screens as Record<string, Record<string, unknown>>)[settingsKey],
          [fieldKey]: value,
        },
      },
    }));
    setHasChanges(true);
  };

  // ---- Save to screen_layouts_pop per screen ----
  const handleSave = async () => {
    if (!selectedScreen) return;
    setSaving(true);

    try {
      const currentKey = selectedScreen.settingsKey as keyof PopSettings["screens"];
      const popConfigToSave = (settings.screens as Record<string, Record<string, unknown>>)[currentKey];

      // Helper: save popConfig to a single screen's layout-pop
      const saveToScreen = async (screenId: number, popConfig: Record<string, unknown>) => {
        // 1. Get current layout
        const layoutRes = await apiClient.get(`/screen-management/screens/${screenId}/layout-pop`).catch(() => null);
        const layoutData = layoutRes?.data?.data || { version: "pop-5.0", components: {}, settings: {}, gridConfig: {} };

        // 2. Update settings.popConfig
        layoutData.settings = {
          ...(layoutData.settings || {}),
          popConfig,
        };

        // 3. Save
        await apiClient.post(`/screen-management/screens/${screenId}/layout-pop`, layoutData);
      };

      // Save to the selected screen
      await saveToScreen(selectedScreen.screenId, popConfigToSave);

      // If syncToAll is on, save to all other screens with the same settingsKey
      if (syncToAll) {
        const otherScreens: number[] = [];
        for (const group of SCREEN_GROUPS) {
          for (const screen of group.screens) {
            if (screen.settingsKey === selectedScreen.settingsKey && screen.screenId !== selectedScreen.screenId) {
              if (!otherScreens.includes(screen.screenId)) {
                otherScreens.push(screen.screenId);
              }
            }
          }
        }
        await Promise.all(otherScreens.map((sid) => saveToScreen(sid, popConfigToSave)));
      }

      setHasChanges(false);
      // Reload iframe to apply settings
      if (iframeRef.current) {
        iframeRef.current.contentWindow?.location.reload();
      }
      alert("설정이 저장되었습니다.");
    } catch {
      alert("저장에 실패했습니다.");
    }
    setSaving(false);
  };

  // ---- Reset to defaults ----
  const handleReset = () => {
    if (window.confirm("모든 설정을 기본값으로 초기화하시겠습니까?")) {
      setSettings(DEFAULT_SETTINGS);
      setHasChanges(true);
    }
  };

  // ---- Current screen schema values ----
  const currentSettingsKey = selectedScreen?.settingsKey || "inbound";
  const allFields = SETTINGS_SCHEMA[currentSettingsKey] || [];
  // showOnlyForScreens 옵션이 있으면 현재 화면 ID와 일치할 때만 표시
  const currentFields = allFields.filter((f) => {
    if (!f.showOnlyForScreens) return true;
    return selectedScreen?.id ? f.showOnlyForScreens.includes(selectedScreen.id) : false;
  });
  const currentValues = (settings.screens as Record<string, Record<string, unknown>>)[currentSettingsKey] || {};

  return (
    <div className="h-full flex flex-col">
      {/* ---- Header ---- */}
      <div className="flex items-center justify-between px-4 py-2 border-b bg-background">
        <div className="flex items-center gap-3">
          <Settings2 className="h-5 w-5 text-primary" />
          <h1 className="text-base font-bold">POP 화면 설정</h1>
          <Badge variant="outline" className="text-xs">
            {user?.companyCode || "COMPANY_16"}
          </Badge>
          {hasChanges && (
            <Badge variant="warning" className="text-xs">
              미저장 변경
            </Badge>
          )}
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={handleReset} disabled={saving}>
            <RotateCcw className="h-3.5 w-3.5 mr-1" />
            기본값 초기화
          </Button>
          <Button size="sm" onClick={handleSave} disabled={saving || !hasChanges}>
            {saving ? (
              <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
            ) : (
              <Save className="h-3.5 w-3.5 mr-1" />
            )}
            {saving ? "저장중..." : "저장"}
          </Button>
        </div>
      </div>

      {/* ---- Screen Nav (top, collapsible vertically) ---- */}
      <ScreenNav
        groups={SCREEN_GROUPS}
        selectedScreen={selectedScreen}
        onSelect={handleScreenSelect}
        collapsed={navCollapsed}
        onToggleCollapse={() => setNavCollapsed((prev) => !prev)}
      />

      {/* ---- Body: iframe (left) + settings (right) ---- */}
      <div className="flex-1 flex overflow-hidden">
        {/* Left: iframe (POP preview) */}
        <div className="flex-1 min-w-0 bg-muted/10 relative">
          {loading ? (
            <div className="absolute inset-0 flex items-center justify-center">
              <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
            </div>
          ) : (
            <iframe
              ref={iframeRef}
              src={selectedScreen?.url || "/pop/home"}
              className="w-full h-full border-0"
              title="POP 미리보기"
            />
          )}
        </div>

        {/* Right: Settings form */}
        <div className="w-[420px] flex-shrink-0 overflow-y-auto p-4 border-l bg-background">
          {selectedScreen && currentFields.length > 0 ? (
            <>
              <SettingsForm
                screenName={selectedScreen.name}
                settingsKey={currentSettingsKey}
                fields={currentFields}
                values={currentValues}
                onChange={(key, value) => updateScreenSetting(currentSettingsKey, key, value)}
              />
              {/* Sync to all screens with same settingsKey */}
              <div className="mt-4 pt-4 border-t">
                <div className="flex items-center gap-2">
                  <Checkbox
                    id="sync-to-all"
                    checked={syncToAll}
                    onCheckedChange={(checked) => setSyncToAll(!!checked)}
                  />
                  <Label htmlFor="sync-to-all" className="text-sm cursor-pointer">
                    같은 유형의 모든 화면에 적용
                  </Label>
                </div>
                <p className="text-xs text-muted-foreground mt-1 ml-6">
                  저장 시 동일 설정키({currentSettingsKey})를 공유하는 화면에도 설정을 동기화합니다.
                </p>
              </div>
            </>
          ) : (
            <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
              <Settings2 className="h-12 w-12 mb-3 opacity-30" />
              <p className="text-sm">상단에서 화면을 선택하세요</p>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
