﻿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';
import { animated, useSpring } from '@react-spring/web';
import { useGesture } from '@use-gesture/react';

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(false);

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

    try {
      const stored = window.sessionStorage.getItem(heroStorageKey);
      // standardmäßig versteckt, nur sichtbar falls explizit gesetzt (kann später wieder aktiviert werden)
      setHeroVisible(stored === 'show');
    } catch {
      setHeroVisible(false);
    }
  }, [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 [missionDeck, setMissionDeck] = React.useState<MissionPreview[]>([]);
  const [missionLoading, setMissionLoading] = React.useState(false);
  const missionPoolRef = React.useRef<MissionPreview[]>([]);

  const drawRandom = React.useCallback((excludeIds: Set<number>) => {
    const pool = missionPoolRef.current.filter((item) => !excludeIds.has(item.id));
    if (!pool.length) return null;
    return pool[Math.floor(Math.random() * pool.length)];
  }, []);

  const resetDeck = React.useCallback(() => {
    const pool = missionPoolRef.current;
    if (!pool.length) {
      setMissionDeck([]);
      return;
    }
    const shuffled = [...pool].sort(() => Math.random() - 0.5);
    setMissionDeck(shuffled.slice(0, 4));
  }, []);

  const advanceDeck = React.useCallback(() => {
    setMissionDeck((prev) => {
      if (!prev.length) return prev;
      const [, ...rest] = prev;
      const exclude = new Set(rest.map((r) => r.id));
      const nextCandidate = drawRandom(exclude);
      const replenished = nextCandidate ? [...rest, nextCandidate] : rest;
      return replenished;
    });
  }, [drawRandom]);

  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,
          }));
          resetDeck();
        } else {
          missionPoolRef.current = [];
          setMissionDeck([]);
        }
      } catch (err) {
        if (!cancelled) {
          console.warn('Mission preview failed', err);
          missionPoolRef.current = [];
          setMissionDeck([]);
        }
      } finally {
        if (!cancelled) {
          setMissionLoading(false);
        }
      }
    }
    loadMissions();
    return () => {
      cancelled = true;
    };
  }, [resetDeck, token, locale]);

  if (!token) {
    return null;
  }

  const introArray: string[] = [];
  for (let i = 0; i < 12; i += 1) {
    const candidate = t(`home.introRotating.${i}`, '');
    if (candidate) {
      introArray.push(candidate);
    }
  }
  const introMessage =
    introArray.length > 0 ? introArray[Math.floor(Math.random() * introArray.length)] : '';

  return (
    <div className="space-y-0.5 pb-24" style={bodyFont ? { fontFamily: bodyFont } : undefined}>
      <section className="space-y-1 px-4">
        <p className="text-sm font-semibold text-foreground">
          {t('home.welcomeLine').replace('{name}', displayName)}
        </p>
        {introMessage && (
          <p className="text-xs text-muted-foreground">
            {introMessage}
          </p>
        )}
      </section>

      {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-0.5" style={headingFont ? { fontFamily: headingFont } : undefined}>
        <div className="space-y-0.5">
          <MissionActionCard
            token={token}
            mission={missionDeck[0] ?? null}
            loading={missionLoading}
            onAdvance={advanceDeck}
            stack={missionDeck.slice(0, 3)}
          />
          <UploadActionCard token={token} accentColor={accentColor} secondaryAccent={secondaryAccent} radius={radius} bodyFont={bodyFont} />
          <EmotionActionCard />
        </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,
  onAdvance,
  stack,
}: {
  token: string;
  mission: MissionPreview | null;
  loading: boolean;
  onAdvance: () => void;
  stack: MissionPreview[];
}) {
  const { branding } = useEventBranding();
  const radius = branding.buttons?.radius ?? 12;
  const primary = branding.buttons?.primary ?? branding.primaryColor;
  const secondary = branding.buttons?.secondary ?? branding.secondaryColor;
  const buttonStyle = branding.buttons?.style ?? 'filled';
  const headingFont = branding.typography?.heading ?? branding.fontFamily ?? undefined;
  const bodyFont = branding.typography?.body ?? branding.fontFamily ?? undefined;
  const textColor = '#1f2937';
  const subTextColor = '#334155';
  const swipeThreshold = 120;
  const stackLayers = stack.slice(1, 4);

  const cardStyle: React.CSSProperties = {
    borderRadius: `${radius + 8}px`,
    backgroundColor: '#fcf7ef',
    backgroundImage: `linear-gradient(0deg, ${primary}33, ${primary}22), url(/patterns/rays-sunburst.svg)`,
    backgroundBlendMode: 'multiply, normal',
    backgroundSize: '330% 330%',
    backgroundPosition: 'center',
    backgroundRepeat: 'no-repeat',
    filter: 'contrast(1.12) saturate(1.1)',
    border: `1px solid ${primary}26`,
    boxShadow: `0 12px 28px ${primary}22, 0 2px 6px ${primary}1f`,
    fontFamily: bodyFont,
    position: 'relative',
    overflow: 'hidden',
  };

  const [{ x, y, rotateZ, rotateY, rotateX, scale, opacity }, api] = useSpring(() => ({
    x: 0,
    y: 0,
    rotateZ: 0,
    rotateY: 0,
    rotateX: 0,
    scale: 1,
    opacity: 1,
    config: { tension: 320, friction: 26 },
  }));

  React.useEffect(() => {
    api.start({ x: 0, y: 0, rotateZ: 0, rotateY: 0, rotateX: 0, scale: 1, opacity: 1, immediate: false });
  }, [mission?.id, api]);

  const bind = useGesture(
    {
      onDrag: ({ active, movement: [mx, my], velocity: [vx], direction: [dx], cancel }) => {
        if (active && Math.abs(mx) > swipeThreshold) {
          cancel?.();
          api.start({
            x: dx > 0 ? 520 : -520,
            y: my,
            rotateZ: dx > 0 ? 12 : -12,
            rotateY: dx > 0 ? 18 : -18,
            rotateX: -my / 10,
            opacity: 0,
            scale: 1,
            immediate: false,
            onRest: () => {
              onAdvance();
              api.start({ x: 0, y: 0, rotateZ: 0, rotateY: 0, rotateX: 0, opacity: 1, scale: 1, immediate: false });
            },
          });
          return;
        }

        api.start({
          x: mx,
          y: my,
          rotateZ: mx / 18,
          rotateY: mx / 28,
          rotateX: -my / 36,
          scale: active ? 1.02 : 1,
          opacity: 1,
          immediate: false,
        });
      },
      onDragEnd: () => {
        api.start({ x: 0, y: 0, rotateZ: 0, rotateY: 0, rotateX: 0, scale: 1, opacity: 1, immediate: false });
      },
    },
    {
      drag: {
        filterTaps: true,
        bounds: { left: -200, right: 200, top: -120, bottom: 120 },
        rubberband: true,
      },
    }
  );

  return (
    <Card className="border-0 shadow-none bg-transparent" style={{ fontFamily: bodyFont }}>
      <CardContent className="px-0 py-0">
        <div className="relative min-h-[280px]">
          {stackLayers.map((item, index) => {
            const depth = index + 1;
            const scaleDown = 1 - depth * 0.03;
            const translateY = depth * 12;
            const fade = Math.max(0.25, 0.55 - depth * 0.08);
            return (
              <div
                key={item.id ?? index}
                className="absolute inset-0 pointer-events-none"
                style={{
                  ...cardStyle,
                  transform: `translateY(${translateY}px) scale(${scaleDown})`,
                  opacity: fade,
                  filter: 'brightness(0.96) contrast(0.98)',
                }}
                aria-hidden
              />
            );
          })}
          <animated.div
            className="relative overflow-hidden touch-pan-y"
            style={{
              ...cardStyle,
              x,
              y,
              rotateZ,
              rotateY,
              rotateX,
              scale,
              opacity,
              transformOrigin: 'center center',
              willChange: 'transform',
            }}
            {...bind()}
          >
            <div
              className="absolute inset-x-0 top-0 h-12"
              style={{
                background: `linear-gradient(90deg, ${secondary}80, ${primary}cc)`,
                filter: 'saturate(1.05)',
            }}
            aria-hidden
          />
          <div className="relative z-10 flex flex-col gap-3 px-5 pb-4 pt-1">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-3">
                <div
                  className="flex h-11 w-11 items-center justify-center rounded-2xl bg-white/90 text-foreground shadow-sm"
                  style={{ borderRadius: `${radius - 2}px` }}
                >
                  <Sparkles className="h-5 w-5" aria-hidden />
                </div>
                <div>
                  <p
                    className="text-xs font-semibold uppercase tracking-wide"
                    style={{ ...(headingFont ? { fontFamily: headingFont } : {}), color: subTextColor }}
                  >
                    Fotoaufgabe
                  </p>
                  <p className="text-sm" style={{ color: subTextColor }}>
                    Wir haben schon etwas für dich vorbereitet.
                  </p>
                </div>
              </div>
            </div>

            {mission ? (
              <div className="space-y-2">
                <div
                  className="rounded-[14px] py-3 text-center"
                  style={{
                    background: 'rgba(255,255,255,0.6)',
                    paddingLeft: '30px',
                    paddingRight: '30px',
                  }}
                >
                  <p
                    className="text-lg font-semibold leading-snug"
                    style={{ ...(headingFont ? { fontFamily: headingFont } : {}), color: textColor }}
                  >
                    {mission.title}
                  </p>
                  {mission.description && (
                    <p className="text-sm leading-relaxed" style={{ color: subTextColor }}>
                      {mission.description}
                    </p>
                  )}
                </div>
              </div>
            ) : (
              <p className="text-sm text-center" style={{ color: subTextColor }}>
                Ziehe deine erste Mission im Aufgaben-Tab oder wähle eine Stimmung.
              </p>
            )}

            <div className="grid grid-cols-[2fr_1fr] gap-2 pt-1">
              <Button asChild className="w-full" style={{ borderRadius: `${radius}px` }}>
                <Link
                  to={
                    mission
                      ? `/e/${encodeURIComponent(token)}/upload?task=${mission.id}`
                      : `/e/${encodeURIComponent(token)}/tasks`
                  }
                >
                  Aufgabe starten
                </Link>
              </Button>
              <Button
                type="button"
                variant="secondary"
                className="w-full"
                onClick={onShuffle}
                disabled={loading}
                style={{
                  borderRadius: `${radius}px`,
                  backgroundColor: secondary,
                  color: '#ffffff',
                }}
              >
                <RefreshCw className={`mr-2 h-4 w-4 ${loading ? 'animate-spin' : ''}`} aria-hidden />
                Andere Aufgabe
              </Button>
            </div>
          </div>
        </animated.div>
      </CardContent>
    </Card>
  );
}

function EmotionActionCard() {
  return (
    <Card className="border border-muted/40 shadow-sm">
      <CardHeader className="py-[4px]">
        <CardTitle>Wähle eine Stimmung und erhalte eine passende Aufgabe</CardTitle>
        <CardDescription className="text-sm text-muted-foreground">
          Tippe deinen Mood, wir picken die nächste Mission für dich.
        </CardDescription>
      </CardHeader>
      <CardContent className="py-[4px]">
        <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 border-muted/30 shadow-sm"
      style={{
        background: 'var(--guest-surface)',
        borderRadius: `${radius}px`,
        fontFamily: bodyFont,
      }}
    >
      <CardContent className="flex flex-col gap-1.5 py-[4px]">
        <div className="flex items-center gap-3">
          <div className="rounded-2xl p-3" style={{ background: `${accentColor}15` }}>
            <UploadCloud className="h-5 w-5" aria-hidden style={{ color: accentColor }} />
          </div>
          <div>
            <p className="text-lg font-semibold text-foreground">Direkt hochladen</p>
            <p className="text-sm text-muted-foreground">Kamera öffnen oder ein Foto aus deiner Galerie wählen.</p>
          </div>
        </div>
        <Button
          asChild
          className="text-white"
          style={{
            borderRadius: `${radius}px`,
            background: `linear-gradient(120deg, ${accentColor}, ${secondaryAccent})`,
            boxShadow: `0 12px 28px ${accentColor}25`,
          }}
        >
          <Link to={`/e/${encodeURIComponent(token)}/upload`}>Foto hochladen</Link>
        </Button>
        <p className="text-xs text-muted-foreground">Offline möglich – wir laden später hoch.</p>
      </CardContent>
    </Card>
  );
}
