import { createFileRoute, Link } from "@tanstack/react-router";
import { useQuery } from "@tanstack/react-query";
import { motion } from "framer-motion";
import {
  Flame,
  Clock,
  BookOpen,
  Target,
  ArrowUpRight,
  Plus,
  MessageSquare,
  Upload,
  Sparkles,
  ListChecks,
} from "lucide-react";
import {
  AreaChart,
  Area,
  ResponsiveContainer,
  XAxis,
  YAxis,
  Tooltip,
  CartesianGrid,
  BarChart,
  Bar,
} from "recharts";
import { PageHeader, StatCard, Section } from "@/components/common/PageBits";
import { analyticsService, chatsService, documentsService } from "@/services";
import { MOCK_USER } from "@/lib/mock-data";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Progress } from "@/components/ui/progress";
import { Skeleton } from "@/components/ui/skeleton";
import { formatDistanceToNow } from "date-fns";

export const Route = createFileRoute("/_app/dashboard")({
  head: () => ({ meta: [{ title: "Dashboard — Study Unique" }] }),
  component: Dashboard,
});

function Dashboard() {
  const activity = useQuery({ queryKey: ["activity"], queryFn: analyticsService.activity });
  const docs = useQuery({ queryKey: ["documents"], queryFn: documentsService.list });
  const chats = useQuery({ queryKey: ["chats"], queryFn: chatsService.list });

  const totalMinutes = activity.data?.slice(-7).reduce((a, b) => a + b.minutes, 0) ?? 0;
  const goal = MOCK_USER.weeklyGoalMin;
  const goalPct = Math.min(100, Math.round((totalMinutes / goal) * 100));

  return (
    <div className="mx-auto w-full max-w-7xl space-y-6 p-4 md:p-6">
      <PageHeader
        title={`Welcome back, ${MOCK_USER.name.split(" ")[0]} 👋`}
        description="Here's a snapshot of your learning this week."
        actions={
          <>
            <Link to="/documents/upload">
              <Button variant="outline" size="sm">
                <Upload className="mr-1.5 h-4 w-4" />
                Upload
              </Button>
            </Link>
            <Link to="/chat">
              <Button size="sm" className="gradient-brand text-primary-foreground">
                <MessageSquare className="mr-1.5 h-4 w-4" />
                New chat
              </Button>
            </Link>
          </>
        }
      />

      {/* Stats */}
      <div className="grid gap-3 md:grid-cols-2 lg:grid-cols-4">
        <StatCard label="Study streak" value={`${MOCK_USER.studyStreak} days`} hint="Personal best: 21" icon={Flame} accent="accent" />
        <StatCard label="This week" value={`${totalMinutes} min`} hint={`${goalPct}% of weekly goal`} icon={Clock} accent="primary" />
        <StatCard label="Documents" value={String(docs.data?.length ?? 0)} hint="3 added this week" icon={BookOpen} accent="secondary" />
        <StatCard label="Avg quiz score" value="87%" hint="+4% vs last week" icon={Target} accent="success" />
      </div>

      {/* Activity charts */}
      <div className="grid gap-4 lg:grid-cols-3">
        <motion.div
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          className="rounded-2xl border border-border bg-card p-5 lg:col-span-2"
        >
          <div className="flex items-end justify-between">
            <div>
              <p className="text-sm font-semibold">Weekly activity</p>
              <p className="text-xs text-muted-foreground">Minutes studied per day</p>
            </div>
            <Badge variant="secondary" className="text-[10px]">
              Last 30 days
            </Badge>
          </div>
          <div className="mt-4 h-64">
            {activity.isLoading ? (
              <Skeleton className="h-full w-full" />
            ) : (
              <ResponsiveContainer width="100%" height="100%">
                <AreaChart data={activity.data}>
                  <defs>
                    <linearGradient id="gPrimary" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0%" stopColor="var(--color-primary)" stopOpacity={0.5} />
                      <stop offset="100%" stopColor="var(--color-primary)" stopOpacity={0} />
                    </linearGradient>
                  </defs>
                  <CartesianGrid strokeDasharray="3 3" stroke="var(--color-border)" />
                  <XAxis dataKey="date" stroke="var(--color-muted-foreground)" fontSize={11} tickFormatter={(d) => d.slice(5)} />
                  <YAxis stroke="var(--color-muted-foreground)" fontSize={11} />
                  <Tooltip contentStyle={{ background: "var(--color-popover)", border: "1px solid var(--color-border)", borderRadius: 8 }} />
                  <Area type="monotone" dataKey="minutes" stroke="var(--color-primary)" strokeWidth={2} fill="url(#gPrimary)" />
                </AreaChart>
              </ResponsiveContainer>
            )}
          </div>
        </motion.div>

        <motion.div
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          className="flex flex-col rounded-2xl border border-border bg-card p-5"
        >
          <p className="text-sm font-semibold">Weekly goal</p>
          <p className="text-xs text-muted-foreground">
            {totalMinutes} / {goal} minutes
          </p>
          <div className="my-5 flex flex-1 items-center justify-center">
            <RingProgress value={goalPct} />
          </div>
          <Progress value={goalPct} className="h-1.5" />
          <Link
            to="/analytics"
            className="mt-3 inline-flex items-center text-xs font-medium text-primary hover:underline"
          >
            View analytics
            <ArrowUpRight className="ml-1 h-3 w-3" />
          </Link>
        </motion.div>
      </div>

      <div className="grid gap-4 lg:grid-cols-3">
        {/* Recent documents */}
        <Section
          title="Recent documents"
          description="Your latest uploads"
          action={
            <Link to="/documents" className="text-xs text-primary hover:underline">
              View all
            </Link>
          }
        >
          <div className="space-y-2">
            {(docs.data ?? []).slice(0, 4).map((d) => (
              <Link
                key={d.id}
                to="/documents/$id"
                params={{ id: d.id }}
                className="flex items-center gap-3 rounded-xl border border-border bg-card p-3 transition-colors hover:border-primary/40"
              >
                <div className="flex h-10 w-10 items-center justify-center rounded-md bg-muted text-[10px] font-semibold uppercase text-muted-foreground">
                  {d.type}
                </div>
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm font-medium">{d.title}</p>
                  <p className="text-xs text-muted-foreground">
                    {d.pages} pages • {formatDistanceToNow(new Date(d.updatedAt), { addSuffix: true })}
                  </p>
                </div>
              </Link>
            ))}
          </div>
        </Section>

        {/* Recent chats */}
        <Section
          title="Recent chats"
          action={
            <Link to="/chat" className="text-xs text-primary hover:underline">
              Open chat
            </Link>
          }
        >
          <div className="space-y-2">
            {(chats.data ?? []).slice(0, 4).map((c) => (
              <Link
                key={c.id}
                to="/chat"
                className="flex items-center gap-3 rounded-xl border border-border bg-card p-3 hover:border-primary/40"
              >
                <div className="flex h-10 w-10 items-center justify-center rounded-md bg-muted">
                  <MessageSquare className="h-4 w-4 text-muted-foreground" />
                </div>
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm font-medium">{c.title}</p>
                  <p className="text-xs text-muted-foreground">
                    {formatDistanceToNow(new Date(c.updatedAt), { addSuffix: true })}
                  </p>
                </div>
              </Link>
            ))}
          </div>
        </Section>

        {/* Quick actions */}
        <Section title="Quick actions">
          <div className="grid grid-cols-2 gap-2">
            {[
              { to: "/documents/upload", icon: Upload, label: "Upload" },
              { to: "/summary", icon: Sparkles, label: "Summary" },
              { to: "/flashcards", icon: Plus, label: "Flashcards" },
              { to: "/quiz", icon: ListChecks, label: "Quiz" },
            ].map((a) => (
              <Link
                key={a.to}
                to={a.to}
                className="flex flex-col items-center justify-center gap-2 rounded-xl border border-border bg-card p-4 text-xs font-medium transition-colors hover:border-primary/40 hover:bg-muted"
              >
                <a.icon className="h-5 w-5 text-primary" />
                {a.label}
              </Link>
            ))}
          </div>

          <div className="mt-3 rounded-xl border border-border bg-card p-4">
            <p className="text-xs font-semibold">Recent quizzes</p>
            <div className="mt-3 h-24">
              <ResponsiveContainer width="100%" height="100%">
                <BarChart data={(activity.data ?? []).slice(-7)}>
                  <Bar dataKey="quizzes" fill="var(--color-accent)" radius={[4, 4, 0, 0]} />
                  <Tooltip contentStyle={{ background: "var(--color-popover)", border: "1px solid var(--color-border)", borderRadius: 8 }} />
                </BarChart>
              </ResponsiveContainer>
            </div>
          </div>
        </Section>
      </div>
    </div>
  );
}

function RingProgress({ value }: { value: number }) {
  const radius = 56;
  const c = 2 * Math.PI * radius;
  const offset = c - (value / 100) * c;
  return (
    <svg width="140" height="140" viewBox="0 0 140 140" className="-rotate-90">
      <circle cx="70" cy="70" r={radius} stroke="var(--color-muted)" strokeWidth="12" fill="none" />
      <motion.circle
        cx="70"
        cy="70"
        r={radius}
        stroke="url(#ringGrad)"
        strokeWidth="12"
        strokeLinecap="round"
        fill="none"
        strokeDasharray={c}
        initial={{ strokeDashoffset: c }}
        animate={{ strokeDashoffset: offset }}
        transition={{ duration: 0.8, ease: "easeOut" }}
      />
      <defs>
        <linearGradient id="ringGrad" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="var(--color-primary)" />
          <stop offset="100%" stopColor="var(--color-accent)" />
        </linearGradient>
      </defs>
      <text
        x="70"
        y="74"
        textAnchor="middle"
        className="fill-foreground text-xl font-semibold"
        transform="rotate(90 70 70)"
      >
        {value}%
      </text>
    </svg>
  );
}
