"use client";

import type { ButtonBlockProps } from "@/features/editor/state/editorStore";
import { NumericPropertyControl } from "@/features/editor/components/NumericPropertyControl";
import { ColorPickerField, TEXT_COLOR_PALETTE } from "@/features/editor/components/ColorPickerField";

export type ButtonPropertiesPanelProps = {
  buttonProps: ButtonBlockProps;
  selectedBlockId: string;
  updateBlock: (id: string, partial: Partial<ButtonBlockProps>) => void;
};

export function ButtonPropertiesPanel({ buttonProps, selectedBlockId, updateBlock }: ButtonPropertiesPanelProps) {
  const imageSource: "none" | "url" | "upload" = (() => {
    const hasSrc = (buttonProps.imageSrc ?? "").trim() !== "";
    if (!hasSrc) return "none";
    if (buttonProps.imageSourceType === "asset") return "upload";
    return "url";
  })();

  return (
    <>
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>버튼 텍스트</span>
          <textarea
            className="w-full min-h-[60px] rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
            aria-label="버튼 텍스트"
            value={buttonProps.label}
            onChange={(e) => {
              updateBlock(selectedBlockId, { label: e.target.value } as any);
            }}
          />
        </label>
      </div>
      <div className="mt-3 space-y-2 border-t border-slate-800 pt-3 text-xs text-slate-400">
        <h4 className="text-[11px] font-semibold text-slate-200">버튼 이미지</h4>

        <div className="space-y-1">
          <label className="flex flex-col gap-1">
            <span>버튼 이미지 소스</span>
            <select
              className="w-full rounded border border-slate-700 bg-slate-900 px-2 py-1 text-[11px] outline-none focus:border-sky-500"
              aria-label="버튼 이미지 소스"
              value={imageSource}
              onChange={(e) => {
                const next = e.target.value as "none" | "url" | "upload";
                if (next === "none") {
                  updateBlock(selectedBlockId, {
                    imageSrc: "",
                    imageAssetId: null,
                  } as any);
                } else if (next === "url") {
                  updateBlock(selectedBlockId, {
                    imageSourceType: "externalUrl",
                    imageAssetId: null,
                  } as any);
                } else {
                  updateBlock(selectedBlockId, {
                    imageSourceType: "asset",
                  } as any);
                }
              }}
            >
              <option value="none">사용 안 함</option>
              <option value="url">URL</option>
              <option value="upload">파일 업로드</option>
            </select>
          </label>
        </div>

        {imageSource === "url" && (
          <div className="space-y-1">
            <label className="flex flex-col gap-1">
              <span>버튼 이미지 URL</span>
              <input
                className="w-full rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
                aria-label="버튼 이미지 URL"
                value={buttonProps.imageSrc ?? ""}
                onChange={(e) => {
                  const value = e.target.value;
                  updateBlock(selectedBlockId, {
                    imageSrc: value,
                    imageSourceType: "externalUrl",
                    imageAssetId: null,
                  } as any);
                }}
              />
            </label>
          </div>
        )}

        {imageSource === "upload" && (
          <div className="space-y-1">
            <label className="flex flex-col gap-1">
              <span>버튼 이미지 파일 업로드</span>
              <input
                type="file"
                accept="image/*"
                className="w-full text-[11px] text-slate-300 file:mr-2 file:rounded file:border file:border-slate-700 file:bg-slate-800 file:px-2 file:py-1 file:text-[11px] file:text-slate-100 hover:file:bg-slate-700"
                aria-label="버튼 이미지 파일 업로드"
                onChange={async (event) => {
                  const file = event.target.files?.[0];
                  if (!file) return;

                  try {
                    const formData = new FormData();
                    formData.append("file", file);

                    const response = await fetch("/api/image", {
                      method: "POST",
                      body: formData,
                    });

                    if (!response.ok) {
                      console.error("버튼 이미지 업로드 실패", await response.text());
                      return;
                    }

                    const data = (await response.json()) as { id: string; servedUrl?: string | null };
                    const servedUrl = data.servedUrl ?? `/api/image/${data.id}`;

                    updateBlock(selectedBlockId, {
                      imageSrc: servedUrl,
                      imageSourceType: "asset",
                      imageAssetId: data.id,
                    } as any);
                  } catch (error) {
                    console.error("버튼 이미지 업로드 중 오류", error);
                  } finally {
                    event.target.value = "";
                  }
                }}
              />
            </label>
          </div>
        )}

        {imageSource !== "none" && (
          <>
            <div className="space-y-1">
              <label className="flex flex-col gap-1">
                <span>버튼 이미지 대체 텍스트</span>
                <input
                  className="w-full rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
                  aria-label="버튼 이미지 대체 텍스트"
                  value={buttonProps.imageAlt ?? ""}
                  onChange={(e) => {
                    updateBlock(selectedBlockId, { imageAlt: e.target.value } as any);
                  }}
                />
              </label>
            </div>

            <div className="space-y-1">
              <label className="flex flex-col gap-1">
                <span>버튼 이미지 위치</span>
                <select
                  className="rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
                  aria-label="버튼 이미지 위치"
                  value={buttonProps.imagePlacement ?? "left"}
                  onChange={(e) => {
                    updateBlock(selectedBlockId, {
                      imagePlacement: e.target.value as any,
                    } as any);
                  }}
                >
                  <option value="left">텍스트 왼쪽</option>
                  <option value="right">텍스트 오른쪽</option>
                  <option value="top">텍스트 위쪽</option>
                  <option value="bottom">텍스트 아래쪽</option>
                </select>
              </label>
            </div>
          </>
        )}
      </div>
      <div className="space-y-1">
        <NumericPropertyControl
          label="가로 패딩 (px)"
          unitLabel="(px)"
          value={buttonProps.paddingX ?? 16}
          min={0}
          max={120}
          step={4}
          presets={[
            { id: "xs", label: "XS", value: 8 },
            { id: "sm", label: "S", value: 12 },
            { id: "md", label: "M", value: 16 },
            { id: "lg", label: "L", value: 24 },
            { id: "xl", label: "XL", value: 32 },
          ]}
          onChangeValue={(v) => {
            updateBlock(selectedBlockId, {
              paddingX: v,
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <NumericPropertyControl
          label="세로 패딩 (px)"
          unitLabel="(px)"
          value={buttonProps.paddingY ?? 10}
          min={0}
          max={80}
          step={2}
          presets={[
            { id: "xs", label: "XS", value: 6 },
            { id: "sm", label: "S", value: 8 },
            { id: "md", label: "M", value: 10 },
            { id: "lg", label: "L", value: 14 },
            { id: "xl", label: "XL", value: 20 },
          ]}
          onChangeValue={(v) => {
            updateBlock(selectedBlockId, {
              paddingY: v,
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>버튼 링크</span>
          <input
            className="w-full rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
            aria-label="버튼 링크"
            value={buttonProps.href}
            onChange={(e) => {
              updateBlock(selectedBlockId, { href: e.target.value } as any);
            }}
          />
        </label>
      </div>
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>정렬</span>
          <select
            className="rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
            aria-label="버튼 정렬"
            value={buttonProps.align ?? "left"}
            onChange={(e) => {
              const value = e.target.value as NonNullable<ButtonBlockProps["align"]>;
              updateBlock(selectedBlockId, { align: value } as any);
            }}
          >
            <option value="left">왼쪽</option>
            <option value="center">가운데</option>
            <option value="right">오른쪽</option>
          </select>
        </label>
      </div>
      <div className="space-y-1">
        {/* 버튼 크기 스케일 컨트롤은 paddingX/paddingY 및 폰트 크기(px) 컨트롤로 충분하므로 제거했다. */}
      </div>
      <div className="space-y-1">
        <ColorPickerField
          label="텍스트 색상"
          ariaLabelColorInput="버튼 텍스트 색상 피커"
          ariaLabelHexInput="버튼 텍스트 색상 HEX"
          value={
            buttonProps.textColorCustom && buttonProps.textColorCustom.startsWith("#")
              ? buttonProps.textColorCustom
              : "#f9fafb"
          }
          onChange={(hex) => {
            updateBlock(selectedBlockId, {
              textColorCustom: hex,
            } as any);
          }}
          palette={TEXT_COLOR_PALETTE}
          onPaletteSelect={(item) => {
            updateBlock(selectedBlockId, {
              textColorCustom: item.color,
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>스타일</span>
          <select
            className="rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
            aria-label="버튼 스타일"
            value={buttonProps.variant ?? "solid"}
            onChange={(e) => {
              const value = e.target.value as NonNullable<ButtonBlockProps["variant"]>;
              updateBlock(selectedBlockId, { variant: value } as any);
            }}
          >
            <option value="solid">채움</option>
            <option value="outline">외곽선</option>
            <option value="ghost">고스트</option>
          </select>
        </label>
      </div>
      <div className="space-y-1">
        <ColorPickerField
          label="채움 색상"
          ariaLabelColorInput="버튼 채움 색상 피커"
          ariaLabelHexInput="버튼 채움 색상 HEX"
          value={
            buttonProps.fillColorCustom && buttonProps.fillColorCustom.startsWith("#")
              ? buttonProps.fillColorCustom
              : TEXT_COLOR_PALETTE[0]?.color ?? "#0ea5e9"
          }
          onChange={(hex) => {
            updateBlock(selectedBlockId, {
              fillColorCustom: hex,
            } as any);
          }}
          palette={TEXT_COLOR_PALETTE}
          onPaletteSelect={(item) => {
            updateBlock(selectedBlockId, {
              fillColorCustom: item.color,
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <ColorPickerField
          label="외곽선 색상"
          ariaLabelColorInput="버튼 외곽선 색상 피커"
          ariaLabelHexInput="버튼 외곽선 색상 HEX"
          value={
            buttonProps.strokeColorCustom && buttonProps.strokeColorCustom.startsWith("#")
              ? buttonProps.strokeColorCustom
              : TEXT_COLOR_PALETTE[0]?.color ?? "#0ea5e9"
          }
          onChange={(hex) => {
            updateBlock(selectedBlockId, {
              strokeColorCustom: hex,
            } as any);
          }}
          palette={TEXT_COLOR_PALETTE}
          onPaletteSelect={(item) => {
            updateBlock(selectedBlockId, {
              strokeColorCustom: item.color,
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <NumericPropertyControl
          label="모서리 둥글기"
          value={(() => {
            const r = buttonProps.borderRadius ?? "md";
            return r === "none" ? 0 : r === "sm" ? 1 : r === "lg" ? 3 : r === "full" ? 4 : 2;
          })()}
          min={0}
          max={4}
          step={1}
          presets={[
            { id: "none", label: "없음", value: 0 },
            { id: "sm", label: "작게", value: 1 },
            { id: "md", label: "보통", value: 2 },
            { id: "lg", label: "크게", value: 3 },
            { id: "full", label: "완전 둥글게", value: 4 },
          ]}
          onChangeValue={(v) => {
            const next =
              v <= 0 ? "none" : v === 1 ? "sm" : v === 3 ? "lg" : v >= 4 ? "full" : "md";
            updateBlock(selectedBlockId, { borderRadius: next } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>버튼 너비 모드</span>
          <select
            className="rounded border border-slate-700 bg-slate-900 px-2 py-1 text-xs outline-none focus:border-sky-500"
            aria-label="버튼 너비 모드"
            value={buttonProps.widthMode ?? (buttonProps.fullWidth ? "full" : "auto")}
            onChange={(e) => {
              updateBlock(selectedBlockId, {
                widthMode: e.target.value as NonNullable<ButtonBlockProps["widthMode"]>,
              } as any);
            }}
          >
            <option value="auto">자동</option>
            <option value="full">전체 폭</option>
            <option value="fixed">고정 값</option>
          </select>
        </label>
        {(buttonProps.widthMode ?? (buttonProps.fullWidth ? "full" : "auto")) === "fixed" && (
          <NumericPropertyControl
            label="버튼 고정 너비"
            unitLabel="(px)"
            value={buttonProps.widthPx ?? 240}
            min={80}
            max={600}
            step={10}
            presets={[
              { id: "sm", label: "작게", value: 180 },
              { id: "md", label: "보통", value: 240 },
              { id: "lg", label: "넓게", value: 320 },
            ]}
            onChangeValue={(v) => {
              updateBlock(selectedBlockId, {
                widthPx: v,
              } as any);
            }}
          />
        )}
      </div>
      <div className="space-y-1">
        <NumericPropertyControl
          label="버튼 크기"
          unitLabel="(px)"
          value={(() => {
            const raw = buttonProps.fontSizeCustom ?? "";
            const match = raw.match(/([0-9]+(?:\.[0-9]+)?)/);
            if (match) return Number(match[1]);
            // 기본 버튼 텍스트 크기: md 스케일(16px) 기준
            return 16;
          })()}
          min={10}
          max={32}
          step={1}
          presets={[
            { id: "xs", label: "XS", value: 12 },
            { id: "sm", label: "S", value: 14 },
            { id: "base", label: "M", value: 16 },
            { id: "lg", label: "L", value: 18 },
            { id: "xl", label: "XL", value: 20 },
            { id: "2xl", label: "2XL", value: 24 },
            { id: "3xl", label: "3XL", value: 30 },
          ]}
          onChangeValue={(px) => {
            // 버튼은 텍스트 스케일 상태 없이 px만 저장하지만,
            // 프리셋 값은 TextPropertiesPanel과 동일한 테이블을 사용한다.
            updateBlock(selectedBlockId, {
              fontSizeCustom: `${px}px`,
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <NumericPropertyControl
          label="줄 간격"
          value={(() => {
            const raw = buttonProps.lineHeightCustom ?? "";
            const match = raw.match(/(-?[0-9]+(?:\.[0-9]+)?)/);
            if (match) return Number(match[1]);
            return 1.4;
          })()}
          min={0.8}
          max={3}
          step={0.05}
          presets={[
            { id: "tight", label: "좁게", value: 1.1 },
            { id: "normal", label: "보통", value: 1.4 },
            { id: "relaxed", label: "넓게", value: 1.8 },
          ]}
          onChangeValue={(v) => {
            updateBlock(selectedBlockId, {
              lineHeightCustom: v.toString(),
            } as any);
          }}
        />
      </div>
      <div className="space-y-1">
        <NumericPropertyControl
          label="글자 간격"
          unitLabel="(px)"
          value={(() => {
            const raw = buttonProps.letterSpacingCustom ?? "";
            const match = raw.match(/(-?[0-9]+(?:\.[0-9]+)?)/);
            if (match) {
              const em = Number(match[1]);
              if (Number.isFinite(em)) return em * 16;
            }
            return 0;
          })()}
          min={-2}
          max={10}
          step={0.1}
          presets={[
            { id: "tighter", label: "아주 좁게", value: -1.5 },
            { id: "tight", label: "좁게", value: -0.5 },
            { id: "normal", label: "보통", value: 0 },
            { id: "wide", label: "넓게", value: 1 },
            { id: "wider", label: "아주 넓게", value: 2 },
          ]}
          onChangeValue={(px) => {
            const em = px / 16;
            updateBlock(selectedBlockId, {
              letterSpacingCustom: `${em}em`,
            } as any);
          }}
        />
      </div>
    </>
  );
}
