import { useState, useMemo } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { homeFeed, surpriseMe, getSettings, updateSettings, getChannels, markChannelsSeen } from "../api";
import VideoCard from "../components/VideoCard";
import { scrollToTop } from "../utils/scroll";

const PAGE_SIZE = 25;

const FEED_MODES = [
  { value: "ranked",        label: "For you",      hint: "Ranked by your taste" },
  { value: "chronological", label: "New",           hint: "Everything in date order" },
  { value: "rediscover",    label: "Rediscover",    hint: "Older unwatched videos ranked by your taste" },
  { value: "random",        label: "Explore",       hint: "Random from discovery pool" },
  { value: "inbox",         label: "Inbox",         hint: "New from followed channels since last visit" },
];

export default function Home() {
  const qc = useQueryClient();
  const [surpriseResults, setSurpriseResults] = useState(null);
  const [mode, setMode] = useState(() => localStorage.getItem("home-feed-mode") ?? "ranked");
  const [page, setPage] = useState(0);
  const [dismissed, setDismissed] = useState(new Set());
  const [shuffleKey, setShuffleKey] = useState(0);
  const [duration, setDuration] = useState("");
  const [viewMode, setViewMode] = useState(() => localStorage.getItem("home-view-mode") ?? "list");

  const toggleViewMode = () => {
    const next = viewMode === "grid" ? "list" : "grid";
    localStorage.setItem("home-view-mode", next);
    setViewMode(next);
  };

  const { data: userSettings } = useQuery({
    queryKey: ["settings"],
    queryFn: () => getSettings().then(r => r.data),
    staleTime: 60_000,
  });

  const { data: channels = [] } = useQuery({
    queryKey: ["channels"],
    queryFn: () => getChannels().then(r => r.data),
    staleTime: 60_000,
  });
  const inboxCount = channels.reduce((sum, c) => sum + (c.new_count ?? 0), 0);

  const markSeenMut = useMutation({
    mutationFn: () => markChannelsSeen(),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["channels"] }),
  });
  const hideWatched = userSettings?.hide_watched_from_feed ?? false;

  const handleHideWatchedToggle = () => {
    const next = !hideWatched;
    updateSettings({ hide_watched_from_feed: next });
    qc.setQueryData(["settings"], old => old ? { ...old, hide_watched_from_feed: next } : old);
  };

  const { data: feedData = [], isLoading: loadingFeed } = useQuery({
    queryKey: ["home-feed", mode, page, hideWatched, duration, mode === "random" ? shuffleKey : 0],
    queryFn: () => homeFeed(page, PAGE_SIZE, mode, duration).then((r) => r.data),
    staleTime: 10 * 60_000,
    placeholderData: (prev) => prev,
  });

  const surpriseMut = useMutation({
    mutationFn: () => surpriseMe().then((r) => r.data),
    onSuccess: (data) => setSurpriseResults(data),
  });

  const visibleFeed = useMemo(
    () => feedData.filter(v => !dismissed.has(v.youtube_video_id)),
    [feedData, dismissed],
  );

  const hasFollowing = channels.length > 0 || feedData.length > 0 || page > 0;
  const hasNextPage = mode === "ranked"
    ? feedData.filter(v => !v.is_recommended).length === PAGE_SIZE
    : feedData.length === PAGE_SIZE;

  const handleDismiss = (video) =>
    setDismissed(prev => new Set([...prev, video.youtube_video_id]));

  const handleModeChange = (newMode) => {
    localStorage.setItem("home-feed-mode", newMode);
    setMode(newMode);
    setPage(0);
    setDismissed(new Set());
  };

  const handleDurationChange = (d) => {
    setDuration(prev => prev === d ? "" : d);
    setPage(0);
    setDismissed(new Set());
  };

  const handleReshuffle = () => {
    setShuffleKey(k => k + 1);
    setPage(0);
    setDismissed(new Set());
    scrollToTop();
  };

  return (
    <div className="flex flex-col gap-10">
      {loadingFeed ? (
        <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>
      ) : hasFollowing ? (
        <section className="flex flex-col gap-6">
          {/* Title row + secondary controls */}
          <div className="flex items-center justify-between gap-2">
            <h2 className="font-display font-semibold text-base sm:text-xl text-zinc-200">Home</h2>
            <div className="flex items-center gap-1.5">
              <button
                onClick={toggleViewMode}
                title={viewMode === "grid" ? "Switch to list view" : "Switch to grid view"}
                className="flex items-center justify-center w-7 h-7 rounded-md text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 transition-colors"
              >
                {viewMode === "grid" ? (
                  <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="M4 6h16M4 10h16M4 14h16M4 18h16" />
                  </svg>
                ) : (
                  <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="M4 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1V5zm10 0a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V5zM4 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1v-4zm10 0a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z" />
                  </svg>
                )}
              </button>
              <button
                onClick={handleHideWatchedToggle}
                title={hideWatched ? "Showing unwatched only" : "Showing all videos"}
                className={[
                  "flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors",
                  hideWatched ? "text-accent" : "text-zinc-600 hover:text-zinc-400",
                ].join(" ")}
              >
                {hideWatched ? "Unwatched" : "All"}
              </button>
            </div>
          </div>

          {/* Mode switcher — own row, full width on mobile */}
          <div className="flex items-center gap-0.5 bg-zinc-900 rounded-lg p-0.5 self-start">
            {FEED_MODES.map(m => (
              <button
                key={m.value}
                onClick={() => handleModeChange(m.value)}
                title={m.hint}
                className={[
                  "relative px-2.5 py-1 rounded-md text-xs font-medium transition-colors",
                  mode === m.value ? "bg-zinc-700 text-zinc-100" : "text-zinc-500 hover:text-zinc-300",
                ].join(" ")}
              >
                {m.label}
                {m.value === "inbox" && inboxCount > 0 && (
                  <span className="absolute -top-1 -right-1 min-w-[13px] h-3 bg-zinc-200 text-zinc-900 text-[8px] font-bold rounded-full flex items-center justify-center px-0.5 leading-none">
                    {inboxCount > 99 ? "99+" : inboxCount}
                  </span>
                )}
              </button>
            ))}
          </div>

          {/* Duration filter */}
          <div className="flex items-center gap-1.5">
            {[["short", "< 10 min"], ["medium", "10–30 min"], ["long", "30+ min"]].map(([val, label]) => (
              <button
                key={val}
                onClick={() => handleDurationChange(val)}
                className={[
                  "px-2.5 py-1 rounded-full text-xs font-medium transition-colors",
                  duration === val
                    ? "bg-zinc-700 text-zinc-100"
                    : "text-zinc-600 hover:text-zinc-400",
                ].join(" ")}
              >
                {label}
              </button>
            ))}
          </div>

          {mode === "inbox" && (
            <div className="flex items-center justify-between">
              <p className="text-xs text-zinc-600">Unwatched videos from followed channels since your last visit.</p>
              <button
                onClick={() => markSeenMut.mutate()}
                disabled={markSeenMut.isPending}
                className="flex items-center gap-1.5 text-xs text-zinc-500 hover:text-zinc-300 transition-colors shrink-0 ml-4 disabled:opacity-50"
              >
                Mark all read
              </button>
            </div>
          )}
          {mode === "chronological" && (
            <p className="text-xs text-zinc-600">All videos from channels you follow, newest first.</p>
          )}
          {mode === "random" && (
            <div className="flex items-center justify-between">
              <p className="text-xs text-zinc-600">Random from your discovery pool — no weighting, no ranking.</p>
              <button
                onClick={handleReshuffle}
                className="flex items-center gap-1.5 text-xs text-zinc-500 hover:text-zinc-300 transition-colors shrink-0 ml-4"
              >
                <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="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                </svg>
                Reshuffle
              </button>
            </div>
          )}

          {visibleFeed.length === 0 && !loadingFeed ? (
            <p className="text-center text-zinc-500 text-sm py-12">
              {mode === "inbox" ? "You're all caught up — no new videos since your last visit." : "Nothing to show here."}
            </p>
          ) : (
            <div className={viewMode === "list" ? "flex flex-col gap-2" : "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4"}>
              {visibleFeed.map((v) => (
                <VideoCard
                  key={v.youtube_video_id}
                  video={v}
                  variant={viewMode}
                  onDismiss={v.is_recommended ? handleDismiss : undefined}
                />
              ))}
            </div>
          )}
          <div className="flex items-center justify-center gap-3 pt-2">
            <button
              onClick={() => { setPage(p => p - 1); scrollToTop(); }}
              disabled={page === 0}
              className="px-3 py-1.5 rounded-lg bg-zinc-800 text-zinc-300 text-xs font-medium hover:bg-zinc-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
            >
              ← Prev
            </button>
            <span className="text-zinc-500 text-xs tabular-nums">Page {page + 1}</span>
            <button
              onClick={() => { setPage(p => p + 1); scrollToTop(); }}
              disabled={!hasNextPage}
              className="px-3 py-1.5 rounded-lg bg-zinc-800 text-zinc-300 text-xs font-medium hover:bg-zinc-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
            >
              Next →
            </button>
          </div>
        </section>
      ) : (
        <section className="flex flex-col items-center py-16 gap-4 text-center">
          <p className="text-zinc-400 text-sm max-w-sm">
            Follow some channels to get a personalised feed. Or let us pick something.
          </p>
          <button
            onClick={() => surpriseMut.mutate()}
            disabled={surpriseMut.isPending}
            className="bg-accent text-black font-display font-bold text-lg px-8 py-4 rounded-2xl hover:scale-105 active:scale-95 transition-all disabled:opacity-60 shadow-lg"
          >
            <span className="flex items-center gap-2">
              <span className="text-2xl">✦</span>
              {surpriseMut.isPending ? "Picking something…" : "Surprise Me"}
            </span>
          </button>
          {surpriseResults && (
            <div className="mt-6 w-full grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
              {surpriseResults.map((v) => (
                <VideoCard key={v.youtube_video_id || v.video_id} video={{
                  youtube_video_id: v.youtube_video_id,
                  title: v.title,
                  thumbnail_url: v.thumbnail_url,
                  duration_seconds: v.duration_seconds,
                  channel_name: v.channel_name,
                  is_downloaded: v.downloaded,
                  is_watched: v.watched,
                }} />
              ))}
            </div>
          )}
        </section>
      )}

      {/* Surprise Me — footer */}
      {hasFollowing && (
        <section className="flex flex-col items-center gap-3 py-4 border-t border-zinc-800/60">
          <p className="text-zinc-600 text-xs">Want something random?</p>
          <button
            onClick={() => surpriseMut.mutate()}
            disabled={surpriseMut.isPending}
            className="flex items-center gap-2 px-5 py-2 rounded-full bg-zinc-800 text-zinc-300 text-sm font-medium hover:bg-zinc-700 transition-colors disabled:opacity-60"
          >
            <span>✦</span>
            {surpriseMut.isPending ? "Picking…" : "Surprise Me"}
          </button>
          {surpriseResults && (
            <div className="mt-4 w-full grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
              {surpriseResults.map((v) => (
                <VideoCard key={v.youtube_video_id || v.video_id} video={{
                  youtube_video_id: v.youtube_video_id,
                  title: v.title,
                  thumbnail_url: v.thumbnail_url,
                  duration_seconds: v.duration_seconds,
                  channel_name: v.channel_name,
                  is_downloaded: v.downloaded,
                  is_watched: v.watched,
                }} />
              ))}
            </div>
          )}
        </section>
      )}
    </div>
  );
}
