"use client";

import React, { createContext, useContext, useMemo } from "react";
import { hexToOklch, getContrastText, generatePrimaryShades } from "./colors";

export interface ThemeProviderProps {
  children: React.ReactNode;
  /** Tenant primary brand color (hex). Default: WealthX green */
  primary?: string;
  /** Tenant secondary brand color (hex). Default: WealthX dark navy */
  secondary?: string;
  /** Tenant font family override. Default: Figtree */
  fontFamily?: string;
  /** Disable CSS variable injection (e.g. for SSR with static CSS) */
  injectCssVariables?: boolean;
}

/**
 * React context that stores the computed theme CSS variables.
 *
 * Portal-rendered components (Dialog, AlertDialog, Popover, Tooltip, etc.)
 * escape the DOM subtree of the ThemeProvider wrapper \<div\>, so they lose
 * the scoped CSS custom properties set via inline styles. Components that
 * render inside a portal consume this context and re-apply the variables
 * on their outermost portal element, restoring the theme cascade.
 */
const ThemeVarsContext = createContext<Record<string, string>>({});

/**
 * Returns the theme CSS variables from the nearest ThemeProvider.
 * Portal-based components use this to re-apply scoped theme vars
 * on content rendered outside the ThemeProvider's DOM subtree.
 */
export function useThemeVars(): Record<string, string> {
  return useContext(ThemeVarsContext);
}

const DEFAULT_PRIMARY = "#33FF99";
const DEFAULT_SECONDARY = "#162029";
const DEFAULT_FONT =
  '"Figtree", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"';

/**
 * WealthX ThemeProvider — injects tenant brand colors as scoped CSS variables.
 *
 * How it works:
 * 1. Takes primary/secondary hex colors from tenant config
 * 2. Converts to oklch() (matching globals.css format)
 * 3. Auto-computes WCAG contrast text for each via WCAG luminance
 * 4. Sets CSS custom properties as inline styles on a wrapper \<div\>,
 *    scoped to this subtree (inherited by children via CSS cascade).
 *    This allows multiple ThemeProviders on the same page with different colors.
 *
 * Usage:
 *   \<ThemeProvider primary="#FF6600" secondary="#1A1A2E"\>
 *     \<App /\>
 *   \</ThemeProvider\>
 */
export function ThemeProvider({
  children,
  primary = DEFAULT_PRIMARY,
  secondary = DEFAULT_SECONDARY,
  fontFamily = DEFAULT_FONT,
  injectCssVariables = true,
}: ThemeProviderProps): React.ReactElement {
  const vars = useMemo(() => {
    if (!injectCssVariables) return {} as Record<string, string>;

    const primaryOklch = hexToOklch(primary);
    const primaryFgOklch = hexToOklch(getContrastText(primary));
    const secondaryOklch = hexToOklch(secondary);
    const secondaryFgOklch = hexToOklch(getContrastText(secondary));

    return {
      // Brand primary — used by buttons, links, focus rings, active states
      "--primary": primaryOklch,
      "--primary-foreground": primaryFgOklch,
      "--ring": primaryOklch,

      // Sidebar uses primary for active navigation
      "--sidebar-primary": primaryOklch,
      "--sidebar-primary-foreground": primaryFgOklch,

      // Brand secondary — tenant navy used by Secondary button variant
      // NOTE: --secondary is reserved for paper/surface (#F5F8FA), so we use --brand-secondary
      "--brand-secondary": secondaryOklch,
      "--brand-secondary-foreground": secondaryFgOklch,

      // Font family — applies to all components + typography utility classes
      "--font-sans": fontFamily,
      "--font-family-sans": fontFamily,

      // Legacy compat (used by existing WealthX apps)
      "--theme-primary": primary,
      "--theme-secondary": secondary,

      // Primary shade palette (50–950) — Tailwind-style, tenant-adaptive.
      // Defined here so they react to tenant theme switches.
      // Referenced as var(--primary-50) … var(--primary-950) in components.
      ...generatePrimaryShades(primary),

      // Pipeline stage palette — maps stage slots to primary shades.
      // stage-1 = darkest visible, stage-5 = lightest visible on white bg.
      "--color-stage-1": `var(--primary-600)`,
      "--color-stage-2": `var(--primary-400)`,
      "--color-stage-3": `var(--primary-300)`,
      "--color-stage-4": `var(--primary-200)`,
      "--color-stage-5": `var(--primary-100)`,
      // WCAG-computed contrast text for any primary-shaded background
      "--color-stage-fg": primaryFgOklch,
    };
  }, [primary, secondary, fontFamily, injectCssVariables]);

  return (
    <ThemeVarsContext.Provider value={vars}>
      <div data-wealthx-theme style={vars as React.CSSProperties}>
        {children}
      </div>
    </ThemeVarsContext.Provider>
  );
}

/**
 * Build CSS variables object for SSR or static contexts.
 * Returns a flat Record\<string, string\> that can be serialized to a \<style\> tag.
 */
export function buildCssVariables(options: {
  primary?: string;
  secondary?: string;
  fontFamily?: string;
}): Record<string, string> {
  const primary = options.primary ?? DEFAULT_PRIMARY;
  const secondary = options.secondary ?? DEFAULT_SECONDARY;
  const fontFamily = options.fontFamily ?? DEFAULT_FONT;

  return {
    "--primary": hexToOklch(primary),
    "--primary-foreground": hexToOklch(getContrastText(primary)),
    "--ring": hexToOklch(primary),
    "--sidebar-primary": hexToOklch(primary),
    "--sidebar-primary-foreground": hexToOklch(getContrastText(primary)),
    "--brand-secondary": hexToOklch(secondary),
    "--brand-secondary-foreground": hexToOklch(getContrastText(secondary)),
    "--font-sans": fontFamily,
    "--font-family-sans": fontFamily,
    "--theme-primary": primary,
    "--theme-secondary": secondary,
  };
}
