"use client";

import type { ImageBlockProps } from "@/features/editor/state/editorStore";
import { NumericPropertyControl } from "@/features/editor/components/NumericPropertyControl";
import { ColorPickerField, TEXT_COLOR_PALETTE } from "@/features/editor/components/ColorPickerField";
import { useAppLocale } from "@/features/i18n/LocaleProvider";
import { getEditorImagePanelMessages } from "@/features/i18n/messages/editorImagePanel";

export type ImagePropertiesPanelProps = {
  imageProps: ImageBlockProps;
  selectedBlockId: string;
  updateBlock: (id: string, partial: Partial<ImageBlockProps>) => void;
};

export function ImagePropertiesPanel({ imageProps, selectedBlockId, updateBlock }: ImagePropertiesPanelProps) {
  const locale = useAppLocale();
  const m = getEditorImagePanelMessages(locale);
  const source: "url" | "upload" =
    imageProps.sourceType === "asset" || (imageProps.src && imageProps.src.startsWith("/api/image/"))
      ? "upload"
      : "url";

  return (
    <>
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>{m.imageSourceLabel}</span>
          <select
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            aria-label={m.imageSourceAria}
            value={source}
            onChange={(e) => {
              const next = e.target.value as "url" | "upload";
              if (next === "url") {
                updateBlock(selectedBlockId, {
                  sourceType: "externalUrl",
                  assetId: null,
                } as any);
              } else {
                updateBlock(selectedBlockId, {
                  sourceType: "asset",
                } as any);
              }
            }}
          >
            <option value="url">{m.imageSourceOptionUrl}</option>
            <option value="upload">{m.imageSourceOptionUpload}</option>
          </select>
        </label>
      </div>

      {source === "url" && (
        <div className="space-y-1">
          <label className="flex flex-col gap-1 text-xs text-slate-400">
            <span>{m.imageUrlLabel}</span>
            <input
              className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-xs text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
              aria-label={m.imageUrlAria}
              value={imageProps.src}
              onChange={(e) => {
                const value = e.target.value;
                updateBlock(selectedBlockId, {
                  src: value,
                  sourceType: "externalUrl",
                  assetId: null,
                } as any);
              }}
            />
          </label>
        </div>
      )}

      {source === "upload" && (
        <div className="space-y-1">
          <label className="flex flex-col gap-1 text-xs text-slate-400">
            <span>{m.imageUploadLabel}</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={m.imageUploadAria}
              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("Image upload failed", 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, {
                    src: servedUrl,
                    sourceType: "asset",
                    assetId: data.id,
                  } as any);
                } catch (error) {
                  console.error("Error while uploading image", error);
                } finally {
                  event.target.value = "";
                }
              }}
            />
          </label>
        </div>
      )}
      <div className="space-y-1">
        <label className="flex flex-col gap-1 text-xs text-slate-400">
          <span>{m.altLabel}</span>
          <input
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-xs text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            aria-label={m.altAria}
            value={imageProps.alt}
            onChange={(e) => {
              updateBlock(selectedBlockId, { alt: 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-800 dark:text-slate-200">{m.styleSectionTitle}</h4>

        {/* 카드 배경색 */}
        <div className="space-y-1">
          <ColorPickerField
            label={m.cardBackgroundLabel}
            ariaLabelColorInput={m.cardBackgroundPickerAria}
            ariaLabelHexInput={m.cardBackgroundHexAria}
            value={imageProps.backgroundColorCustom ?? ""}
            onChange={(hex) => {
              const next = hex && hex.trim().length > 0 ? hex : undefined;
              updateBlock(selectedBlockId, { backgroundColorCustom: next } as any);
            }}
            palette={TEXT_COLOR_PALETTE}
          />
        </div>

        {/* 정렬 */}
        <label className="flex flex-col gap-1">
          <span>{m.alignLabel}</span>
          <select
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            aria-label={m.alignAria}
            value={imageProps.align ?? "center"}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                align: e.target.value as ImageBlockProps["align"],
              } as any)
            }
          >
            <option value="left">{m.alignOptionLeft}</option>
            <option value="center">{m.alignOptionCenter}</option>
            <option value="right">{m.alignOptionRight}</option>
          </select>
        </label>

        {/* 너비 모드 */}
        <label className="flex flex-col gap-1">
          <span>{m.widthModeLabel}</span>
          <select
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            aria-label={m.widthModeAria}
            value={imageProps.widthMode ?? "auto"}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                widthMode: e.target.value as ImageBlockProps["widthMode"],
              } as any)
            }
          >
            <option value="auto">{m.widthModeOptionAuto}</option>
            <option value="fixed">{m.widthModeOptionFixed}</option>
          </select>
        </label>

        {(imageProps.widthMode ?? "auto") === "fixed" && (
          <NumericPropertyControl
            label={m.fixedWidthLabel}
            unitLabel={m.fixedWidthUnitLabel}
            value={imageProps.widthPx ?? 320}
            min={40}
            max={1200}
            step={10}
            presets={[
              { id: "sm", label: m.fixedWidthPresetSmall, value: 240 },
              { id: "md", label: m.fixedWidthPresetMedium, value: 320 },
              { id: "lg", label: m.fixedWidthPresetLarge, value: 480 },
            ]}
            onChangeValue={(v) => {
              updateBlock(selectedBlockId, {
                widthPx: v,
              } as any);
            }}
          />
        )}

        {/* 모서리 둥글기 */}
        <NumericPropertyControl
          label={m.borderRadiusLabel}
          value={(() => {
            if (typeof imageProps.borderRadiusPx === "number") {
              return imageProps.borderRadiusPx;
            }
            const r = imageProps.borderRadius ?? "md";
            // 토큰만 있는 기존 데이터의 경우, 토큰별 대표값으로 초기화한다.
            return r === "none" ? 0 : r === "sm" ? 20 : r === "lg" ? 120 : r === "full" ? 180 : 60;
          })()}
          min={0}
          max={200}
          step={1}
          presets={[
            { id: "none", label: m.borderRadiusPresetNone, value: 0 },
            { id: "sm", label: m.borderRadiusPresetSmall, value: 20 },
            { id: "md", label: m.borderRadiusPresetMedium, value: 60 },
            { id: "lg", label: m.borderRadiusPresetLarge, value: 120 },
            { id: "full", label: m.borderRadiusPresetFull, value: 180 },
          ]}
          onChangeValue={(v) => {
            // 0~50 범위를 토큰으로 매핑한다.
            const nextToken =
              v <= 0 ? "none" : v <= 30 ? "sm" : v <= 90 ? "md" : v <= 150 ? "lg" : "full";
            updateBlock(selectedBlockId, {
              borderRadius: nextToken,
              borderRadiusPx: v,
            } as any);
          }}
        />
      </div>
    </>
  );
}
