import React, { createContext, useContext, useEffect, useMemo } from 'react';
import type { EventBranding } from '../types/event-branding';

type EventBrandingContextValue = {
  branding: EventBranding;
  isCustom: boolean;
};

export const DEFAULT_EVENT_BRANDING: EventBranding = {
  primaryColor: '#f43f5e',
  secondaryColor: '#fb7185',
  backgroundColor: '#ffffff',
  fontFamily: null,
  logoUrl: null,
};
const DEFAULT_PRIMARY = DEFAULT_EVENT_BRANDING.primaryColor.toLowerCase();
const DEFAULT_SECONDARY = DEFAULT_EVENT_BRANDING.secondaryColor.toLowerCase();
const DEFAULT_BACKGROUND = DEFAULT_EVENT_BRANDING.backgroundColor.toLowerCase();

const EventBrandingContext = createContext<EventBrandingContextValue | undefined>(undefined);

function normaliseHexColor(value: string | null | undefined, fallback: string): string {
  if (typeof value !== 'string') {
    return fallback;
  }

  const trimmed = value.trim();
  return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(trimmed) ? trimmed : fallback;
}

function resolveBranding(input?: EventBranding | null): EventBranding {
  if (!input) {
    return DEFAULT_EVENT_BRANDING;
  }

  return {
    primaryColor: normaliseHexColor(input.primaryColor, DEFAULT_EVENT_BRANDING.primaryColor),
    secondaryColor: normaliseHexColor(input.secondaryColor, DEFAULT_EVENT_BRANDING.secondaryColor),
    backgroundColor: normaliseHexColor(input.backgroundColor, DEFAULT_EVENT_BRANDING.backgroundColor),
    fontFamily: input.fontFamily?.trim() || null,
    logoUrl: input.logoUrl?.trim() || null,
  };
}

function applyCssVariables(branding: EventBranding) {
  if (typeof document === 'undefined') {
    return;
  }

  const root = document.documentElement;
  root.style.setProperty('--guest-primary', branding.primaryColor);
  root.style.setProperty('--guest-secondary', branding.secondaryColor);
  root.style.setProperty('--guest-background', branding.backgroundColor);

  if (branding.fontFamily) {
    root.style.setProperty('--guest-font-family', branding.fontFamily);
    root.style.setProperty('--guest-heading-font', branding.fontFamily);
  } else {
    root.style.removeProperty('--guest-font-family');
    root.style.removeProperty('--guest-heading-font');
  }
}

function resetCssVariables() {
  if (typeof document === 'undefined') {
    return;
  }

  const root = document.documentElement;
  root.style.removeProperty('--guest-primary');
  root.style.removeProperty('--guest-secondary');
  root.style.removeProperty('--guest-background');
  root.style.removeProperty('--guest-font-family');
  root.style.removeProperty('--guest-heading-font');
}

export function EventBrandingProvider({
  branding,
  children,
}: {
  branding?: EventBranding | null;
  children: React.ReactNode;
}) {
  const resolved = useMemo(() => resolveBranding(branding), [branding]);

  useEffect(() => {
    applyCssVariables(resolved);

    return () => {
      resetCssVariables();
      applyCssVariables(DEFAULT_EVENT_BRANDING);
    };
  }, [resolved]);

  const value = useMemo<EventBrandingContextValue>(() => ({
    branding: resolved,
    isCustom:
      resolved.primaryColor.toLowerCase() !== DEFAULT_PRIMARY
      || resolved.secondaryColor.toLowerCase() !== DEFAULT_SECONDARY
      || resolved.backgroundColor.toLowerCase() !== DEFAULT_BACKGROUND,
  }), [resolved]);

  return <EventBrandingContext.Provider value={value}>{children}</EventBrandingContext.Provider>;
}

export function useEventBranding(): EventBrandingContextValue {
  const context = useContext(EventBrandingContext);

  if (!context) {
    throw new Error('useEventBranding must be used within an EventBrandingProvider');
  }

  return context;
}

export function useOptionalEventBranding(): EventBrandingContextValue | undefined {
  return useContext(EventBrandingContext);
}
