"use client";

import { useEffect, useMemo, useRef, useState } from "react";

interface DailyActivity {
  date: string;
  flashcards: number;
  questions: number;
  total: number;
  level: 0 | 1 | 2 | 3 | 4;
}

interface ActivitySummary {
  days: DailyActivity[];
  today: string;
  currentStreak: number;
}

const levelClasses = [
  "bg-white/10",
  "bg-primary/45",
  "bg-primary",
  "bg-accent",
  "bg-[#fbbf24]",
] as const;

export function ActivityBanner({ onNewClass }: { onNewClass: () => void }) {
  const [summary, setSummary] = useState<ActivitySummary | null>(null);
  const [error, setError] = useState(false);

  useEffect(() => {
    fetch("/api/activity")
      .then((response) => {
        if (!response.ok) throw new Error("Failed to load activity");
        return response.json();
      })
      .then(setSummary)
      .catch(() => setError(true));
  }, []);

  return (
    <section className="relative mb-10 overflow-hidden rounded-[2rem] bg-[#172033] px-5 py-7 text-white shadow-[var(--shadow-card)] sm:px-8 sm:py-9 dark:bg-[#111827]">
      <div className="absolute -right-16 -top-24 h-64 w-64 rounded-full bg-primary/70 blur-3xl" />
      <div className="absolute -bottom-28 right-1/3 h-52 w-52 rounded-full bg-accent/35 blur-3xl" />
      <div className="relative mb-6 flex items-center justify-between gap-4">
        <div>
          <p className="text-xs font-bold uppercase tracking-[0.22em] text-white/55">Personal library</p>
          <h1 className="editorial-title mt-1 text-3xl text-white sm:text-4xl">Study activity</h1>
        </div>
        <button onClick={onNewClass} className="inline-flex min-h-11 shrink-0 items-center justify-center gap-2 rounded-xl bg-white px-4 text-sm font-bold text-[#172033] shadow-lg transition-transform hover:-translate-y-0.5 sm:min-h-12 sm:px-5">
          <span className="text-xl leading-none">+</span> New class
        </button>
      </div>

      {error && (
        <div className="relative rounded-xl border border-white/15 bg-white/8 px-4 py-5 text-sm text-white/70" role="alert">
          Study activity could not be loaded. Your library is still available below.
        </div>
      )}
      {!summary && !error && <div className="relative h-52 animate-subtle-pulse rounded-2xl bg-white/8" />}
      {summary && (
        <div className="relative grid gap-6 xl:grid-cols-[minmax(0,1fr)_10rem] xl:items-center">
          <div className="min-w-0">
            <ActivityHeatmap days={summary.days} today={summary.today} />
          </div>
          <StreakDisplay streak={summary.currentStreak} />
        </div>
      )}
    </section>
  );
}

function ActivityHeatmap({ days, today }: { days: DailyActivity[]; today: string }) {
  const scrollRef = useRef<HTMLDivElement>(null);
  const [activeDay, setActiveDay] = useState<DailyActivity | null>(null);
  const weeks = useMemo(
    () => Array.from({ length: 53 }, (_, index) => days.slice(index * 7, index * 7 + 7)),
    [days]
  );

  useEffect(() => {
    const container = scrollRef.current;
    if (container) container.scrollLeft = container.scrollWidth;
  }, [days]);

  return (
    <div>
      <div className="relative mb-2 h-12">
        <p className="absolute bottom-0 left-0 text-xs font-semibold text-white/55">Last 53 weeks · Arizona time</p>
        <div className="absolute right-0 top-0">
          {activeDay && <DayTooltip day={activeDay} />}
        </div>
      </div>
      <div ref={scrollRef} className="overflow-x-auto pb-2 [scrollbar-color:rgba(255,255,255,.25)_transparent]">
        <div className="grid w-max grid-cols-[2rem_auto] gap-2">
          <div className="pt-6 text-[10px] font-semibold leading-[15px] text-white/45" aria-hidden>
            <div className="h-[15px]" />
            <div>Mon</div>
            <div className="h-[15px]" />
            <div>Wed</div>
            <div className="h-[15px]" />
            <div>Fri</div>
          </div>
          <div>
            <div className="mb-2 flex h-4 gap-[3px] text-[10px] font-semibold text-white/45" aria-hidden>
              {weeks.map((week, index) => (
                <div key={week[0]?.date ?? index} className="w-3">
                  {getMonthLabel(week, weeks[index - 1])}
                </div>
              ))}
            </div>
            <div className="flex gap-[3px]" role="group" aria-label="Study activity over the last 53 weeks">
              {weeks.map((week, weekIndex) => (
                <div key={week[0]?.date ?? weekIndex} className="grid grid-rows-7 gap-[3px]">
                  {week.map((day) => day.date > today ? (
                    <span key={day.date} aria-hidden className="h-3 w-3" />
                  ) : (
                      <button
                        key={day.date}
                        type="button"
                        aria-label={getDayAriaLabel(day)}
                        onMouseEnter={() => setActiveDay(day)}
                        onMouseLeave={() => setActiveDay(null)}
                        onFocus={() => setActiveDay(day)}
                        onBlur={() => setActiveDay(null)}
                        onClick={() => setActiveDay((current) => current?.date === day.date ? null : day)}
                        className={`h-3 w-3 rounded-[3px] border border-white/8 ${levelClasses[day.level]} focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white`}
                      />
                    ))}
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
      <div className="mt-2 flex items-center justify-end gap-1.5 text-[10px] font-semibold text-white/45" aria-label="Activity intensity from less to more">
        <span>Less</span>
        {levelClasses.map((className, index) => <span key={index} className={`h-3 w-3 rounded-[3px] border border-white/8 ${className}`} />)}
        <span>More</span>
      </div>
    </div>
  );
}

function DayTooltip({ day }: { day: DailyActivity }) {
  const formatted = new Date(`${day.date}T12:00:00Z`).toLocaleDateString("en-US", {
    timeZone: "America/Phoenix",
    month: "short",
    day: "numeric",
    year: "numeric",
  });
  return (
    <div role="tooltip" className="rounded-lg border border-white/15 bg-[#0d1422] px-3 py-2 text-right text-xs shadow-xl">
      <div className="font-bold text-white">{formatted} · {day.total} total</div>
      <div className="mt-0.5 text-white/60">{day.flashcards} flashcards · {day.questions} questions</div>
    </div>
  );
}

function StreakDisplay({ streak }: { streak: number }) {
  const size = 24 + Math.min(streak, 30) * 0.6;
  const color = streak === 0 ? "text-white/30" : streak < 7 ? "text-accent" : streak < 30 ? "text-[#ff7a36]" : "text-[#fbbf24]";
  return (
    <div className="flex items-center justify-center gap-4 rounded-2xl border border-white/12 bg-white/7 px-5 py-4 xl:flex-col xl:gap-2 xl:text-center">
      <svg viewBox="0 0 24 24" aria-hidden className={`shrink-0 fill-current ${color}`} style={{ width: size, height: size }}>
        <path d="M13.5 2.1c.4 3.1-1.4 4.5-2.6 6.1-1 1.3-1.5 2.4-.8 4.1.5-1.4 1.5-2.3 2.5-3.2 1.8 1.6 3.4 3.6 3.4 6.3 0 2.5-1.7 4.6-4 4.6s-4-2-4-4.6c0-1.2.4-2.3 1-3.3-2.4 1.3-4 3.7-4 6.3 0 3.1 2.8 5.6 7 5.6s7-2.7 7-6.7c0-5.6-3.4-10.3-5.5-15.2Z" />
      </svg>
      <div>
        <div className="text-3xl font-extrabold">{streak}</div>
        <div className="text-xs font-semibold text-white/55">day streak</div>
        <div className="mt-1 text-[10px] text-white/40">20 activities per day</div>
      </div>
    </div>
  );
}

function getMonthLabel(week: DailyActivity[], previousWeek?: DailyActivity[]) {
  const firstOfMonth = week.find((day) => Number(day.date.slice(8, 10)) <= 7);
  if (!firstOfMonth) return "";
  const month = firstOfMonth.date.slice(5, 7);
  if (previousWeek?.some((day) => day.date.slice(5, 7) === month)) return "";
  return new Date(`${firstOfMonth.date}T12:00:00Z`).toLocaleDateString("en-US", { month: "short", timeZone: "America/Phoenix" });
}

function getDayAriaLabel(day: DailyActivity) {
  return `${day.date}: ${day.flashcards} flashcards and ${day.questions} questions, ${day.total} total activities`;
}
