import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { getStats, deleteTasteTag } from "../api";
import { Link } from "react-router-dom";

function fmt(seconds) {
  if (!seconds) return "0m";
  const h = Math.floor(seconds / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  if (h === 0) return `${m}m`;
  if (m === 0) return `${h}h`;
  return `${h}h ${m}m`;
}

function fmtBytes(bytes) {
  if (!bytes) return "0 B";
  const units = ["B", "KB", "MB", "GB", "TB"];
  let i = 0, v = bytes;
  while (v >= 1024 && i < units.length - 1) { v /= 1024; i++; }
  return `${v.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
}

function StatCard({ label, value, sub }) {
  return (
    <div className="bg-zinc-900 rounded-2xl p-4 flex flex-col gap-1">
      <p className="text-[11px] text-zinc-500 uppercase tracking-wider font-medium">{label}</p>
      <p className="text-2xl font-bold text-white font-mono leading-none">{value}</p>
      {sub && <p className="text-xs text-zinc-600 mt-0.5">{sub}</p>}
    </div>
  );
}

export default function Stats() {
  const qc = useQueryClient();
  const { data, isLoading } = useQuery({
    queryKey: ["stats"],
    queryFn: () => getStats().then(r => r.data),
    staleTime: 5 * 60_000,
  });

  const deleteTag = useMutation({
    mutationFn: (tag) => deleteTasteTag(tag),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["stats"] }),
  });

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-24">
        <div className="w-8 h-8 border-2 border-accent border-t-transparent rounded-full animate-spin" />
      </div>
    );
  }
  if (!data) return null;

  const maxSeconds = Math.max(...(data.top_channels.map(c => c.watch_seconds || 0)), 1);
  const today = new Date();
  const days = Array.from({ length: 30 }, (_, i) => {
    const d = new Date(today);
    d.setDate(today.getDate() - (29 - i));
    return d.toISOString().slice(0, 10);
  });
  const dailyMap = Object.fromEntries((data.daily || []).map(d => [d.date, d]));
  const maxDayCount = Math.max(...days.map(d => dailyMap[d]?.count || 0), 1);

  const maxCatCount = Math.max(...(data.top_categories || []).map(c => c.watch_count || 0), 1);
  const topTags = (data.taste_profile || []).slice(0, 12);
  const maxTagScore = Math.max(...topTags.map(t => t.score || 0), 1);

  return (
    <div className="flex flex-col gap-8 max-w-4xl mx-auto">
      <h1 className="font-display font-bold text-2xl text-white">Stats</h1>

      {/* Top numbers */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        <StatCard label="Total watched" value={data.total_watched.toLocaleString()} sub={fmt(data.total_watch_seconds) + " total"} />
        <StatCard label="This week" value={data.this_week.count} sub={fmt(data.this_week.seconds)} />
        <StatCard label="This month" value={data.this_month.count} sub={fmt(data.this_month.seconds)} />
        <StatCard label="Total liked" value={(data.total_liked || 0).toLocaleString()} sub="videos" />
      </div>

      {/* Engagement row */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        <StatCard
          label="Avg completion"
          value={`${data.avg_completion_percent ?? 0}%`}
          sub="of videos you start"
        />
        <StatCard
          label="Finished"
          value={(data.finished_count || 0).toLocaleString()}
          sub="watched ≥90%"
        />
        <StatCard
          label="Bailed early"
          value={(data.bailed_count || 0).toLocaleString()}
          sub="left before 20%"
        />
        <StatCard
          label="Rewatched"
          value={(data.rewatched_videos || 0).toLocaleString()}
          sub={`${data.total_rewatches || 0} total rewatches`}
        />
      </div>

      {/* Activity chart */}
      <div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
        <h2 className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Activity — last 30 days</h2>
        <div className="flex items-end gap-0.5 h-16">
          {days.map(date => {
            const entry = dailyMap[date];
            const count = entry?.count || 0;
            const pct = count / maxDayCount;
            return (
              <div
                key={date}
                title={`${date}: ${count} video${count !== 1 ? "s" : ""}`}
                className="flex-1 rounded-sm transition-all"
                style={{
                  height: count === 0 ? "2px" : `${Math.max(pct * 100, 6)}%`,
                  backgroundColor: count === 0 ? "#27272a" : `hsl(50,95%,${30 + pct * 30}%)`,
                }}
              />
            );
          })}
        </div>
        <div className="flex justify-between text-[10px] text-zinc-600">
          <span>30 days ago</span><span>Today</span>
        </div>
      </div>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
        {/* Top channels */}
        {data.top_channels.length > 0 && (
          <div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
            <h2 className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Top channels by watch time</h2>
            <div className="flex flex-col gap-2.5">
              {data.top_channels.map(ch => {
                const pct = (ch.watch_seconds || 0) / maxSeconds;
                return (
                  <div key={ch.id} className="flex flex-col gap-1">
                    <div className="flex items-center justify-between text-sm">
                      <Link to={`/channels/${ch.id}`} className="text-zinc-200 hover:text-white transition-colors truncate text-[13px]">{ch.name}</Link>
                      <span className="text-zinc-500 text-[11px] shrink-0 ml-2 font-mono">{ch.watch_count} · {fmt(ch.watch_seconds)}</span>
                    </div>
                    <div className="h-1 bg-zinc-800 rounded-full overflow-hidden">
                      <div className="h-full bg-accent/60 rounded-full" style={{ width: `${pct * 100}%` }} />
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {/* Top categories */}
        {data.top_categories?.length > 0 && (
          <div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
            <h2 className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Top categories</h2>
            <div className="flex flex-col gap-2.5">
              {data.top_categories.map(cat => {
                const pct = cat.watch_count / maxCatCount;
                const comp = cat.avg_completion ? Math.round(cat.avg_completion) : null;
                return (
                  <div key={cat.category} className="flex flex-col gap-1">
                    <div className="flex items-center justify-between">
                      <span className="text-[13px] text-zinc-200 truncate">{cat.category}</span>
                      <span className="text-[11px] text-zinc-500 shrink-0 ml-2 font-mono">
                        {cat.watch_count}{comp !== null ? ` · ${comp}% avg` : ""}
                      </span>
                    </div>
                    <div className="h-1 bg-zinc-800 rounded-full overflow-hidden">
                      <div className="h-full bg-indigo-500/60 rounded-full" style={{ width: `${pct * 100}%` }} />
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </div>

      {/* Disk usage */}
      {data.disk?.total_bytes && (
        <div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
          <h2 className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Disk usage</h2>
          <div className="flex flex-col gap-2">
            <div className="flex justify-between text-sm">
              <span className="text-zinc-400">Downloads</span>
              <span className="text-zinc-300 font-mono">{fmtBytes(data.disk.download_bytes)}</span>
            </div>
            <div className="h-2 bg-zinc-800 rounded-full overflow-hidden">
              <div
                className="h-full bg-accent/70 rounded-full transition-all"
                style={{ width: `${Math.min((data.disk.used_bytes / data.disk.total_bytes) * 100, 100)}%` }}
              />
            </div>
            <div className="flex justify-between text-[11px] text-zinc-600">
              <span>{fmtBytes(data.disk.used_bytes)} used</span>
              <span>{fmtBytes(data.disk.free_bytes)} free · {fmtBytes(data.disk.total_bytes)} total</span>
            </div>
          </div>
        </div>
      )}

      {/* Taste profile */}
      {topTags.length > 0 && (
        <div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
          <div className="flex items-baseline gap-2">
            <h2 className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Taste profile</h2>
            <p className="text-[11px] text-zinc-600">built from your watches, likes and bookmarks</p>
          </div>
          <div className="flex flex-wrap gap-2">
            {topTags.map(t => {
              const intensity = t.score / maxTagScore;
              return (
                <span
                  key={t.tag}
                  title={`score: ${t.score.toFixed(1)}`}
                  className="flex items-center gap-1 px-3 py-1 rounded-full text-xs font-medium"
                  style={{
                    backgroundColor: `rgba(250,204,21,${0.08 + intensity * 0.18})`,
                    color: `hsl(50,95%,${55 + intensity * 20}%)`,
                    fontSize: `${11 + intensity * 4}px`,
                  }}
                >
                  {t.tag}
                  <button
                    onClick={() => deleteTag.mutate(t.tag)}
                    disabled={deleteTag.isPending}
                    className="opacity-40 hover:opacity-100 transition-opacity leading-none ml-0.5"
                    title="Remove from taste profile"
                  >
                    ×
                  </button>
                </span>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}
