import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  getDiscovery, getDiscoveryVideos,
  followDiscovery, dismissDiscovery, dismissDiscoveryVideo, refreshDiscovery,
} from "../api";
import VideoCard from "../components/VideoCard";
import { scrollToTop } from "../utils/scroll";

const PAGE_SIZE = 50;

const SOURCE_LABELS = {
  search:    "Based on your channels",
  graph:     "Related to channels you follow",
  community: "Popular with other users",
  category:  "Similar category",
  liked:     "Related to videos you liked",
};

function formatSubs(n) {
  if (!n) return null;
  if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(n >= 10_000_000 ? 0 : 1)}M`;
  if (n >= 1_000) return `${Math.round(n / 1_000)}K`;
  return String(n);
}

function avatarColor(name) {
  if (!name) return "#52525b";
  let h = 0;
  for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) % 360;
  return `hsl(${h}, 55%, 42%)`;
}

function ChannelCard({ item }) {
  const navigate = useNavigate();
  const qc = useQueryClient();
  const [gone, setGone] = useState(false);

  const followMut = useMutation({
    mutationFn: () => followDiscovery(item.channel_id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["channels"] });
      setTimeout(() => {
        setGone(true);
        qc.invalidateQueries({ queryKey: ["discovery"] });
        qc.invalidateQueries({ queryKey: ["discovery-videos"] });
      }, 600);
    },
  });

  const dismissMut = useMutation({
    mutationFn: () => dismissDiscovery(item.channel_id),
    onSuccess: () => {
      setTimeout(() => {
        setGone(true);
        qc.invalidateQueries({ queryKey: ["discovery"] });
        qc.invalidateQueries({ queryKey: ["discovery-videos"] });
      }, 300);
    },
  });

  const [featured, ...rest] = item.preview_videos ?? [];
  const subs = formatSubs(item.subscriber_count);
  const busy = followMut.isPending || dismissMut.isPending;

  if (gone) return null;

  return (
    <div className={`rounded-xl border border-zinc-800 bg-zinc-900 overflow-hidden flex flex-col transition-opacity duration-300 ${
      followMut.isSuccess || dismissMut.isSuccess ? "opacity-0 pointer-events-none" : "opacity-100"
    }`}>
      {/* Featured thumbnail */}
      {featured ? (
        <div
          className="relative aspect-video bg-zinc-800 overflow-hidden cursor-pointer group/thumb"
          onClick={() => navigate(`/channels/${item.channel_id}`)}
        >
          <img
            src={featured.thumbnail_url}
            alt={featured.title}
            className="w-full h-full object-cover group-hover/thumb:scale-105 transition-transform duration-300"
            loading="lazy"
          />
          <div className="absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-zinc-900/80 to-transparent" />
          <div className="absolute bottom-2 left-3">
            {item.thumbnail_url ? (
              <img src={item.thumbnail_url} alt={item.name}
                className="w-8 h-8 rounded-full object-cover ring-2 ring-zinc-900" />
            ) : (
              <div className="w-8 h-8 rounded-full flex items-center justify-center font-bold text-white text-sm ring-2 ring-zinc-900"
                style={{ backgroundColor: avatarColor(item.name) }}>
                {item.name?.[0]?.toUpperCase()}
              </div>
            )}
          </div>
        </div>
      ) : (
        <div
          className="h-20 cursor-pointer flex items-end px-3 pb-2"
          style={{ background: `linear-gradient(135deg, ${avatarColor(item.name)}44, ${avatarColor(item.name)}22)` }}
          onClick={() => navigate(`/channels/${item.channel_id}`)}
        >
          {item.thumbnail_url ? (
            <img src={item.thumbnail_url} alt={item.name}
              className="w-10 h-10 rounded-full object-cover ring-2 ring-zinc-900" />
          ) : (
            <div className="w-10 h-10 rounded-full flex items-center justify-center font-bold text-white text-base ring-2 ring-zinc-900"
              style={{ backgroundColor: avatarColor(item.name) }}>
              {item.name?.[0]?.toUpperCase()}
            </div>
          )}
        </div>
      )}

      {/* Info */}
      <div className="p-3 flex flex-col gap-2 flex-1">
        <div className="flex items-start justify-between gap-2">
          <div className="min-w-0 flex-1">
            <button
              onClick={() => navigate(`/channels/${item.channel_id}`)}
              className="font-semibold text-sm text-zinc-100 hover:text-white text-left leading-tight line-clamp-1"
            >
              {item.name}
            </button>
            <p className="text-xs text-zinc-500 mt-0.5 truncate">
              {[subs && `${subs} subscribers`, SOURCE_LABELS[item.source] ?? "Recommended"].filter(Boolean).join(" · ")}
            </p>
          </div>
          {!followMut.isSuccess && (
            <button
              onClick={() => dismissMut.mutate()}
              disabled={busy}
              title="Not interested"
              className="p-1 rounded-md text-zinc-600 hover:text-zinc-300 hover:bg-zinc-800 transition-colors disabled:opacity-40 shrink-0"
            >
              <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          )}
        </div>

        {rest.length > 0 && (
          <ul className="flex flex-col gap-0.5">
            {rest.slice(0, 2).map((v, i) => (
              <li key={i} className="text-xs text-zinc-500 truncate">· {v.title}</li>
            ))}
          </ul>
        )}

        {!featured && item.description && (
          <p className="text-xs text-zinc-500 line-clamp-2">{item.description}</p>
        )}

        <div className="mt-auto pt-1">
          {followMut.isSuccess ? (
            <p className="text-xs text-accent font-medium text-center py-1">Following ✓</p>
          ) : (
            <button
              onClick={() => followMut.mutate()}
              disabled={busy}
              className="w-full py-1.5 rounded-lg bg-accent text-black text-xs font-semibold hover:bg-yellow-300 transition-colors disabled:opacity-50"
            >
              Follow
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

function Tab({ active, onClick, children, count }) {
  return (
    <button
      onClick={onClick}
      className={[
        "px-4 py-2 text-sm font-medium border-b-2 transition-colors -mb-px flex items-center gap-2",
        active
          ? "border-accent text-zinc-100"
          : "border-transparent text-zinc-500 hover:text-zinc-300",
      ].join(" ")}
    >
      {children}
      {count > 0 && (
        <span className={`text-xs px-1.5 py-0.5 rounded-full ${active ? "bg-accent/20 text-accent" : "bg-zinc-800 text-zinc-500"}`}>
          {count}
        </span>
      )}
    </button>
  );
}

export default function DiscoveryPage() {
  const qc = useQueryClient();
  const [tab, setTab] = useState("channels");
  const [channelPage, setChannelPage] = useState(0);
  const [videoPage, setVideoPage] = useState(0);
  const [dismissedVideos, setDismissedVideos] = useState(new Set());

  const { data: channels = [], isLoading: loadingChannels } = useQuery({
    queryKey: ["discovery", channelPage],
    queryFn: () => getDiscovery(channelPage * PAGE_SIZE, PAGE_SIZE).then((r) => r.data),
    staleTime: 0,
    placeholderData: (prev) => prev,
  });

  const { data: videos = [], isLoading: loadingVideos } = useQuery({
    queryKey: ["discovery-videos", videoPage],
    queryFn: () => getDiscoveryVideos(videoPage * PAGE_SIZE, PAGE_SIZE).then((r) => r.data),
    staleTime: 0,
    placeholderData: (prev) => prev,
  });

  const refreshMut = useMutation({
    mutationFn: refreshDiscovery,
    onSuccess: () => setTimeout(() => {
      qc.invalidateQueries({ queryKey: ["discovery"] });
      qc.invalidateQueries({ queryKey: ["discovery-videos"] });
    }, 8000),
  });

  const handleDismissVideo = (video) => {
    setDismissedVideos(prev => new Set([...prev, video.youtube_video_id]));
    dismissDiscoveryVideo(video.youtube_video_id).then(() => {
      qc.invalidateQueries({ queryKey: ["discovery-videos"] });
    });
  };

  const visibleVideos = videos.filter(v => !dismissedVideos.has(v.youtube_video_id));
  const isEmpty = tab === "channels" ? channels.length === 0 : visibleVideos.length === 0;
  const isLoading = tab === "channels" ? loadingChannels : loadingVideos;
  const hasNextChannelPage = channels.length === PAGE_SIZE;
  const hasNextVideoPage = videos.length === PAGE_SIZE;

  return (
    <div className="flex flex-col gap-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <h1 className="font-display font-bold text-2xl text-zinc-100">Discover</h1>
        <button
          onClick={() => refreshMut.mutate()}
          disabled={refreshMut.isPending}
          className="flex items-center gap-2 text-sm font-medium px-4 py-2 bg-zinc-800 text-zinc-300 rounded-lg hover:bg-zinc-700 transition-colors disabled:opacity-60"
        >
          {refreshMut.isPending && (
            <svg className="w-3.5 h-3.5 animate-spin" fill="none" viewBox="0 0 24 24">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
              <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" />
            </svg>
          )}
          {refreshMut.isPending ? "Searching…" : "Find more"}
        </button>
      </div>

      {refreshMut.isSuccess && !refreshMut.isPending && (
        <div className="px-4 py-3 rounded-xl bg-zinc-800/60 border border-zinc-700/50 text-sm text-zinc-300">
          Searching YouTube for new channels — results will appear in a few seconds.
        </div>
      )}

      {/* Tabs */}
      <div className="flex items-center gap-1 border-b border-zinc-800">
        <Tab active={tab === "channels"} onClick={() => setTab("channels")} count={0}>
          Channels
        </Tab>
        <Tab active={tab === "videos"} onClick={() => setTab("videos")} count={0}>
          Videos
        </Tab>
      </div>

      {/* Content */}
      {isLoading ? (
        <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>
      ) : isEmpty ? (
        <div className="flex flex-col items-center gap-4 py-24 text-center">
          <div className="w-16 h-16 rounded-full bg-zinc-800 flex items-center justify-center">
            <svg className="w-7 h-7 text-zinc-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5}
                d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
            </svg>
          </div>
          <div>
            <p className="text-zinc-300 font-medium">Nothing here yet</p>
            <p className="text-zinc-500 text-sm mt-1 max-w-xs">
              Follow a few channels first, then hit "Find more" to discover similar ones.
            </p>
          </div>
          <button
            onClick={() => refreshMut.mutate()}
            disabled={refreshMut.isPending}
            className="mt-2 px-6 py-2.5 rounded-xl bg-accent text-black font-semibold text-sm hover:bg-yellow-300 transition-colors disabled:opacity-60"
          >
            {refreshMut.isPending ? "Searching…" : "Find channels"}
          </button>
        </div>
      ) : tab === "channels" ? (
        <>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
            {channels.map((item) => (
              <ChannelCard key={item.id} item={item} />
            ))}
          </div>
          <div className="flex items-center justify-center gap-3 pt-2">
            <button
              onClick={() => { setChannelPage(p => p - 1); scrollToTop(); }}
              disabled={channelPage === 0}
              className="px-4 py-2 rounded-lg bg-zinc-800 text-zinc-300 text-sm font-medium hover:bg-zinc-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
            >
              ← Prev
            </button>
            <span className="text-zinc-500 text-sm tabular-nums">Page {channelPage + 1}</span>
            <button
              onClick={() => { setChannelPage(p => p + 1); scrollToTop(); }}
              disabled={!hasNextChannelPage}
              className="px-4 py-2 rounded-lg bg-zinc-800 text-zinc-300 text-sm font-medium hover:bg-zinc-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
            >
              Next →
            </button>
          </div>
        </>
      ) : (
        <>
          <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
            {visibleVideos.map((v) => (
              <VideoCard
                key={v.youtube_video_id}
                video={{ ...v, is_recommended: true }}
                onDismiss={handleDismissVideo}
              />
            ))}
          </div>
          <div className="flex items-center justify-center gap-3 pt-2">
            <button
              onClick={() => { setVideoPage(p => p - 1); scrollToTop(); }}
              disabled={videoPage === 0}
              className="px-4 py-2 rounded-lg bg-zinc-800 text-zinc-300 text-sm font-medium hover:bg-zinc-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
            >
              ← Prev
            </button>
            <span className="text-zinc-500 text-sm tabular-nums">Page {videoPage + 1}</span>
            <button
              onClick={() => { setVideoPage(p => p + 1); scrollToTop(); }}
              disabled={!hasNextVideoPage}
              className="px-4 py-2 rounded-lg bg-zinc-800 text-zinc-300 text-sm font-medium hover:bg-zinc-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
            >
              Next →
            </button>
          </div>
        </>
      )}
    </div>
  );
}
