'use client';

import { createContext, useContext, useCallback, useEffect, useState, ReactNode } from 'react';

interface BrandingData {
  site_title: string;
  site_primary_color: string;
  site_logo_url: string;
  site_favicon_url: string;
  site_font_family: string;
  site_tagline: string;
}

interface BrandingContextValue {
  branding: BrandingData;
  loaded: boolean;
  refreshBranding: () => Promise<void>;
}

const DEFAULT_BRANDING: BrandingData = {
  site_title: 'RestroAgent',
  site_primary_color: '',
  site_logo_url: '',
  site_favicon_url: '',
  site_font_family: '',
  site_tagline: '',
};

const BrandingContext = createContext<BrandingContextValue>({
  branding: DEFAULT_BRANDING,
  loaded: false,
  refreshBranding: async () => {},
});

function hexToHslString(hex: string): string | null {
  const m = hex.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
  if (!m) return null;
  let r = parseInt(m[1], 16) / 255;
  let g = parseInt(m[2], 16) / 255;
  let b = parseInt(m[3], 16) / 255;
  const max = Math.max(r, g, b), min = Math.min(r, g, b);
  let h = 0, s = 0;
  const l = (max + min) / 2;
  if (max !== min) {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
      case g: h = ((b - r) / d + 2) / 6; break;
      default: h = ((r - g) / d + 4) / 6; break;
    }
  }
  return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
}

function applyBrandingToDOM(merged: BrandingData) {
  if (merged.site_primary_color) {
    const hsl = hexToHslString(merged.site_primary_color);
    if (hsl) document.documentElement.style.setProperty('--primary', hsl);
  }
  if (merged.site_title) {
    document.title = merged.site_title;
  }
  if (merged.site_favicon_url) {
    let link = document.querySelector<HTMLLinkElement>('link[rel="icon"]');
    if (!link) {
      link = document.createElement('link');
      link.rel = 'icon';
      document.head.appendChild(link);
    }
    link.href = merged.site_favicon_url;
  }
  if (merged.site_font_family) {
    const family = merged.site_font_family;
    const existingFontLink = document.getElementById('ra-brand-font') as HTMLLinkElement | null;
    if (!existingFontLink) {
      const fontLink = document.createElement('link');
      fontLink.id = 'ra-brand-font';
      fontLink.rel = 'stylesheet';
      fontLink.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family)}:wght@400;500;600;700&display=swap`;
      document.head.appendChild(fontLink);
    } else if (!existingFontLink.href.includes(encodeURIComponent(family))) {
      existingFontLink.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family)}:wght@400;500;600;700&display=swap`;
    }
    const fontStack = `'${family}', sans-serif`;
    document.documentElement.style.fontFamily = fontStack;
    document.body.style.fontFamily = fontStack;
  }
}

export function BrandingProvider({ children }: { children: ReactNode }) {
  const [branding, setBranding] = useState<BrandingData>(DEFAULT_BRANDING);
  const [loaded, setLoaded] = useState(false);

  const fetchBranding = useCallback(async () => {
    try {
      const r = await fetch('/api/public/branding');
      const data = await r.json() as { branding: Record<string, string> };
      const b = data.branding ?? {};
      const merged: BrandingData = {
        site_title: b.site_title || DEFAULT_BRANDING.site_title,
        site_primary_color: b.site_primary_color || '',
        site_logo_url: b.site_logo_url || '',
        site_favicon_url: b.site_favicon_url || '',
        site_font_family: b.site_font_family || '',
        site_tagline: b.site_tagline || '',
      };
      setBranding(merged);
      applyBrandingToDOM(merged);
      setLoaded(true);
    } catch {
      setLoaded(true);
    }
  }, []);

  useEffect(() => {
    fetchBranding();
  }, [fetchBranding]);

  return (
    <BrandingContext.Provider value={{ branding, loaded, refreshBranding: fetchBranding }}>
      {children}
    </BrandingContext.Provider>
  );
}

export function useBranding(): BrandingContextValue {
  return useContext(BrandingContext);
}
