import React from 'react';
import { Button } from '@/components/ui/button';
import { createBrowserRouter, useLocation, useParams, Link, Navigate } from 'react-router-dom';
import Header from './components/Header';
import BottomNav from './components/BottomNav';
import RouteTransition from './components/RouteTransition';
import { useEventData } from './hooks/useEventData';
import { AlertTriangle, Loader2 } from 'lucide-react';
import { EventStatsProvider } from './context/EventStatsContext';
import { GuestIdentityProvider, useOptionalGuestIdentity } from './context/GuestIdentityContext';
import { EventBrandingProvider } from './context/EventBrandingContext';
import { LocaleProvider } from './i18n/LocaleContext';
import { DEFAULT_LOCALE, isLocaleCode } from './i18n/messages';
import { useTranslation, type TranslateFn } from './i18n/useTranslation';
import type { EventBranding } from './types/event-branding';
import type { EventBrandingPayload, FetchEventErrorCode } from './services/eventApi';
import { NotificationCenterProvider } from './context/NotificationCenterContext';
import RouteErrorElement from '@/components/RouteErrorElement';
import { isTaskModeEnabled } from './lib/engagement';

const LandingPage = React.lazy(() => import('./pages/LandingPage'));
const ProfileSetupPage = React.lazy(() => import('./pages/ProfileSetupPage'));
const HomePage = React.lazy(() => import('./pages/HomePage'));
const TaskPickerPage = React.lazy(() => import('./pages/TaskPickerPage'));
const TaskDetailPage = React.lazy(() => import('./pages/TaskDetailPage'));
const UploadPage = React.lazy(() => import('./pages/UploadPage'));
const UploadQueuePage = React.lazy(() => import('./pages/UploadQueuePage'));
const GalleryPage = React.lazy(() => import('./pages/GalleryPage'));
const PhotoLightbox = React.lazy(() => import('./pages/PhotoLightbox'));
const AchievementsPage = React.lazy(() => import('./pages/AchievementsPage'));
const SlideshowPage = React.lazy(() => import('./pages/SlideshowPage'));
const LiveShowPlayerPage = React.lazy(() => import('./pages/LiveShowPlayerPage'));
const SettingsPage = React.lazy(() => import('./pages/SettingsPage'));
const LegalPage = React.lazy(() => import('./pages/LegalPage'));
const HelpCenterPage = React.lazy(() => import('./pages/HelpCenterPage'));
const HelpArticlePage = React.lazy(() => import('./pages/HelpArticlePage'));
const PublicGalleryPage = React.lazy(() => import('./pages/PublicGalleryPage'));
const SharedPhotoPage = React.lazy(() => import('./pages/SharedPhotoPage'));
const NotFoundPage = React.lazy(() => import('./pages/NotFoundPage'));

function HomeLayout() {
  const { token } = useParams();

  if (!token) {
    return (
      <div className="pb-16">
        <Header title="Event" />
        <div className="px-4 py-3">
          <RouteTransition />
        </div>
        <BottomNav />
      </div>
    );
  }

  return (
    <GuestIdentityProvider eventKey={token}>
      <EventBoundary token={token} />
    </GuestIdentityProvider>
  );
}

export const router = createBrowserRouter([
  { path: '/event', element: <SimpleLayout title="Event"><LandingPage /></SimpleLayout>, errorElement: <RouteErrorElement /> },
  { path: '/share/:slug', element: <SharedPhotoPage />, errorElement: <RouteErrorElement /> },
  { path: '/show/:token', element: <LiveShowPlayerPage />, errorElement: <RouteErrorElement /> },
  {
    path: '/setup/:token',
    element: <SetupLayout />, 
    errorElement: <RouteErrorElement />,
    children: [
      { index: true, element: <ProfileSetupPage /> },
    ],
  },
  { path: '/g/:token', element: <PublicGalleryPage />, errorElement: <RouteErrorElement /> },
  {
    path: '/e/:token',
    element: <HomeLayout />,
    errorElement: <RouteErrorElement />,
    children: [
      { index: true, element: <HomePage /> },
      { path: 'tasks', element: <TaskGuard><TaskPickerPage /></TaskGuard> },
      { path: 'tasks/:taskId', element: <TaskGuard><TaskDetailPage /></TaskGuard> },
      { path: 'upload', element: <UploadPage /> },
      { path: 'queue', element: <UploadQueuePage /> },
      { path: 'gallery', element: <GalleryPage /> },
      { path: 'photo/:photoId', element: <PhotoLightbox /> },
      { path: 'achievements', element: <AchievementsPage /> },
      { path: 'slideshow', element: <SlideshowPage /> },
      { path: 'help', element: <HelpCenterPage /> },
      { path: 'help/:slug', element: <HelpArticlePage /> },
    ],
  },
  { path: '/settings', element: <SimpleLayout title="Einstellungen"><SettingsPage /></SimpleLayout>, errorElement: <RouteErrorElement /> },
  { path: '/legal/:page', element: <SimpleLayout title="Rechtliches"><LegalPage /></SimpleLayout>, errorElement: <RouteErrorElement /> },
  { path: '/help', element: <HelpStandalone />, errorElement: <RouteErrorElement /> },
  { path: '/help/:slug', element: <HelpArticleStandalone />, errorElement: <RouteErrorElement /> },
  { path: '*', element: <NotFoundPage />, errorElement: <RouteErrorElement /> },
]);

function EventBoundary({ token }: { token: string }) {
  const identity = useOptionalGuestIdentity();
  const { event, status, error, errorCode } = useEventData();
  const location = useLocation();

  if (status === 'loading') {
    return <EventLoadingView />;
  }

  if (status === 'error' || !event) {
    return <EventErrorView code={errorCode} message={error} />;
  }

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

  const eventLocale = isLocaleCode(event.default_locale) ? event.default_locale : DEFAULT_LOCALE;
  const localeStorageKey = `guestLocale_event_${event.id ?? token}`;
  const branding = mapEventBranding(event.branding ?? (event as any)?.settings?.branding ?? null);

  const isGalleryRoute = /^\/e\/[^/]+\/gallery(?:\/|$)/.test(location.pathname);
  const contentPaddingClass = isGalleryRoute ? 'px-0 py-0' : 'px-4 py-3';

  return (
    <LocaleProvider defaultLocale={eventLocale} storageKey={localeStorageKey}>
      <EventBrandingProvider branding={branding}>
        <EventStatsProvider eventKey={token}>
          <NotificationCenterProvider eventToken={token}>
            <div className="pb-16">
              <Header eventToken={token} />
              <div className={contentPaddingClass}>
                <RouteTransition />
              </div>
              <BottomNav />
            </div>
          </NotificationCenterProvider>
        </EventStatsProvider>
      </EventBrandingProvider>
    </LocaleProvider>
  );
}

function TaskGuard({ children }: { children: React.ReactNode }) {
  const { token } = useParams<{ token: string }>();
  const { event, status } = useEventData();

  if (status === 'loading') {
    return <EventLoadingView />;
  }

  if (event && !isTaskModeEnabled(event)) {
    return <Navigate to={`/e/${encodeURIComponent(token ?? '')}`} replace />;
  }

  return <>{children}</>;
}

function SetupLayout() {
  const { token } = useParams<{ token: string }>();
  const { event } = useEventData();
  if (!token) return null;
  const eventLocale = event && isLocaleCode(event.default_locale) ? event.default_locale : DEFAULT_LOCALE;
  const localeStorageKey = event ? `guestLocale_event_${event.id}` : `guestLocale_event_${token}`;
  const branding = event ? mapEventBranding(event.branding ?? (event as any)?.settings?.branding ?? null) : null;
  return (
    <GuestIdentityProvider eventKey={token}>
      <LocaleProvider defaultLocale={eventLocale} storageKey={localeStorageKey}>
        <EventBrandingProvider branding={branding}>
          <EventStatsProvider eventKey={token}>
            <NotificationCenterProvider eventToken={token}>
              <div className="pb-0">
                <Header eventToken={token} />
                <RouteTransition />
              </div>
            </NotificationCenterProvider>
          </EventStatsProvider>
        </EventBrandingProvider>
      </LocaleProvider>
    </GuestIdentityProvider>
  );
}

function EventLoadingView() {
  const { t } = useTranslation();
  return (
    <div className="flex min-h-screen flex-col items-center justify-center gap-4 px-6 text-center">
      <Loader2 className="h-10 w-10 animate-spin text-muted-foreground" aria-hidden />
      <div className="space-y-1">
        <p className="text-lg font-semibold text-foreground">{t('eventAccess.loading.title')}</p>
        <p className="text-sm text-muted-foreground">{t('eventAccess.loading.subtitle')}</p>
      </div>
    </div>
  );
}

function mapEventBranding(raw?: EventBrandingPayload | null): EventBranding | null {
  if (!raw) {
    return null;
  }

  const palette = raw.palette ?? {};
  const typography = raw.typography ?? {};
  const buttons = raw.buttons ?? {};
  const logo = raw.logo ?? {};
  const primary = palette.primary ?? raw.primary_color ?? '';
  const secondary = palette.secondary ?? raw.secondary_color ?? '';
  const background = palette.background ?? raw.background_color ?? '';
  const surface = palette.surface ?? raw.surface_color ?? background;
  const headingFont = typography.heading ?? raw.heading_font ?? raw.font_family ?? null;
  const bodyFont = typography.body ?? raw.body_font ?? raw.font_family ?? null;
  const sizePreset = (typography.size as 's' | 'm' | 'l' | undefined) ?? (raw.font_size as 's' | 'm' | 'l' | undefined) ?? 'm';
  const logoMode = logo.mode ?? raw.logo_mode ?? (logo.value || raw.logo_url ? 'upload' : 'emoticon');
  const logoValue = logo.value ?? raw.logo_value ?? raw.logo_url ?? raw.icon ?? null;
  const logoPosition = logo.position ?? raw.logo_position ?? 'left';
  const logoSize = (logo.size as 's' | 'm' | 'l' | undefined) ?? (raw.logo_size as 's' | 'm' | 'l' | undefined) ?? 'm';
  const buttonStyle = (buttons.style as 'filled' | 'outline' | undefined) ?? (raw.button_style as 'filled' | 'outline' | undefined) ?? 'filled';
  const buttonRadius = typeof buttons.radius === 'number' ? buttons.radius : (typeof raw.button_radius === 'number' ? raw.button_radius : 12);
  const buttonPrimary = buttons.primary ?? raw.button_primary_color ?? primary ?? '';
  const buttonSecondary = buttons.secondary ?? raw.button_secondary_color ?? secondary ?? '';
  const linkColor = buttons.link_color ?? raw.link_color ?? secondary ?? '';

  return {
    primaryColor: primary ?? '',
    secondaryColor: secondary ?? '',
    backgroundColor: background ?? '',
    fontFamily: bodyFont,
    logoUrl: logoMode === 'upload' ? (logoValue ?? null) : null,
    palette: {
      primary: primary ?? '',
      secondary: secondary ?? '',
      background: background ?? '',
      surface: surface ?? background ?? '',
    },
    typography: {
      heading: headingFont,
      body: bodyFont,
      sizePreset,
    },
    logo: {
      mode: logoMode,
      value: logoValue,
      position: logoPosition,
      size: logoSize,
    },
    buttons: {
      style: buttonStyle,
      radius: buttonRadius,
      primary: buttonPrimary,
      secondary: buttonSecondary,
      linkColor,
    },
    mode: (raw.mode as 'light' | 'dark' | 'auto' | undefined) ?? 'auto',
    useDefaultBranding: raw.use_default_branding ?? undefined,
  };
}

interface EventErrorViewProps {
  code: FetchEventErrorCode | null;
  message: string | null;
}

function EventErrorView({ code, message }: EventErrorViewProps) {
  const { t } = useTranslation();
  const content = getErrorContent(t, code, message);

  return (
    <div className="flex min-h-screen flex-col items-center justify-center gap-6 px-6 text-center">
      <div className="flex h-16 w-16 items-center justify-center rounded-full bg-red-100 text-red-600">
        <AlertTriangle className="h-8 w-8" aria-hidden />
      </div>
      <div className="space-y-2">
        <h2 className="text-2xl font-semibold text-foreground">{content.title}</h2>
        <p className="text-sm text-muted-foreground">{content.description}</p>
        {content.hint && (
          <p className="text-xs text-muted-foreground">{content.hint}</p>
        )}
      </div>
      {content.ctaHref && content.ctaLabel && (
        <Button asChild>
          <Link to={content.ctaHref}>{content.ctaLabel}</Link>
        </Button>
      )}
    </div>
  );
}

function getErrorContent(
  t: TranslateFn,
  code: FetchEventErrorCode | null,
  message: string | null,
) {
  const build = (key: string, options?: { ctaHref?: string }) => {
    const ctaLabel = t(`eventAccess.error.${key}.ctaLabel`, '');
    const hint = t(`eventAccess.error.${key}.hint`, '');
    return {
      title: t(`eventAccess.error.${key}.title`),
      description: message ?? t(`eventAccess.error.${key}.description`),
      ctaLabel: ctaLabel.trim().length > 0 ? ctaLabel : undefined,
      ctaHref: options?.ctaHref,
      hint: hint.trim().length > 0 ? hint : null,
    };
  };

  switch (code) {
    case 'invalid_token':
      return build('invalid_token', { ctaHref: '/event' });
    case 'token_revoked':
      return build('token_revoked', { ctaHref: '/event' });
    case 'token_expired':
      return build('token_expired', { ctaHref: '/event' });
    case 'token_rate_limited':
      return build('token_rate_limited');
    case 'access_rate_limited':
      return build('access_rate_limited');
    case 'event_not_public':
      return build('event_not_public');
    case 'gallery_expired':
      return build('gallery_expired', { ctaHref: '/event' });
    case 'network_error':
      return build('network_error');
    case 'server_error':
      return build('server_error');
    default:
      return build('default', { ctaHref: '/event' });
  }
}

function SimpleLayout({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <EventBrandingProvider>
      <div className="pb-16">
        <Header title={title} />
        <div className="px-4 py-3">
          <RouteTransition>{children}</RouteTransition>
        </div>
        <BottomNav />
      </div>
    </EventBrandingProvider>
  );
}

function HelpStandalone() {
  const { t } = useTranslation();
  return (
    <SimpleLayout title={t('help.center.title')}>
      <HelpCenterPage />
    </SimpleLayout>
  );
}

function HelpArticleStandalone() {
  const { t } = useTranslation();
  return (
    <SimpleLayout title={t('help.center.title')}>
      <HelpArticlePage />
    </SimpleLayout>
  );
}
