"use client";

import {
  useEffect,
  useMemo,
  useState,
  type CSSProperties,
  type ChangeEvent,
} from "react";
import { getVideoAttributionText } from "@/lib/branding";
import {
  CURATED_FONTS,
  googleFontsStylesheetUrl,
  SYSTEM_FONT,
  type CuratedFontKey,
  type WatermarkFontKey,
} from "@/lib/fonts";
import {
  curatedFontApiUrl,
  previewFontFamilyCss,
} from "@/lib/preview-typography";
import {
  WATERMARK_OFFSET_MAX,
  WATERMARK_OFFSET_MIN,
  WATERMARK_POSITIONS,
  WATERMARK_TEXT_MAX,
  type WatermarkMode,
  type WatermarkPosition,
  type WatermarkSettings,
} from "@/lib/watermark";

type Props = {
  enabled: boolean;
  locked: boolean;
  previewImageUrl: string | null;
  value: WatermarkSettings;
  onChange: (next: WatermarkSettings) => void;
  onUploadLogo: (file: File) => Promise<string>;
  onUploadFont: (file: File) => Promise<string>;
  logoPreviewUrl?: string | null;
};

const POSITION_LABELS: Record<WatermarkPosition, string> = {
  "top-left": "Top left",
  "top-right": "Top right",
  "bottom-left": "Bottom left",
  "bottom-right": "Bottom right",
  center: "Center",
};

const CUSTOM_PREVIEW_FAMILY = "S2VIDCustomWm";

function previewStyle(
  position: WatermarkPosition,
  offsetX: number,
  offsetY: number,
): CSSProperties {
  const base: CSSProperties = {
    position: "absolute",
    maxWidth: "32%",
    pointerEvents: "none",
  };
  const ox = `${offsetX}px`;
  const oy = `${offsetY}px`;
  switch (position) {
    case "top-left":
      return { ...base, top: oy, left: ox };
    case "top-right":
      return { ...base, top: oy, right: ox };
    case "bottom-left":
      return { ...base, bottom: oy, left: ox };
    case "center":
      return {
        ...base,
        top: "50%",
        left: "50%",
        transform: `translate(calc(-50% + ${offsetX}px), calc(-50% + ${offsetY}px))`,
      };
    case "bottom-right":
    default:
      return { ...base, bottom: oy, right: ox };
  }
}

function previewFontFamily(fontKey: WatermarkFontKey | undefined): string {
  return previewFontFamilyCss(fontKey);
}

export function WatermarkPreview({
  enabled,
  locked,
  previewImageUrl,
  value,
  onChange,
  onUploadLogo,
  onUploadFont,
  logoPreviewUrl,
}: Props) {
  const [logoUploading, setLogoUploading] = useState(false);
  const [logoError, setLogoError] = useState<string | null>(null);
  const [fontUploading, setFontUploading] = useState(false);
  const [fontError, setFontError] = useState<string | null>(null);
  const [customFontObjectUrl, setCustomFontObjectUrl] = useState<string | null>(null);

  const overlay = useMemo(
    () => previewStyle(value.position, value.offsetX, value.offsetY),
    [value.position, value.offsetX, value.offsetY],
  );

  const textFontStyle = useMemo(
    () => ({ fontFamily: previewFontFamily(value.fontKey) }),
    [value.fontKey],
  );

  // Load bundled + curated fonts for live canvas preview (same files as FFmpeg)
  useEffect(() => {
    const styleId = "s2vid-watermark-preview-fonts";
    let el = document.getElementById(styleId) as HTMLStyleElement | null;
    if (!el) {
      el = document.createElement("style");
      el.id = styleId;
      document.head.appendChild(el);
    }
    el.textContent = [
      `@font-face {
  font-family: '${SYSTEM_FONT.previewFamily}';
  src: url('${curatedFontApiUrl(SYSTEM_FONT.key)}') format('truetype');
  font-display: swap;
}`,
      ...CURATED_FONTS.map(
        (f) => `@font-face {
  font-family: 'S2VIDPreview-${f.key}';
  src: url('${curatedFontApiUrl(f.key)}') format('truetype');
  font-display: swap;
}`,
      ),
    ].join("\n");
  }, []);

  // Legacy Google Fonts link (kept for any older preview paths)
  useEffect(() => {
    const id = "s2vid-watermark-google-fonts";
    if (document.getElementById(id)) return;
    const link = document.createElement("link");
    link.id = id;
    link.rel = "stylesheet";
    link.href = googleFontsStylesheetUrl(CURATED_FONTS.map((f) => f.key));
    document.head.appendChild(link);
  }, []);

  // @font-face for uploaded custom font (browser preview only)
  useEffect(() => {
    if (!customFontObjectUrl) return;
    const styleId = "s2vid-watermark-custom-font";
    let el = document.getElementById(styleId) as HTMLStyleElement | null;
    if (!el) {
      el = document.createElement("style");
      el.id = styleId;
      document.head.appendChild(el);
    }
    el.textContent = `
@font-face {
  font-family: '${CUSTOM_PREVIEW_FAMILY}';
  src: url('${customFontObjectUrl}');
  font-display: swap;
}`;
    return () => {
      /* keep style until next custom font replaces it */
    };
  }, [customFontObjectUrl]);

  useEffect(() => {
    return () => {
      if (customFontObjectUrl) URL.revokeObjectURL(customFontObjectUrl);
    };
  }, [customFontObjectUrl]);

  function patch(partial: Partial<WatermarkSettings>) {
    if (locked) return;
    onChange({ ...value, ...partial });
  }

  async function handleLogo(e: ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file || locked) return;
    setLogoError(null);
    setLogoUploading(true);
    try {
      const path = await onUploadLogo(file);
      patch({ mode: "logo", logoPath: path });
    } catch (err) {
      setLogoError(err instanceof Error ? err.message : "Logo upload failed");
    } finally {
      setLogoUploading(false);
    }
  }

  async function handleFont(e: ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file || locked) return;
    setFontError(null);
    setFontUploading(true);
    try {
      const objectUrl = URL.createObjectURL(file);
      if (customFontObjectUrl) URL.revokeObjectURL(customFontObjectUrl);
      setCustomFontObjectUrl(objectUrl);
      const path = await onUploadFont(file);
      patch({ mode: "text", fontKey: "custom", fontPath: path });
    } catch (err) {
      setFontError(err instanceof Error ? err.message : "Font upload failed");
    } finally {
      setFontUploading(false);
    }
  }

  function setFontKey(key: WatermarkFontKey) {
    if (key === "custom") {
      patch({ fontKey: "custom", fontPath: value.fontPath ?? null });
      return;
    }
    patch({ fontKey: key, fontPath: null });
  }

  return (
    <div
      className={`relative rounded-lg border border-gray-700 bg-surface p-6 ${
        locked ? "opacity-80" : ""
      }`}
    >
      <div className="mb-4 flex flex-wrap items-center gap-2">
        <h3 className="text-lg font-medium text-white">Watermark layout</h3>
      </div>

      <div
        className="relative mx-auto aspect-video w-full max-w-xl overflow-hidden rounded border border-gray-800 bg-black"
        aria-hidden={locked}
      >
        {previewImageUrl ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={previewImageUrl} alt="" className="h-full w-full object-contain" />
        ) : (
          <div className="flex h-full items-center justify-center text-sm text-gray-600">
            Upload a cover image to preview
          </div>
        )}

        {enabled && value.mode !== "none" && (
          <div style={overlay} className="rounded bg-black/40 px-2 py-1">
            {value.mode === "logo" && logoPreviewUrl ? (
              // eslint-disable-next-line @next/next/no-img-element
              <img src={logoPreviewUrl} alt="" className="max-h-16 w-auto object-contain" />
            ) : (
              <span
                className="text-[11px] font-medium text-white/90 drop-shadow"
                style={value.mode === "text" ? textFontStyle : undefined}
              >
                {value.mode === "text" && value.text?.trim()
                  ? value.text.trim().slice(0, WATERMARK_TEXT_MAX)
                  : getVideoAttributionText()}
              </span>
            )}
          </div>
        )}
      </div>

      <div className="mt-4 space-y-4" aria-disabled={locked}>
        <div className="flex flex-wrap gap-2">
          {(
            [
              ["none", "No watermark"],
              ["default", "Songs2VID badge"],
              ["text", "Custom text"],
              ["logo", "PNG logo"],
            ] as const
          ).map(([mode, label]) => (
            <button
              key={mode}
              type="button"
              disabled={locked}
              onClick={() => patch({ mode: mode as WatermarkMode })}
              className={`rounded border px-3 py-1.5 text-xs font-medium transition-colors ${
                value.mode === mode
                  ? "border-accent bg-accent/15 text-accent"
                  : "border-gray-700 text-gray-400 hover:border-gray-500"
              } disabled:cursor-not-allowed`}
            >
              {label}
            </button>
          ))}
        </div>

        {value.mode === "text" && (
          <>
            <label className="block text-sm text-gray-400">
              Watermark text
              <input
                type="text"
                maxLength={WATERMARK_TEXT_MAX}
                disabled={locked}
                value={value.text ?? ""}
                onChange={(e) => patch({ text: e.target.value })}
                className="input-field mt-1"
                placeholder="Your brand name"
              />
            </label>

            <label className="block text-sm text-gray-400">
              Font
              <select
                disabled={locked}
                value={value.fontKey ?? "system"}
                onChange={(e) => setFontKey(e.target.value as WatermarkFontKey)}
                className="input-field mt-1"
              >
                <option value="system">{SYSTEM_FONT.label}</option>
                {CURATED_FONTS.map((f) => (
                  <option key={f.key} value={f.key} style={{ fontFamily: f.cssFamily }}>
                    {f.label}
                  </option>
                ))}
                <option value="custom">Custom upload (.ttf / .otf)</option>
              </select>
            </label>

            {(value.fontKey === "custom" ||
              (value.fontKey &&
                value.fontKey !== "system" &&
                CURATED_FONTS.some((f) => f.key === (value.fontKey as CuratedFontKey)))) && (
              <p className="text-xs text-gray-500" style={textFontStyle}>
                Preview: The quick brown fox jumps over the lazy dog
              </p>
            )}

            {value.fontKey === "custom" && (
              <div>
                <label className="mb-1 block text-sm text-gray-400">
                  Upload font (.ttf or .otf, max 10 MB)
                </label>
                <input
                  type="file"
                  accept=".ttf,.otf,font/ttf,font/otf"
                  disabled={locked || fontUploading}
                  onChange={(e) => void handleFont(e)}
                  className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white"
                />
                {fontUploading && (
                  <p className="mt-1 text-xs text-yellow-400">Uploading font…</p>
                )}
                {fontError && <p className="mt-1 text-xs text-red-400">{fontError}</p>}
                {value.fontPath && !fontError && (
                  <p className="mt-1 text-xs text-green-400">Custom font ready for render</p>
                )}
              </div>
            )}
          </>
        )}

        {value.mode === "logo" && (
          <div>
            <label className="mb-1 block text-sm text-gray-400">PNG logo</label>
            <input
              type="file"
              accept="image/png,.png"
              disabled={locked || logoUploading}
              onChange={(e) => void handleLogo(e)}
              className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white"
            />
            {logoUploading && <p className="mt-1 text-xs text-yellow-400">Uploading logo…</p>}
            {logoError && <p className="mt-1 text-xs text-red-400">{logoError}</p>}
          </div>
        )}

        <div>
          <p className="mb-2 text-sm text-gray-400">Position</p>
          <div className="grid grid-cols-3 gap-2 sm:grid-cols-5">
            {WATERMARK_POSITIONS.map((pos) => (
              <button
                key={pos}
                type="button"
                disabled={locked || value.mode === "none"}
                onClick={() => patch({ position: pos })}
                className={`rounded border px-2 py-2 text-[11px] font-medium ${
                  value.position === pos
                    ? "border-accent bg-accent/15 text-accent"
                    : "border-gray-700 text-gray-400"
                } disabled:opacity-40`}
              >
                {POSITION_LABELS[pos]}
              </button>
            ))}
          </div>
        </div>

        <div className="grid gap-3 sm:grid-cols-2">
          <label className="text-sm text-gray-400">
            Offset X ({value.offsetX}px)
            <input
              type="range"
              min={WATERMARK_OFFSET_MIN}
              max={WATERMARK_OFFSET_MAX}
              disabled={locked || value.mode === "none"}
              value={value.offsetX}
              onChange={(e) => patch({ offsetX: Number(e.target.value) })}
              className="mt-1 w-full"
            />
          </label>
          <label className="text-sm text-gray-400">
            Offset Y ({value.offsetY}px)
            <input
              type="range"
              min={WATERMARK_OFFSET_MIN}
              max={WATERMARK_OFFSET_MAX}
              disabled={locked || value.mode === "none"}
              value={value.offsetY}
              onChange={(e) => patch({ offsetY: Number(e.target.value) })}
              className="mt-1 w-full"
            />
          </label>
        </div>
      </div>
    </div>
  );
}
