import React from 'react';
import { Link, useParams } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import EmotionPicker from '../components/EmotionPicker';
import GalleryPreview from '../components/GalleryPreview';
import { useGuestIdentity } from '../context/GuestIdentityContext';
import { useEventData } from '../hooks/useEventData';
import { useGuestTaskProgress } from '../hooks/useGuestTaskProgress';
import { Sparkles, UploadCloud, X, RefreshCw } from 'lucide-react';
import { useTranslation, type TranslateFn } from '../i18n/useTranslation';
import { useEventBranding } from '../context/EventBrandingContext';
import type { EventBranding } from '../types/event-branding';

export default function HomePage() {
  const { token } = useParams<{ token: string }>();
  const { name, hydrated } = useGuestIdentity();
  const { event } = useEventData();
  const { completedCount } = useGuestTaskProgress(token ?? '');
  const { t, locale } = useTranslation();
  const { branding } = useEventBranding();
  const headingFont = branding.typography?.heading ?? branding.fontFamily ?? undefined;
  const bodyFont = branding.typography?.body ?? branding.fontFamily ?? undefined;
  const radius = branding.buttons?.radius ?? 12;

  const heroStorageKey = token ? `guestHeroDismissed_${token}` : 'guestHeroDismissed';
  const [heroVisible, setHeroVisible] = React.useState(() => {
    if (typeof window === 'undefined') {
      return true;
    }

    try {
      return window.sessionStorage.getItem(heroStorageKey) !== '1';
    } catch {
      return true;
    }
  });

  React.useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }

    try {
      setHeroVisible(window.sessionStorage.getItem(heroStorageKey) !== '1');
    } catch {
      setHeroVisible(true);
    }
  }, [heroStorageKey]);

  const dismissHero = React.useCallback(() => {
    setHeroVisible(false);
    if (typeof window === 'undefined') {
      return;
    }

    try {
      window.sessionStorage.setItem(heroStorageKey, '1');
    } catch {
      // ignore storage exceptions (e.g. private mode)
    }
  }, [heroStorageKey]);

  const displayName = hydrated && name ? name : t('home.fallbackGuestName');
  const eventNameDisplay = event?.name ?? t('home.hero.defaultEventName');
  const accentColor = branding.primaryColor;
  const secondaryAccent = branding.secondaryColor;

  const [missionPreview, setMissionPreview] = React.useState<MissionPreview | null>(null);
  const [missionLoading, setMissionLoading] = React.useState(false);
  const missionPoolRef = React.useRef<MissionPreview[]>([]);

  const shuffleMissionPreview = React.useCallback(() => {
    const pool = missionPoolRef.current;
    if (!pool.length) {
      setMissionPreview(null);
      return;
    }
    const choice = pool[Math.floor(Math.random() * pool.length)];
    setMissionPreview(choice);
  }, []);

  React.useEffect(() => {
    if (!token) return;
    let cancelled = false;
    async function loadMissions() {
      setMissionLoading(true);
      try {
    const safeToken = token ?? '';
    const response = await fetch(
      `/api/v1/events/${encodeURIComponent(safeToken)}/tasks?locale=${encodeURIComponent(locale)}`,
      {
        headers: {
          Accept: 'application/json',
          'X-Locale': locale,
        },
      }
    );
        if (!response.ok) throw new Error('Aufgaben konnten nicht geladen werden.');
        const payload = await response.json();
        if (cancelled) return;
        if (Array.isArray(payload) && payload.length) {
          missionPoolRef.current = payload.map((task: Record<string, unknown>) => ({
            id: Number(task.id),
            title: typeof task.title === 'string' ? task.title : 'Mission',
            description: typeof task.description === 'string' ? task.description : '',
            duration: typeof task.duration === 'number' ? task.duration : 3,
            emotion: task.emotion ?? null,
          }));
          shuffleMissionPreview();
        } else {
          missionPoolRef.current = [];
          setMissionPreview(null);
        }
      } catch (err) {
        if (!cancelled) {
          console.warn('Mission preview failed', err);
          missionPoolRef.current = [];
          setMissionPreview(null);
        }
      } finally {
        if (!cancelled) {
          setMissionLoading(false);
        }
      }
    }
    loadMissions();
    return () => {
      cancelled = true;
    };
  }, [shuffleMissionPreview, token, locale]);

  if (!token) {
    return null;
  }

  return (
    <div className="space-y-6 pb-32" style={bodyFont ? { fontFamily: bodyFont } : undefined}>
      {heroVisible && (
        <HeroCard
          name={displayName}
          eventName={eventNameDisplay}
          tasksCompleted={completedCount}
          t={t}
          branding={branding}
          onDismiss={dismissHero}
          ctaLabel={t('home.actions.items.tasks.label')}
          ctaHref={`/e/${encodeURIComponent(token)}/tasks`}
        />
      )}

      <section className="space-y-4" style={headingFont ? { fontFamily: headingFont } : undefined}>
        <div className="flex items-center justify-between gap-3">
          <div>
            <h2 className="text-base font-semibold text-foreground">Starte dein Fotospiel</h2>
            <p className="text-xs text-muted-foreground">Wähle, wie du den nächsten Moment einfängst.</p>
          </div>
        </div>

        <div className="space-y-3">
          <MissionActionCard
            token={token}
            mission={missionPreview}
            loading={missionLoading}
            onShuffle={shuffleMissionPreview}
          />
          <EmotionActionCard />
          <UploadActionCard token={token} accentColor={accentColor} secondaryAccent={secondaryAccent} radius={radius} bodyFont={bodyFont} />
        </div>
      </section>

      <Separator />

      <GalleryPreview token={token} />
    </div>
  );
}

function HeroCard({
  name,
  eventName,
  tasksCompleted,
  t,
  branding,
  onDismiss,
  ctaLabel,
  ctaHref,
}: {
  name: string;
  eventName: string;
  tasksCompleted: number;
  t: TranslateFn;
  branding: EventBranding;
  onDismiss: () => void;
  ctaLabel?: string;
  ctaHref?: string;
}) {
  const heroTitle = t('home.hero.title').replace('{name}', name);
  const heroDescription = t('home.hero.description').replace('{eventName}', eventName);
  const progressMessage = tasksCompleted > 0
    ? t('home.hero.progress.some').replace('{count}', `${tasksCompleted}`)
    : t('home.hero.progress.none');

  const style = React.useMemo(() => ({
    background: `linear-gradient(135deg, ${branding.primaryColor}, ${branding.secondaryColor})`,
    color: '#ffffff',
    fontFamily: branding.fontFamily ?? undefined,
  }), [branding.fontFamily, branding.primaryColor, branding.secondaryColor]);

  return (
    <Card className="relative overflow-hidden border-0 text-white shadow-md" style={style}>
      <Button
        type="button"
        variant="ghost"
        size="icon"
        className="absolute right-3 top-3 h-8 w-8 rounded-full bg-white/20 text-white hover:bg-white/30"
        onClick={onDismiss}
      >
        <X className="h-4 w-4" aria-hidden />
        <span className="sr-only">{t('common.actions.close')}</span>
      </Button>
      <CardHeader className="space-y-4 pr-10">
        <CardDescription className="text-sm text-white/80">{t('home.hero.subtitle')}</CardDescription>
        <CardTitle className="text-2xl font-bold leading-snug">{heroTitle}</CardTitle>
        <p className="text-sm text-white/85">{heroDescription}</p>
        <div className="flex flex-wrap items-center gap-3">
          <p className="text-sm font-medium text-white/90">{progressMessage}</p>
          {ctaHref && ctaLabel && (
            <Button
              variant="secondary"
              size="sm"
              asChild
              className="rounded-full bg-white/15 px-4 py-1 text-xs font-semibold uppercase tracking-wide text-white hover:bg-white/25"
            >
              <Link to={ctaHref}>{ctaLabel}</Link>
            </Button>
          )}
        </div>
      </CardHeader>
    </Card>
  );
}

type MissionPreview = {
  id: number;
  title: string;
  description?: string;
  duration?: number;
  emotion?: { name?: string; slug?: string } | null;
};

function MissionActionCard({
  token,
  mission,
  loading,
  onShuffle,
}: {
  token: string;
  mission: MissionPreview | null;
  loading: boolean;
  onShuffle: () => void;
}) {
  return (
    <Card className="border-0 shadow-sm">
      <CardHeader className="flex flex-row items-start gap-3">
        <div className="flex h-10 w-10 items-center justify-center rounded-2xl bg-pink-100 text-pink-600">
          <Sparkles className="h-5 w-5" aria-hidden />
        </div>
        <div>
          <CardTitle className="text-base font-semibold text-foreground">Mission starten</CardTitle>
          <CardDescription className="text-xs text-muted-foreground">
            Wir haben bereits eine Aufgabe für dich vorbereitet. Tippe, um direkt loszulegen.
          </CardDescription>
        </div>
      </CardHeader>
      <CardContent className="space-y-3">
        {mission ? (
          <>
            <p className="text-lg font-semibold text-foreground">{mission.title}</p>
            {mission.description && (
              <p className="text-sm text-muted-foreground line-clamp-2">{mission.description}</p>
            )}
            <div className="flex gap-3 text-xs text-muted-foreground">
              <span>{mission.duration ?? 3} Min</span>
              {mission.emotion?.name && <span>{mission.emotion.name}</span>}
            </div>
          </>
        ) : (
          <p className="text-sm text-muted-foreground">
            Ziehe deine erste Mission im Aufgaben-Tab oder lade deine Stimmung hoch.
          </p>
        )}
        <div className="flex flex-col gap-2 sm:flex-row">
          <Button asChild className="flex-1">
            <Link to={`/e/${encodeURIComponent(token)}/tasks`}>Mission starten</Link>
          </Button>
          <Button
            type="button"
            variant="ghost"
            className="flex-1"
            onClick={onShuffle}
            disabled={loading}
          >
            <RefreshCw className={`mr-2 h-4 w-4 ${loading ? 'animate-spin' : ''}`} aria-hidden />
            Andere Mission
          </Button>
        </div>
      </CardContent>
    </Card>
  );
}

function EmotionActionCard() {
  return (
    <Card className="border border-muted/40 shadow-sm">
      <CardHeader>
        <CardTitle>Foto nach Gefühlslage</CardTitle>
        <CardDescription className="text-sm text-muted-foreground">
          Wähle deine Stimmung, wir schlagen dir passende Missionen vor.
        </CardDescription>
      </CardHeader>
      <CardContent>
        <EmotionPicker variant="embedded" showSkip={false} />
      </CardContent>
    </Card>
  );
}

function UploadActionCard({
  token,
  accentColor,
  secondaryAccent,
  radius,
  bodyFont,
}: {
  token: string;
  accentColor: string;
  secondaryAccent: string;
  radius: number;
  bodyFont?: string;
}) {
  return (
    <Card
      className="overflow-hidden border-0 text-white shadow-sm"
      style={{
        background: `linear-gradient(120deg, ${accentColor}, ${secondaryAccent})`,
        borderRadius: `${radius}px`,
        fontFamily: bodyFont,
      }}
    >
      <CardContent className="flex flex-col gap-3 py-5">
        <div className="flex items-center gap-3">
          <div className="rounded-2xl bg-white/15 p-3">
            <UploadCloud className="h-5 w-5" aria-hidden />
          </div>
          <div>
            <p className="text-lg font-semibold">Direkt hochladen</p>
            <p className="text-sm text-white/80">Kamera öffnen oder ein Foto aus deiner Galerie wählen.</p>
          </div>
        </div>
        <Button
          asChild
          className="bg-white/90 text-slate-900 hover:bg-white"
          style={{ borderRadius: `${radius}px` }}
        >
          <Link to={`/e/${encodeURIComponent(token)}/upload`}>Foto hochladen</Link>
        </Button>
      </CardContent>
    </Card>
  );
}
