import type { CSSProperties } from "react";
import type { StoreSiteTheme } from "@alqove/api-client";

/**
 * A store's theme is seller-authored, so nothing here trusts it blindly: every
 * value is validated against a known set (or a hex pattern) before it reaches
 * the DOM as a CSS custom property.
 */

export const DEFAULT_THEME = {
  primary_color: "#065f46",
  accent_color: "#f59e0b",
  background_color: "#ffffff",
  text_color: "#0f172a",
  font: "sans",
  corner_radius: "md",
  header_style: "solid",
} as const;

const HEX = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;

const FONT_STACKS: Record<string, string> = {
  sans: "var(--font-dm-sans), ui-sans-serif, system-ui, sans-serif",
  serif: "ui-serif, Georgia, Cambria, 'Times New Roman', serif",
  mono: "var(--font-jetbrains-mono), ui-monospace, monospace",
};

const RADII: Record<string, string> = {
  none: "0px",
  sm: "2px",
  md: "6px",
  lg: "14px",
};

export type HeaderStyle = "solid" | "transparent" | "minimal";

function color(value: string | undefined, fallback: string): string {
  return value && HEX.test(value) ? value : fallback;
}

/**
 * Relative luminance per WCAG, used to pick readable text over a seller-chosen
 * background. A store that picks a pale primary still gets legible buttons.
 */
export function readableTextOn(hex: string): string {
  const normalized = hex.replace("#", "");
  const full =
    normalized.length === 3
      ? normalized
          .split("")
          .map((c) => c + c)
          .join("")
      : normalized;

  if (full.length !== 6) return "#ffffff";

  const channels = [0, 2, 4].map((i) => {
    const srgb = parseInt(full.slice(i, i + 2), 16) / 255;
    return srgb <= 0.03928 ? srgb / 12.92 : ((srgb + 0.055) / 1.055) ** 2.4;
  });

  const luminance =
    0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2];

  return luminance > 0.55 ? "#0f172a" : "#ffffff";
}

export function headerStyle(theme: StoreSiteTheme | null | undefined): HeaderStyle {
  const value = theme?.header_style;
  return value === "transparent" || value === "minimal" ? value : "solid";
}

/**
 * Theme → CSS custom properties. Applied once on the storefront wrapper so
 * every block styles itself off `var(--sf-*)` rather than re-reading the theme.
 */
export function themeToCssVars(theme: StoreSiteTheme | null | undefined): CSSProperties {
  const primary = color(theme?.primary_color, DEFAULT_THEME.primary_color);
  const accent = color(theme?.accent_color, DEFAULT_THEME.accent_color);
  const background = color(theme?.background_color, DEFAULT_THEME.background_color);
  const text = color(theme?.text_color, DEFAULT_THEME.text_color);

  const font = FONT_STACKS[theme?.font ?? ""] ?? FONT_STACKS.sans;
  const radius = RADII[theme?.corner_radius ?? ""] ?? RADII.md;

  return {
    "--sf-primary": primary,
    "--sf-on-primary": readableTextOn(primary),
    "--sf-accent": accent,
    "--sf-on-accent": readableTextOn(accent),
    "--sf-bg": background,
    "--sf-text": text,
    "--sf-muted": `color-mix(in srgb, ${text} 62%, ${background})`,
    "--sf-border": `color-mix(in srgb, ${text} 14%, ${background})`,
    "--sf-surface": `color-mix(in srgb, ${text} 4%, ${background})`,
    "--sf-font": font,
    "--sf-radius": radius,
    backgroundColor: "var(--sf-bg)",
    color: "var(--sf-text)",
    fontFamily: "var(--sf-font)",
  } as CSSProperties;
}
