import type {RadiusId, ThemeId} from "./theme-values";
import type {StaticImageData} from "next/image";

import {env} from "~env";

import airbnbTheme from "@/assets/themes/airbnb.png";
import blackTheme from "@/assets/themes/black.png";
import coinbaseTheme from "@/assets/themes/coinbase.png";
import defaultTheme from "@/assets/themes/default.png";
import discordTheme from "@/assets/themes/discord.png";
import lavenderTheme from "@/assets/themes/lavender.png";
import mintTheme from "@/assets/themes/mint.png";
import netflixTheme from "@/assets/themes/netflix.png";
import rabbitTheme from "@/assets/themes/rabbit.png";
import skyTheme from "@/assets/themes/sky.png";
import spotifyTheme from "@/assets/themes/spotify.png";

import {DEFAULT_BASE} from "./theme-values";

export type {
  RadiusId,
  SemanticColorOverride,
  ThemeId,
  ThemeSemanticOverrides,
  ThemeValues,
} from "./theme-values";
export {
  DEFAULT_BASE,
  findMatchingTheme,
  radiusIds,
  themeComparisonKeys,
  themeIds,
  themeValuesById,
} from "./theme-values";

export const tabLabels = ["components", "dashboard", "mail", "chat", "finances"] as const;

export type TabLabel = (typeof tabLabels)[number];

export const tabs = tabLabels.map((label) => ({disabled: false, label}));

export const HEROUI_PRO_URL = env.NEXT_PUBLIC_PRO_URL ?? "https://heroui.pro";

export const iframeTabs: Record<string, string> = {
  chat: `${HEROUI_PRO_URL}/templates/chat`,
  dashboard: `${HEROUI_PRO_URL}/templates/dashboard`,
  finances: `${HEROUI_PRO_URL}/templates/finances`,
  mail: `${HEROUI_PRO_URL}/templates/email`,
};

/**
 * Adaptive colors that need different values in light vs dark modes.
 * Maps a color ID to its light and dark mode variants.
 */
export const adaptiveColors: Record<string, {light: string; dark: string}> = {
  "oklch(0 0 0)": {
    dark: "oklch(0.9848 0 0)",
    light: "oklch(0 0 0)",
  },
};

export const fontIds = [
  "inter",
  "figtree",
  "hanken-grotesk",
  "geist",
  "dm-sans",
  "public-sans",
  "google-sans",
  "bricolage-grotesque",
  "varela-round",
  "fraunces",
  "ibm-plex-mono",
  "fredoka",
  "jetbrains-mono",
  "instrument-sans",
] as const;

export type FontConfig = {
  id: (typeof fontIds)[number];
  label: string;
  variable: string;
  /** Google Fonts CDN URL for on-demand loading */
  cdnUrl: string;
};

export const fonts: FontConfig[] = [
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap",
    id: "inter",
    label: "Inter",
    variable: "--font-inter",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Figtree:wght@300..900&display=swap",
    id: "figtree",
    label: "Figtree",
    variable: "--font-figtree",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@100..900&display=swap",
    id: "hanken-grotesk",
    label: "Hanken Grotesk",
    variable: "--font-hanken-grotesk",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap",
    id: "geist",
    label: "Geist",
    variable: "--font-geist",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=DM+Sans:wght@100..900&display=swap",
    id: "dm-sans",
    label: "DM Sans",
    variable: "--font-dm-sans",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Public+Sans:wght@100..900&display=swap",
    id: "public-sans",
    label: "Public Sans",
    variable: "--font-public-sans",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Google+Sans:wght@100..900&display=swap",
    id: "google-sans",
    label: "Google Sans",
    variable: "--font-google-sans",
  },
  {
    cdnUrl:
      "https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@200..800&display=swap",
    id: "bricolage-grotesque",
    label: "Bricolage Grotesque",
    variable: "--font-bricolage-grotesque",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Varela+Round&display=swap",
    id: "varela-round",
    label: "Varela Round",
    variable: "--font-varela-round",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Fraunces:wght@100..900&display=swap",
    id: "fraunces",
    label: "Fraunces",
    variable: "--font-fraunces",
  },
  {
    cdnUrl:
      "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap",
    id: "ibm-plex-mono",
    label: "IBM Plex Mono",
    variable: "--font-ibm-plex-mono",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Fredoka:wght@300..700&display=swap",
    id: "fredoka",
    label: "Fredoka",
    variable: "--font-fredoka",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@100..800&display=swap",
    id: "jetbrains-mono",
    label: "JetBrains Mono",
    variable: "--font-jetbrains-mono",
  },
  {
    cdnUrl: "https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400..700&display=swap",
    id: "instrument-sans",
    label: "Instrument Sans",
    variable: "--font-instrument-sans",
  },
];

/** Map font ID to font info for quick lookup */
export const fontMap = Object.fromEntries(fonts.map((f) => [f.id, f])) as Record<
  (typeof fontIds)[number],
  FontConfig
>;

export const radiusOptions: Array<{
  cssValue: string;
  description: string;
  id: RadiusId;
  label: string;
}> = [
  {cssValue: "0", description: "none", id: "none", label: "-"},
  {cssValue: "0.125rem", description: "extra small", id: "extra-small", label: "XS"},
  {cssValue: "0.25rem", description: "small", id: "small", label: "S"},
  {cssValue: "0.5rem", description: "medium", id: "medium", label: "M"},
  {cssValue: "0.75rem", description: "large", id: "large", label: "L"},
];
export const formRadiusOptions: Array<{
  cssValue: string;
  description: string;
  id: RadiusId;
  label: string;
}> = [
  {cssValue: "0", description: "none", id: "none", label: "-"},
  {cssValue: "0.125rem", description: "extra small", id: "extra-small", label: "XS"},
  {cssValue: "0.25rem", description: "small", id: "small", label: "S"},
  {cssValue: "0.5rem", description: "medium", id: "medium", label: "M"},
  {cssValue: "0.75rem", description: "large", id: "large", label: "L"},
  {cssValue: "1rem", description: "extra large", id: "extra-large", label: "XL"},
];

/** Map radius ID to CSS value for quick lookup */
export const radiusCssMap = Object.fromEntries(
  formRadiusOptions.map((r) => [r.id, r.cssValue]),
) as Record<(typeof formRadiusOptions)[number]["id"], string>;

export const themes: Array<{
  id: ThemeId;
  image: StaticImageData;
  label: string;
}> = [
  {id: "default", image: defaultTheme, label: "Default"},
  {id: "sky", image: skyTheme, label: "Sky"},
  {id: "lavender", image: lavenderTheme, label: "Lavender"},
  {id: "mint", image: mintTheme, label: "Mint"},
  {id: "netflix", image: netflixTheme, label: "Netflix"},
  {id: "uber", image: blackTheme, label: "Uber"},
  {id: "spotify", image: spotifyTheme, label: "Spotify"},
  {id: "coinbase", image: coinbaseTheme, label: "Coinbase"},
  {id: "airbnb", image: airbnbTheme, label: "Airbnb"},
  {id: "discord", image: discordTheme, label: "Discord"},
  {id: "rabbit", image: rabbitTheme, label: "Rabbit"},
];

export type ThemeVariables = {
  lightness: number;
  chroma: number;
  hue: number;
  base: number;
  /** Font family - can be a predefined fontId or a custom font ID (prefixed with "custom-") */
  fontFamily: (typeof fontIds)[number] | string;
  formRadius: RadiusId;
  radius: RadiusId;
  /** Use vibrant (more saturated) soft foreground colors instead of accessible defaults */
  vibrantPalette?: boolean;
};

export const themeVariableKeys = [
  "base",
  "lightness",
  "chroma",
  "hue",
  "fontFamily",
  "formRadius",
  "radius",
] as const satisfies readonly (keyof ThemeVariables)[];

/** Theme variable keys that can be locked (excludes booleans like `vibrantPalette`). */
export type LockableThemeVariableKey = (typeof themeVariableKeys)[number];

export const defaultThemeVariables: ThemeVariables = {
  base: DEFAULT_BASE,
  chroma: 0.195,
  fontFamily: "inter",
  formRadius: "large",
  hue: 253.83,
  lightness: 0.6204,
  radius: "medium",
} as const;

export const LOCAL_STORAGE_KEYS = {
  SHUFFLE_WARNING_SHOWN: "shuffle-warning-shown",
} as const;

export const THEME_BUILDER_CONTENT_ID = "theme-builder-content";
export const THEME_BUILDER_PAGE_ID = "theme-builder-page";
export const THEME_BUILDER_BOTTOM_SHEET_ID = "theme-builder-bottom-sheet";
