import { useState, useEffect, useRef } from "react";
import { useParams } from "react-router-dom";
import { useQuery, useMutation, useQueryClient, useInfiniteQuery } from "@tanstack/react-query";
import {
  getChannel, getChannelVideos, searchChannelYoutube,
  followChannel, unfollowChannel, indexChannel, indexChannelFull, exploreChannelOlder, fetchPopularVideos, downloadChannel,
  getChannelPlaylists, fetchChannelPlaylists, getPlaylistVideos, indexPlaylist,
} from "../api";
import VideoCard from "../components/VideoCard";

const LIMIT = 60;

const TABS = [
  { value: "videos",    label: "Videos" },
  { value: "popular",   label: "Popular" },
  { value: "playlists", label: "Playlists" },
];

const SORTS = [
  { value: "newest",    label: "Newest" },
  { value: "oldest",    label: "Oldest" },
  { value: "title",     label: "A–Z" },
  { value: "unwatched", label: "Unwatched" },
];

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);
}

export default function ChannelPage() {
  const { id } = useParams();
  const qc = useQueryClient();
  const [tab, setTab] = useState("videos");
  const [sort, setSort] = useState("newest");
  const [search, setSearch] = useState("");
  const [activeQ, setActiveQ] = useState("");
  const [indexing, setIndexing] = useState(false);
  const [explorePage, setExplorePage] = useState(2);
  const searchInputRef = useRef(null);
  const [openPlaylistId, setOpenPlaylistId] = useState(null);
  const [playlistOffset, setPlaylistOffset] = useState(0);

  const { data: channel, isLoading: loadingChannel } = useQuery({
    queryKey: ["channel", id],
    queryFn: () => getChannel(id).then((r) => r.data),
  });

  const effectiveSort = tab === "popular" ? "popular" : sort;

  const {
    data: videosData,
    isLoading: loadingVideos,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ["channel-videos", id, effectiveSort, activeQ],
    queryFn: ({ pageParam = 0 }) =>
      getChannelVideos(id, effectiveSort, pageParam, LIMIT, activeQ).then((r) => r.data),
    getNextPageParam: (lastPage, pages) =>
      lastPage.length === LIMIT ? pages.length * LIMIT : undefined,
    enabled: !!id,
  });

  const videos = videosData?.pages.flat() ?? [];

  // Refetch after background re-index
  const refetchedRef = useRef(false);
  useEffect(() => {
    if (!id || refetchedRef.current) return;
    refetchedRef.current = true;
    const t = setTimeout(() => {
      qc.invalidateQueries({ queryKey: ["channel", id] });
      qc.invalidateQueries({ queryKey: ["channel-videos", id] });
    }, 8000);
    return () => clearTimeout(t);
  }, [id, qc]);

  const followMut = useMutation({
    mutationFn: () =>
      channel?.status === "followed" ? unfollowChannel(id) : followChannel(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["channel", id] });
      qc.invalidateQueries({ queryKey: ["channels"] });
    },
  });

  const scheduleRefetch = (delayMs) => {
    setIndexing(true);
    setTimeout(() => {
      qc.invalidateQueries({ queryKey: ["channel-videos", id] });
      qc.invalidateQueries({ queryKey: ["channel", id] });
      setIndexing(false);
    }, delayMs);
  };

  const indexMut = useMutation({
    mutationFn: () => indexChannel(id),
    onSuccess: () => scheduleRefetch(6000),
  });

  const fullIndexMut = useMutation({
    mutationFn: () => indexChannelFull(id),
    onSuccess: () => scheduleRefetch(45000),
  });

  const exploreMut = useMutation({
    mutationFn: () => exploreChannelOlder(id, explorePage),
    onSuccess: () => {
      setExplorePage(p => p + 1);
      scheduleRefetch(20000);
    },
  });

  const popularMut = useMutation({
    mutationFn: () => fetchPopularVideos(id),
    onSuccess: () => scheduleRefetch(20000),
  });

  const deepSearchMut = useMutation({
    mutationFn: () => searchChannelYoutube(id, activeQ || search),
    onSuccess: () => scheduleRefetch(20000),
  });

  const { data: playlists = [], refetch: refetchPlaylists } = useQuery({
    queryKey: ["channel-playlists", id],
    queryFn: () => getChannelPlaylists(id).then((r) => r.data),
    enabled: !!id && tab === "playlists",
  });

  const fetchPlaylistsMut = useMutation({
    mutationFn: () => fetchChannelPlaylists(id),
    onSuccess: () => setTimeout(() => refetchPlaylists(), 8000),
  });

  const { data: playlistVideos, isLoading: loadingPlaylistVideos, refetch: refetchPlaylistVideos } = useQuery({
    queryKey: ["playlist-videos", openPlaylistId, playlistOffset],
    queryFn: () => getPlaylistVideos(openPlaylistId, playlistOffset, 60).then((r) => r.data),
    enabled: !!openPlaylistId,
  });

  const indexPlaylistMut = useMutation({
    mutationFn: (plId) => indexPlaylist(plId),
    onSuccess: () => setTimeout(() => refetchPlaylistVideos(), 15000),
  });

  const [dlResult, setDlResult] = useState(null);
  const dlMut = useMutation({
    mutationFn: () => downloadChannel(id),
    onSuccess: (res) => {
      setDlResult(res.data.queued);
      qc.invalidateQueries({ queryKey: ["downloads"] });
    },
  });

  const handleSearch = (e) => {
    e.preventDefault();
    setActiveQ(search.trim());
  };

  const clearSearch = () => {
    setSearch("");
    setActiveQ("");
    searchInputRef.current?.focus();
  };

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

  if (!channel) return <p className="text-zinc-500">Channel not found.</p>;

  const isFollowed = channel.status === "followed";
  const isPending = indexMut.isPending || fullIndexMut.isPending || deepSearchMut.isPending || exploreMut.isPending || popularMut.isPending || indexing;

  return (
    <div className="flex flex-col gap-5">
      {/* Banner */}
      <div className={`-mx-4 -mt-6 relative ${channel.banner_url ? "" : "bg-zinc-900"} rounded-b-2xl overflow-hidden`}>
        {channel.banner_url && (
          <img src={channel.banner_url} alt="" className="w-full h-28 sm:h-48 object-cover" />
        )}
        <div className={channel.banner_url ? "absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent" : ""} />

        <div className={`${channel.banner_url ? "absolute bottom-0 inset-x-0" : ""} px-4 pb-4 pt-3 flex items-end gap-3`}>
          {channel.thumbnail_url ? (
            <img src={channel.thumbnail_url} alt={channel.name}
              className="w-14 h-14 sm:w-20 sm:h-20 rounded-full object-cover shrink-0 ring-2 ring-black/40" />
          ) : (
            <div className="w-14 h-14 sm:w-20 sm:h-20 rounded-full bg-zinc-800 flex items-center justify-center text-2xl font-display font-bold text-zinc-400 shrink-0">
              {channel.name?.[0]?.toUpperCase()}
            </div>
          )}
          <div className="flex-1 min-w-0">
            <h1 className="font-display font-bold text-lg sm:text-2xl text-white drop-shadow leading-tight">{channel.name}</h1>
            <p className="text-xs text-zinc-400 mt-0.5 drop-shadow">
              {[
                formatSubs(channel.subscriber_count) && `${formatSubs(channel.subscriber_count)} subs`,
                channel.video_count && `${channel.video_count} indexed`,
              ].filter(Boolean).join(" · ")}
            </p>
          </div>

          <div className="hidden sm:flex items-center gap-2 shrink-0">
            <button onClick={() => followMut.mutate()} disabled={followMut.isPending}
              className={`text-sm font-medium px-4 py-1.5 rounded-lg transition-colors ${isFollowed ? "bg-zinc-700/80 text-zinc-300 hover:bg-zinc-600" : "bg-zinc-800/80 text-zinc-300 hover:bg-zinc-700"}`}>
              {isFollowed ? "Following" : "Follow"}
            </button>
            <button onClick={() => dlMut.mutate()} disabled={dlMut.isPending}
              className="text-sm font-medium px-4 py-1.5 rounded-lg bg-accent text-black hover:bg-zinc-100 transition-colors disabled:opacity-60">
              {dlMut.isPending ? "Queuing…" : "Download all"}
            </button>
          </div>
        </div>
      </div>

      {/* Mobile actions */}
      <div className="sm:hidden flex items-center gap-2 -mt-1">
        <button onClick={() => followMut.mutate()} disabled={followMut.isPending}
          className="flex-1 text-sm font-medium py-2 rounded-lg bg-zinc-800 text-zinc-300 hover:bg-zinc-700 transition-colors">
          {isFollowed ? "Following ✓" : "Follow"}
        </button>
        <button onClick={() => dlMut.mutate()} disabled={dlMut.isPending}
          className="flex-1 text-sm font-medium py-2 rounded-lg bg-accent text-black hover:bg-zinc-100 transition-colors disabled:opacity-60">
          {dlMut.isPending ? "Queuing…" : "Download all"}
        </button>
      </div>

      {dlResult != null && (
        <p className="text-xs text-zinc-400 font-mono -mt-2">
          {dlResult === 0 ? "Already up to date" : `${dlResult} downloads queued`}
        </p>
      )}

      {channel.description && (
        <p className="text-xs text-zinc-500 line-clamp-2 -mt-1">{channel.description}</p>
      )}

      {/* Search bar */}
      <form onSubmit={handleSearch} className="flex items-center gap-2">
        <div className="relative flex-1">
          <input
            ref={searchInputRef}
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search videos…"
            className="w-full bg-zinc-900 border border-zinc-800 rounded-lg px-3 py-1.5 text-sm text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-zinc-600 transition-colors"
          />
          {search && (
            <button type="button" onClick={clearSearch}
              className="absolute right-2 top-1/2 -translate-y-1/2 text-zinc-600 hover:text-zinc-400">
              <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>
        <button type="submit"
          className="text-sm px-3 py-1.5 rounded-lg bg-zinc-800 text-zinc-300 hover:bg-zinc-700 transition-colors shrink-0">
          Filter
        </button>
        {activeQ && (
          <button
            type="button"
            onClick={() => deepSearchMut.mutate()}
            disabled={deepSearchMut.isPending || indexing}
            className="text-sm px-3 py-1.5 rounded-lg text-zinc-400 hover:text-zinc-100 transition-colors shrink-0 disabled:opacity-40"
          >
            Search YouTube
          </button>
        )}
      </form>

      {/* Tabs + controls */}
      <div className="flex items-center justify-between gap-3 -mt-1 border-b border-zinc-800/60 pb-3">
        <div className="flex items-center gap-0.5">
          {TABS.map(t => (
            <button key={t.value} onClick={() => setTab(t.value)}
              className={`text-sm px-3 py-1 rounded-md transition-colors font-medium ${
                tab === t.value ? "text-zinc-100" : "text-zinc-500 hover:text-zinc-300"
              }`}>
              {t.label}
            </button>
          ))}
        </div>

        <div className="flex items-center gap-3">
          {isPending && (
            <span className="text-xs text-zinc-500 flex items-center gap-1.5">
              <svg className="w-3 h-3 animate-spin" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" />
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" />
              </svg>
              Fetching…
            </span>
          )}
          {tab === "popular" ? (
            <button onClick={() => popularMut.mutate()} disabled={isPending}
              className="text-xs text-zinc-400 hover:text-zinc-100 font-medium transition-colors disabled:opacity-40">
              Fetch popular
            </button>
          ) : (
            <>
              <button onClick={() => indexMut.mutate()} disabled={isPending}
                className="text-xs text-zinc-500 hover:text-zinc-300 transition-colors disabled:opacity-40">
                Fetch recent
              </button>
              <button onClick={() => fullIndexMut.mutate()} disabled={isPending}
                className="text-xs text-zinc-400 hover:text-zinc-100 font-medium transition-colors disabled:opacity-40">
                Fetch all
              </button>
            </>
          )}
        </div>
      </div>

      {/* Sort bar — videos tab only */}
      {tab === "videos" && (
        <div className="flex items-center gap-0.5 -mt-1">
          {SORTS.map(s => (
            <button key={s.value} onClick={() => setSort(s.value)}
              className={`text-xs px-2.5 py-1 rounded-md transition-colors ${
                sort === s.value ? "bg-zinc-700 text-zinc-100" : "text-zinc-500 hover:text-zinc-300"
              }`}>
              {s.label}
            </button>
          ))}
        </div>
      )}

      {/* Playlist browser */}
      {tab === "playlists" && (
        openPlaylistId ? (
          <div className="flex flex-col gap-3">
            <div className="flex items-center gap-3">
              <button onClick={() => { setOpenPlaylistId(null); setPlaylistOffset(0); }}
                className="text-xs text-zinc-400 hover:text-zinc-100 transition-colors">
                ← Back to playlists
              </button>
              {(() => {
                const pl = playlists.find(p => p.id === openPlaylistId);
                return pl ? <span className="text-sm font-medium text-zinc-200 truncate">{pl.title}</span> : null;
              })()}
              <button onClick={() => indexPlaylistMut.mutate(openPlaylistId)}
                disabled={indexPlaylistMut.isPending}
                className="ml-auto text-xs text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40">
                {indexPlaylistMut.isPending ? "Indexing…" : "Re-index"}
              </button>
            </div>
            {loadingPlaylistVideos ? (
              <div className="flex items-center justify-center py-8">
                <div className="w-6 h-6 border-2 border-accent border-t-transparent rounded-full animate-spin" />
              </div>
            ) : playlistVideos?.length ? (
              <>
                <div className="flex flex-col gap-1">
                  {playlistVideos.map((v) => (
                    <VideoCard key={v.youtube_video_id} video={v} variant="list" />
                  ))}
                </div>
                <div className="flex items-center justify-center gap-4 mt-2">
                  {playlistOffset > 0 && (
                    <button onClick={() => setPlaylistOffset(o => Math.max(0, o - 60))}
                      className="text-sm text-zinc-500 hover:text-zinc-300 transition-colors">
                      Previous
                    </button>
                  )}
                  {playlistVideos.length === 60 && (
                    <button onClick={() => setPlaylistOffset(o => o + 60)}
                      className="text-sm text-zinc-500 hover:text-zinc-300 transition-colors">
                      Next
                    </button>
                  )}
                </div>
              </>
            ) : (
              <div className="py-8 flex flex-col items-center gap-3">
                <p className="text-zinc-500 text-sm">No videos indexed for this playlist yet.</p>
                <button onClick={() => indexPlaylistMut.mutate(openPlaylistId)}
                  disabled={indexPlaylistMut.isPending}
                  className="text-sm text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40 underline">
                  {indexPlaylistMut.isPending ? "Indexing…" : "Index playlist"}
                </button>
              </div>
            )}
          </div>
        ) : (
          <div className="flex flex-col gap-3">
            <div className="flex items-center justify-between">
              <span className="text-xs text-zinc-500">{playlists.length} playlists</span>
              <button onClick={() => fetchPlaylistsMut.mutate()}
                disabled={fetchPlaylistsMut.isPending}
                className="text-xs text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40">
                {fetchPlaylistsMut.isPending ? "Fetching…" : "Fetch playlists"}
              </button>
            </div>
            {playlists.length === 0 ? (
              <div className="py-8 flex flex-col items-center gap-3">
                <p className="text-zinc-500 text-sm">No playlists fetched yet.</p>
                <button onClick={() => fetchPlaylistsMut.mutate()}
                  disabled={fetchPlaylistsMut.isPending}
                  className="text-sm text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40 underline">
                  Fetch playlists from YouTube
                </button>
              </div>
            ) : (
              <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
                {playlists.map(pl => (
                  <button key={pl.id} onClick={() => { setOpenPlaylistId(pl.id); setPlaylistOffset(0); }}
                    className="text-left flex flex-col gap-1.5 rounded-lg overflow-hidden hover:bg-zinc-800/50 transition-colors p-1.5">
                    <div className="relative aspect-video w-full rounded overflow-hidden bg-zinc-800">
                      {pl.thumbnail_url ? (
                        <img src={pl.thumbnail_url} alt="" className="w-full h-full object-cover" />
                      ) : (
                        <div className="w-full h-full flex items-center justify-center text-zinc-600">
                          <svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5}
                              d="M4 6h16M4 10h16M4 14h8M4 18h8" />
                          </svg>
                        </div>
                      )}
                      <div className="absolute bottom-1 right-1 bg-black/70 text-white text-xs px-1 rounded">
                        {pl.video_count}
                      </div>
                    </div>
                    <p className="text-xs font-medium text-zinc-200 line-clamp-2 leading-snug px-0.5">{pl.title}</p>
                    {pl.indexed_at && (
                      <p className="text-xs text-zinc-600 px-0.5">Indexed</p>
                    )}
                  </button>
                ))}
              </div>
            )}
          </div>
        )
      )}

      {/* Video list */}
      {tab !== "playlists" && (loadingVideos ? (
        <div className="flex items-center justify-center py-8">
          <div className="w-6 h-6 border-2 border-accent border-t-transparent rounded-full animate-spin" />
        </div>
      ) : videos.length ? (
        <div className="flex flex-col gap-1">
          {videos.map((v) => (
            <VideoCard key={v.youtube_video_id} video={{ ...v, channel_name: channel.name }} variant="list" />
          ))}

          {hasNextPage ? (
            <button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}
              className="mt-4 self-center text-sm text-zinc-500 hover:text-zinc-300 transition-colors disabled:opacity-40 py-2 px-4">
              {isFetchingNextPage ? "Loading…" : "Load more"}
            </button>
          ) : !activeQ && tab === "videos" && (
            <div className="mt-4 flex flex-col items-center gap-3 py-4 border-t border-zinc-800/50">
              <p className="text-xs text-zinc-600">{videos.length} videos indexed</p>
              <div className="flex items-center gap-4">
                <button onClick={() => exploreMut.mutate()} disabled={isPending}
                  className="text-xs text-zinc-400 hover:text-zinc-100 font-medium transition-colors disabled:opacity-40">
                  Explore older videos
                </button>
                <span className="text-zinc-800 text-xs">·</span>
                <button onClick={() => fullIndexMut.mutate()} disabled={isPending}
                  className="text-xs text-zinc-500 hover:text-zinc-300 transition-colors disabled:opacity-40">
                  Fetch entire history
                </button>
              </div>
            </div>
          )}
        </div>
      ) : (
        <div className="py-8 flex flex-col items-center gap-3">
          <p className="text-zinc-500 text-sm">
            {activeQ
              ? `No indexed videos match "${activeQ}"`
              : tab === "popular"
              ? "No popular videos fetched yet."
              : "No videos indexed yet."}
          </p>
          {activeQ ? (
            <button onClick={() => deepSearchMut.mutate()} disabled={isPending}
              className="text-sm text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40 underline">
              Search YouTube for "{activeQ}"
            </button>
          ) : tab === "popular" ? (
            <button onClick={() => popularMut.mutate()} disabled={isPending}
              className="text-sm text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40 underline">
              Fetch popular videos from YouTube
            </button>
          ) : (
            <button onClick={() => fullIndexMut.mutate()} disabled={isPending}
              className="text-sm text-zinc-400 hover:text-zinc-100 transition-colors disabled:opacity-40 underline">
              Fetch all videos
            </button>
          )}
        </div>
      ))}
    </div>
  );
}
