import React from 'react';
import { Navigate, Outlet, useParams } from 'react-router-dom';
import { LocaleProvider } from '@/shared/guest/i18n/LocaleContext';
import { DEFAULT_LOCALE, isLocaleCode } from '@/shared/guest/i18n/messages';
import { NotificationCenterProvider } from '@/shared/guest/context/NotificationCenterContext';
import { EventBrandingProvider } from '@/shared/guest/context/EventBrandingContext';
import { EventDataProvider, useEventData } from '../context/EventDataContext';
import { GuestIdentityProvider, useOptionalGuestIdentity } from '../context/GuestIdentityContext';
import { mapEventBranding } from '../lib/eventBranding';
import { BrandingTheme } from '../lib/brandingTheme';

type EventLayoutProps = {
  tasksEnabledFallback?: boolean;
  requireProfile?: boolean;
};

export default function EventLayout({ tasksEnabledFallback = true, requireProfile = false }: EventLayoutProps) {
  const { token } = useParams<{ token: string }>();

  return (
    <EventDataProvider token={token} tasksEnabledFallback={tasksEnabledFallback}>
      <EventProviders token={token} requireProfile={requireProfile}>
        <Outlet />
      </EventProviders>
    </EventDataProvider>
  );
}

function EventProviders({
  token,
  children,
  requireProfile,
}: {
  token?: string;
  children: React.ReactNode;
  requireProfile: boolean;
}) {
  const { event } = useEventData();
  const eventLocale = event && isLocaleCode(event.default_locale) ? event.default_locale : DEFAULT_LOCALE;
  const localeStorageKey = event
    ? `guestLocale_event_${event.id ?? token ?? 'global'}`
    : `guestLocale_event_${token ?? 'global'}`;
  const branding = mapEventBranding(
    event?.branding ?? (event as unknown as { settings?: { branding?: any } })?.settings?.branding ?? null
  );

  const content = (
    <EventBrandingProvider branding={branding}>
      <LocaleProvider defaultLocale={eventLocale} storageKey={localeStorageKey}>
        <GuestIdentityProvider eventKey={token ?? ''}>
          <BrandingTheme>
            {requireProfile ? <ProfileGate token={token}>{children}</ProfileGate> : children}
          </BrandingTheme>
        </GuestIdentityProvider>
      </LocaleProvider>
    </EventBrandingProvider>
  );

  if (!token) {
    return content;
  }

  return <NotificationCenterProvider eventToken={token}>{content}</NotificationCenterProvider>;
}

function ProfileGate({ token, children }: { token?: string; children: React.ReactNode }) {
  const identity = useOptionalGuestIdentity();

  if (token && identity?.hydrated && !identity.name) {
    return <Navigate to={`/setup/${encodeURIComponent(token)}`} replace />;
  }

  return <>{children}</>;
}
