"use client";

/**
 * InvInputConfigPanel — 통합 "입력 필드" (id: input) cp 톤 설정 패널
 *
 * 흐름:
 *   ① 필드 타입 — CPVisualGrid 10칸 (text/number/date/datetime/select/entity/checkbox/textarea/file/code)
 *   ② 라벨 / 안내 — 라벨 + placeholder + 도움말
 *   ③ 타입별 옵션 — type 에 따라 조건부 (number min/max/step, text minLength/maxLength, textarea rows, select options, file accept/multiple, format)
 *   ▾ 옵션 — required / editable / disabled (FeatureChipGrid)
 *
 * Reference: notes/gbpark/2026-04-28-cp-panel-standard.md
 */

import React from "react";
import {
  Type,
  Hash,
  Calendar,
  CalendarClock,
  ChevronDown,
  Link2,
  CheckSquare,
  AlignLeft,
  Paperclip,
  Code2,
  Plus,
  X,
} from "lucide-react";
import {
  CPSection,
  CPRow,
  CPGroup,
  CPText,
  CPNumber,
  CPVisualGrid,
  FeatureChipGrid,
  Hint,
} from "@/components/v2/config-panels/_shared/cp";
import { RowDeleteBtn } from "../common/row-helpers";
import type { InputConfig, InputFieldType } from "./types";

export interface InvInputConfigPanelProps {
  config?: InputConfig;
  onChange?: (config: InputConfig) => void;
  selectedComponent?: { id: string; config?: InputConfig; [k: string]: any };
}

const TYPE_OPTIONS: Array<{
  value: InputFieldType;
  label: string;
  icon: React.ReactNode;
  desc: string;
}> = [
  { value: "text", label: "문자열", icon: <Type size={16} />, desc: "일반 텍스트 한 줄" },
  { value: "number", label: "숫자", icon: <Hash size={16} />, desc: "정수 / 소수 입력" },
  { value: "date", label: "날짜", icon: <Calendar size={16} />, desc: "YYYY-MM-DD" },
  { value: "datetime", label: "날짜+시간", icon: <CalendarClock size={16} />, desc: "분/초까지" },
  { value: "time", label: "시간", icon: <CalendarClock size={16} />, desc: "HH:mm" },
  { value: "daterange", label: "기간", icon: <Calendar size={16} />, desc: "시작 ~ 끝" },
  { value: "select", label: "드롭다운", icon: <ChevronDown size={16} />, desc: "선택지 list" },
  { value: "entity", label: "엔티티", icon: <Link2 size={16} />, desc: "FK 참조 (팝업)" },
  { value: "checkbox", label: "체크박스", icon: <CheckSquare size={16} />, desc: "참/거짓" },
  { value: "textarea", label: "장문", icon: <AlignLeft size={16} />, desc: "여러 줄 텍스트" },
  { value: "file", label: "파일", icon: <Paperclip size={16} />, desc: "업로드" },
  { value: "code", label: "자동채번", icon: <Code2 size={16} />, desc: "readonly · 자동 생성" },
];

export const InvInputConfigPanel: React.FC<InvInputConfigPanelProps> = ({
  config,
  onChange,
  selectedComponent,
}) => {
  const current: InputConfig =
    (config as InputConfig) || (selectedComponent?.config as InputConfig) || {};

  const patch = (p: Partial<InputConfig>) => onChange?.({ ...current, ...p });

  const type: InputFieldType = (current.type as InputFieldType) || "text";

  const optionsArr: string[] = Array.isArray(current.options)
    ? current.options.map((o: any) => (typeof o === "string" ? o : o.label || o.value || ""))
    : [];

  const addOption = () => patch({ options: [...optionsArr, ""] as any });
  const updateOption = (i: number, v: string) =>
    patch({ options: optionsArr.map((o, idx) => (idx === i ? v : o)) as any });
  const removeOption = (i: number) =>
    patch({ options: optionsArr.filter((_, idx) => idx !== i) as any });

  return (
    <div style={{ fontFamily: "var(--v5-font-sans)", color: "var(--cp-text)", padding: "0 12px" }}>
      {/* ── ① 필드 타입 ─────────────────────────── */}
      <CPSection title="① 필드 타입" desc="입력 모드 (변형 결정)">
        <CPVisualGrid
          cols={5}
          cardHeight={62}
          value={type}
          onChange={(v) => patch({ type: v as InputFieldType })}
          options={TYPE_OPTIONS.map((o) => ({
            value: o.value,
            label: o.label,
            preview: o.icon,
            desc: o.desc,
          }))}
        />
      </CPSection>

      {/* ── ② 라벨 / 안내 ─────────────────────────── */}
      <CPSection title="② 라벨 / 안내">
        <CPRow label="라벨" help="필드 위에 표시될 이름">
          <CPText
            value={current.label || ""}
            onChange={(v) => patch({ label: v })}
            placeholder="필드 라벨"
          />
        </CPRow>
        <CPRow label="placeholder" help="입력 전 안내 텍스트">
          <CPText
            value={current.placeholder || ""}
            onChange={(v) => patch({ placeholder: v })}
            placeholder="입력하세요"
          />
        </CPRow>
        <CPRow label="도움말" help="필드 하단 보조 안내">
          <CPText
            value={current.helperText || ""}
            onChange={(v) => patch({ helperText: v || undefined })}
            placeholder="하단 도움말"
          />
        </CPRow>
      </CPSection>

      {/* ── ③ 타입별 옵션 (조건부) ─────────────────────────── */}
      {type === "number" && (
        <CPSection title="③ 숫자 옵션" desc="범위 / 증감">
          <CPRow label="최소 (min)">
            <CPNumber
              value={current.min ?? undefined}
              onChange={(v) => patch({ min: v })}
              placeholder="제한 없음"
            />
          </CPRow>
          <CPRow label="최대 (max)">
            <CPNumber
              value={current.max ?? undefined}
              onChange={(v) => patch({ max: v })}
              placeholder="제한 없음"
            />
          </CPRow>
          <CPRow label="증감 단위 (step)" help="화살표/스피너 한 칸">
            <CPNumber
              value={current.step ?? undefined}
              onChange={(v) => patch({ step: v })}
              placeholder="1"
            />
          </CPRow>
          <CPRow label="포맷" help="예: #,##0  /  0.00">
            <CPText
              value={current.format || ""}
              onChange={(v) => patch({ format: v || undefined })}
              placeholder="#,##0"
            />
          </CPRow>
        </CPSection>
      )}

      {(type === "text" || type === "textarea") && (
        <CPSection title="③ 문자열 옵션">
          <CPRow label="최소 길이 (minLength)">
            <CPNumber
              value={current.minLength ?? undefined}
              onChange={(v) => patch({ minLength: v })}
              min={0}
              placeholder="제한 없음"
            />
          </CPRow>
          <CPRow label="최대 길이 (maxLength)">
            <CPNumber
              value={current.maxLength ?? undefined}
              onChange={(v) => patch({ maxLength: v })}
              min={0}
              placeholder="제한 없음"
            />
          </CPRow>
          {type === "textarea" && (
            <CPRow label="줄 수 (rows)">
              <CPNumber
                value={current.rows ?? 3}
                onChange={(v) => patch({ rows: v ?? 3 })}
                min={1}
                max={20}
              />
            </CPRow>
          )}
        </CPSection>
      )}

      {(type === "date" || type === "datetime" || type === "time" || type === "daterange") && (
        <CPSection title="③ 날짜 옵션">
          <CPRow
            label="포맷"
            help={
              type === "time"
                ? "예: HH:mm"
                : type === "datetime"
                  ? "예: YYYY-MM-DD HH:mm"
                  : "예: YYYY-MM-DD"
            }
          >
            <CPText
              value={(current as any).dateFormat || current.format || ""}
              onChange={(v) => patch({ dateFormat: v || undefined } as any)}
              placeholder={
                type === "time"
                  ? "HH:mm"
                  : type === "datetime"
                    ? "YYYY-MM-DD HH:mm"
                    : "YYYY-MM-DD"
              }
            />
          </CPRow>
        </CPSection>
      )}

      {type === "select" && (
        <CPSection title="③ 선택지" desc={`${optionsArr.length}개`}>
          <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: 5 }}>
            <button
              type="button"
              onClick={addOption}
              style={{
                padding: "4px 10px",
                fontSize: 10.5,
                background: "var(--cp-bg-subtle)",
                border: "1px solid var(--cp-border)",
                borderRadius: 4,
                cursor: "pointer",
                color: "var(--cp-text)",
                fontFamily: "var(--v5-font-sans)",
                display: "inline-flex",
                alignItems: "center",
                gap: 4,
              }}
            >
              <Plus size={10} /> 추가
            </button>
          </div>
          {optionsArr.length === 0 ? (
            <Hint>선택지가 없습니다. [+ 추가] 로 만드세요.</Hint>
          ) : (
            <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              {optionsArr.map((opt, i) => (
                <div
                  key={i}
                  style={{
                    display: "grid",
                    gridTemplateColumns: "16px 1fr 22px",
                    alignItems: "center",
                    columnGap: 6,
                    padding: "3px 6px",
                    background: "var(--cp-bg-subtle)",
                    border: "1px solid var(--cp-border-subtle)",
                    borderRadius: 4,
                  }}
                >
                  <span
                    style={{
                      fontSize: 9,
                      color: "var(--cp-text-muted)",
                      fontFamily: "var(--v5-font-mono)",
                      textAlign: "right",
                    }}
                  >
                    {i + 1}
                  </span>
                  <input
                    type="text"
                    value={opt}
                    onChange={(e) => updateOption(i, e.target.value)}
                    placeholder={`옵션 ${i + 1}`}
                    style={{
                      height: 22,
                      padding: "0 6px",
                      fontSize: 11,
                      background: "var(--cp-surface)",
                      border: "1px solid var(--cp-border)",
                      borderRadius: 3,
                      color: "var(--cp-text)",
                      outline: "none",
                      fontFamily: "var(--v5-font-sans)",
                    }}
                  />
                  <RowDeleteBtn onClick={() => removeOption(i)} hoverBg={false}>
                    <X size={10} />
                  </RowDeleteBtn>
                </div>
              ))}
            </div>
          )}
        </CPSection>
      )}

      {type === "file" && (
        <CPSection title="③ 파일 옵션">
          <CPRow label="허용 확장자" help="예: image/* 또는 .pdf,.docx">
            <CPText
              value={current.accept || ""}
              onChange={(v) => patch({ accept: v || undefined })}
              placeholder="image/*"
            />
          </CPRow>
          <FeatureChipGrid
            items={[
              {
                key: "multiple",
                label: "다중 선택",
                desc: "한 번에 여러 파일을 선택할 수 있어요.\nOFF 일 때는 한 파일씩 교체.",
              },
            ]}
            source={current as any}
            onToggle={(k, v) => patch({ [k]: v } as Partial<InputConfig>)}
          />
        </CPSection>
      )}

      {type === "entity" && (
        <CPSection title="③ 엔티티 참조" desc="FK 참조 — 팝업에서 행 선택">
          <Hint tone="warn">
            FK 참조 picker UI 는 추후 추가 예정. 현재는 type 만 저장 (백엔드 키 보존).
          </Hint>
        </CPSection>
      )}

      {type === "code" && (
        <CPSection title="③ 자동채번" desc="readonly · 저장 시 자동 생성">
          <Hint>채번 규칙은 별도 설정에서 관리합니다.</Hint>
        </CPSection>
      )}

      {type === "checkbox" && (
        <CPSection title="③ 체크박스">
          <Hint>체크박스는 추가 옵션이 없습니다 (참/거짓).</Hint>
        </CPSection>
      )}

      {/* ── ▾ 옵션 ─────────────────────────── */}
      <CPGroup title="옵션" defaultOpen>
        <FeatureChipGrid
          items={[
            {
              key: "required",
              label: "필수",
              desc: "비어 있으면 저장 시 검증 오류.\n라벨 우측에 빨간 * 표시.",
            },
            {
              key: "editable",
              label: "편집 가능",
              default: true,
              desc: "사용자가 값을 수정할 수 있어요.\nOFF = 화면에는 보이되 편집 불가 (readonly).",
            },
            {
              key: "disabled",
              label: "비활성화",
              desc: "필드 자체를 회색 처리하고 입력/포커스 차단.\n조건부 표시와 함께 자주 쓰여요.",
            },
          ]}
          source={current as any}
          onToggle={(k, v) => patch({ [k]: v } as Partial<InputConfig>)}
        />
      </CPGroup>
    </div>
  );
};

InvInputConfigPanel.displayName = "InvInputConfigPanel";

export default InvInputConfigPanel;
