/**
 * Post-login "Select Profile" screen.
 *
 * UX:
 *   • Login redirects here (users only, not admins).
 *   • 0 shared profiles  → quietly bounce to /  (user can still add their own)
 *   • 1 shared profile   → auto-select + progressive load → /
 *   • N shared profiles  → picker; on tap → progressive load → /
 *
 * Progressive load:
 *   [1/3] Channels …  → "✓ 1,234 channels"
 *   [2/3] Movies …    → "✓ 567 movies"
 *   [3/3] Series …    → "✓ 89 series"
 *   then navigate("/")
 *
 * Relies on useSharedProfilesSync having already mirrored the admin
 * profiles into IndexedDB on auth-hydrate. We just read from that.
 */
import { useEffect, useMemo, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
  Tv,
  Film,
  Clapperboard,
  Loader2,
  Check,
  CircleAlert,
  Plus,
  SkipForward,
  Radio,
  Play,
  Link2,
} from "lucide-react";
import { useAuth } from "@/hooks/useAuth";
import { useProfiles } from "@/hooks/useProfiles";
import { useXtreamData as _unused } from "@/hooks/useXtreamData";
import { xtreamApi } from "@/lib/xtream";
import { m3uApi } from "@/lib/m3u";
import { stalkerApi } from "@/lib/stalker";
import { useQueryClient } from "@tanstack/react-query";
import type { XtreamProfile } from "@/types/xtream";
import {
  FocusableTile,
  FocusableButton,
  FocusableSection,
} from "@/components/focusable";
import { setFocus as spatialSetFocus } from "@noriginmedia/norigin-spatial-navigation";

type Step = "channels" | "movies" | "series" | "done";

type Counts = { channels: number; movies: number; series: number };

const kindIcon = (k?: string) => {
  if (k === "m3u") return Link2;
  if (k === "stalker") return Radio;
  return Play;
};

const kindLabel = (k?: string) => {
  if (k === "m3u") return "M3U Playlist";
  if (k === "stalker") return "Stalker / MAC Portal";
  return "Xtream Codes";
};

const SelectProfile = () => {
  const navigate = useNavigate();
  const { t } = useTranslation();
  const { user, loading: authLoading } = useAuth();
  const { profiles, setActiveProfileId } = useProfiles();
  const qc = useQueryClient();

  // Only show shared-source profiles in the picker. The user's own
  // personal profiles are ignored here (they already worked fine).
  const shared = useMemo(
    () => profiles.filter((p) => p.id.startsWith("shared:")),
    [profiles],
  );

  const [selecting, setSelecting] = useState<XtreamProfile | null>(null);
  const [step, setStep] = useState<Step>("channels");
  const [counts, setCounts] = useState<Counts>({
    channels: 0,
    movies: 0,
    series: 0,
  });
  const [error, setError] = useState<string | null>(null);

  // Redirect rules ───────────────────────────────────────────────
  // Per the Jan 2026 product change, subscribers no longer see the profile
  // picker at all — admin-managed profiles auto-activate in the background
  // (useSharedProfilesSync + useSubscriberProfileSync). Any visit here just
  // bounces straight home. We keep the route for backwards-compat with
  // older bookmarks / deep links.
  useEffect(() => {
    if (authLoading) return;
    if (!user) {
      navigate("/welcome", { replace: true });
      return;
    }
    if (user.role === "admin") {
      navigate("/admin", { replace: true });
      return;
    }
    // role === "user": straight to channels/movies grid.
    navigate("/", { replace: true });
  }, [authLoading, user, navigate]);

  // Auto-select if exactly 1 shared profile ──────────────────────
  useEffect(() => {
    if (authLoading) return;
    if (!user || user.role !== "user") return;
    if (selecting) return;
    if (shared.length === 1) {
      void handlePick(shared[0]);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [shared, authLoading, user]);

  // Bounce to home if there are no shared profiles at all ────────
  useEffect(() => {
    if (authLoading) return;
    if (!user || user.role !== "user") return;
    if (shared.length === 0) {
      // Small delay so the user sees the screen briefly and knows
      // why we're bouncing. Accessibility > instant redirect.
      const t = window.setTimeout(() => navigate("/", { replace: true }), 900);
      return () => window.clearTimeout(t);
    }
  }, [shared.length, authLoading, user, navigate]);

  // Drop initial focus on the first profile so remote arrows have an
  // anchor when the screen mounts.
  useEffect(() => {
    if (selecting) return;
    if (shared.length === 0) return;
    const t = window.setTimeout(() => spatialSetFocus("select-profile-0"), 200);
    return () => window.clearTimeout(t);
  }, [shared.length, selecting]);

  const handlePick = async (p: XtreamProfile) => {
    setError(null);
    setSelecting(p);
    setStep("channels");
    setCounts({ channels: 0, movies: 0, series: 0 });
    setActiveProfileId(p.id);

    try {
      // ── Step 1: Channels ─────────────────────────────────────
      setStep("channels");
      const channels = await loadChannels(p);
      qc.setQueryData(["xtream", p.id, "live"], channels);
      setCounts((c) => ({ ...c, channels: channels.length }));

      // ── Step 2: Movies ───────────────────────────────────────
      setStep("movies");
      const movies = await loadMovies(p);
      qc.setQueryData(["xtream", p.id, "movies"], movies);
      setCounts((c) => ({ ...c, movies: movies.length }));

      // ── Step 3: Series ───────────────────────────────────────
      setStep("series");
      const series = await loadSeries(p);
      qc.setQueryData(["xtream", p.id, "series"], series);
      setCounts((c) => ({ ...c, series: series.length }));

      // ── Done ─────────────────────────────────────────────────
      setStep("done");
      // Small pause so the user sees the final "✓ All loaded" state.
      await new Promise((r) => setTimeout(r, 700));
      navigate("/", { replace: true });
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Unknown error";
      setError(msg);
    }
  };

  // Per-kind loaders that return the right array for each bucket.
  // We run them sequentially so the UI can animate progress.
  const loadChannels = async (p: XtreamProfile) => {
    if (p.kind === "stalker")
      return (await stalkerApi.fetchAll(p.portalUrl!, p.macAddress!)).channels;
    if (p.kind === "m3u") return classifyM3u(p).then((x) => x.channels);
    return xtreamApi.getLiveStreams(p);
  };
  const loadMovies = async (p: XtreamProfile) => {
    if (p.kind === "stalker")
      return (await stalkerApi.fetchAll(p.portalUrl!, p.macAddress!)).movies;
    if (p.kind === "m3u") return classifyM3u(p).then((x) => x.movies);
    return xtreamApi.getMovies(p);
  };
  const loadSeries = async (p: XtreamProfile) => {
    if (p.kind === "stalker")
      return (await stalkerApi.fetchAll(p.portalUrl!, p.macAddress!)).series;
    if (p.kind === "m3u") return classifyM3u(p).then((x) => x.series);
    return xtreamApi.getSeries(p);
  };
  const classifyM3u = async (p: XtreamProfile) => {
    const entries =
      p.m3uContent && p.m3uContent.trim().length
        ? m3uApi.parsePlaylistText(p.m3uContent)
        : await m3uApi.fetchPlaylist(p.m3uUrl!);
    return m3uApi.classify(entries);
  };

  // ── Render ──────────────────────────────────────────────────
  return (
    <div
      data-testid="select-profile-page"
      className="relative h-screen w-full overflow-hidden flex items-center justify-center px-4 py-8"
    >
      <div
        className="absolute inset-0 bg-cover bg-center bg-no-repeat"
        style={{ backgroundImage: "url('/images/nebula-bg.png')" }}
      />
      <div className="absolute inset-0 bg-background/70" />

      <motion.div
        initial={{ opacity: 0, y: 24 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.5 }}
        className="relative z-10 glass-card rounded-3xl p-6 sm:p-8 w-full max-w-lg"
      >
        <div className="flex flex-col items-center mb-6">
          <div
            className="w-14 h-14 rounded-2xl glass flex items-center justify-center mb-3"
            style={{
              border: "1px solid hsla(40, 80%, 55%, 0.4)",
              boxShadow: "0 0 40px hsla(40, 80%, 55%, 0.25)",
            }}
          >
            <Tv className="w-7 h-7 text-primary gold-glow" strokeWidth={1.4} />
          </div>
          <h1 className="font-display text-xl tracking-[0.3em] gold-text">
            {t("selectProfile.title", "SELECT PROFILE")}
          </h1>
          <p className="text-muted-foreground text-[11px] tracking-[0.2em] uppercase mt-2 text-center">
            {selecting
              ? t("selectProfile.loading", "Loading your content…")
              : t(
                  "selectProfile.subtitle",
                  "Pick a profile to start watching",
                )}
          </p>
        </div>

        {/* ── Picker (pre-selection) ─────────────────────────── */}
        {!selecting && (
          <AnimatePresence>
            {shared.length === 0 ? (
              <motion.div
                key="empty"
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                className="flex flex-col items-center py-10 text-center"
                data-testid="select-profile-empty"
              >
                <Loader2 className="w-6 h-6 animate-spin text-primary mb-3" />
                <p className="text-foreground text-sm mb-1">
                  {t(
                    "selectProfile.noneTitle",
                    "No profile configured yet",
                  )}
                </p>
                <p className="text-muted-foreground text-xs">
                  {t(
                    "selectProfile.noneDesc",
                    "Taking you to the home screen…",
                  )}
                </p>
              </motion.div>
            ) : (
              <FocusableSection
                key="list"
                focusKey="select-profile-list-section"
                className="space-y-2"
                data-testid="select-profile-list"
              >
                {shared.map((p, i) => {
                  const Icon = kindIcon(p.kind);
                  return (
                    <FocusableTile
                      key={p.id}
                      focusKey={`select-profile-${i}`}
                      onClick={() => void handlePick(p)}
                      onEnter={() => void handlePick(p)}
                      data-testid={`select-profile-${i}`}
                      className="w-full flex items-center gap-3 px-4 py-3 rounded-2xl glass border border-transparent transition-all group text-start cursor-pointer outline-none"
                    >
                      <div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center shrink-0 group-hover:bg-primary/20">
                        <Icon className="w-5 h-5 text-primary" />
                      </div>
                      <div className="flex-1 min-w-0">
                        <p className="text-foreground text-sm font-medium truncate">
                          {p.name}
                        </p>
                        <p className="text-muted-foreground text-[11px] truncate">
                          {kindLabel(p.kind)}
                        </p>
                      </div>
                      <Play
                        className="w-4 h-4 text-muted-foreground group-hover:text-primary"
                        strokeWidth={2}
                      />
                    </FocusableTile>
                  );
                })}

                {/* Skip / manual options */}
                <div className="flex items-center gap-2 pt-3">
                  <FocusableButton
                    focusKey="select-profile-skip"
                    onEnter={() => navigate("/", { replace: true })}
                    onClick={() => navigate("/", { replace: true })}
                    data-testid="select-profile-skip"
                    className="flex-1 flex items-center justify-center gap-2 px-3 py-2.5 rounded-xl glass text-muted-foreground hover:text-foreground hover:border-primary/40 text-xs outline-none"
                  >
                    <SkipForward className="w-3.5 h-3.5" />
                    {t("selectProfile.skip", "Skip for now")}
                  </FocusableButton>
                  <FocusableButton
                    focusKey="select-profile-add-own"
                    onEnter={() => navigate("/account", { replace: true })}
                    onClick={() => navigate("/account", { replace: true })}
                    data-testid="select-profile-add-own"
                    className="flex-1 flex items-center justify-center gap-2 px-3 py-2.5 rounded-xl bg-primary/20 text-primary hover:bg-primary/30 text-xs font-medium outline-none"
                  >
                    <Plus className="w-3.5 h-3.5" />
                    {t("selectProfile.addOwn", "Add my own")}
                  </FocusableButton>
                </div>
              </FocusableSection>
            )}
          </AnimatePresence>
        )}

        {/* ── Progressive load (post-selection) ──────────────── */}
        {selecting && (
          <div className="space-y-2" data-testid="select-profile-progress">
            <div className="glass rounded-2xl px-4 py-3 flex items-center gap-3 mb-3">
              <div className="w-9 h-9 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
                {(() => {
                  const Icon = kindIcon(selecting.kind);
                  return <Icon className="w-4 h-4 text-primary" />;
                })()}
              </div>
              <div className="flex-1 min-w-0">
                <p className="text-foreground text-sm font-medium truncate">
                  {selecting.name}
                </p>
                <p className="text-muted-foreground text-[11px] truncate">
                  {kindLabel(selecting.kind)}
                </p>
              </div>
            </div>

            <StepRow
              icon={Tv}
              label={t("selectProfile.stepChannels", "Channels")}
              count={counts.channels}
              state={stateFor("channels", step, !!error)}
              testId="progress-channels"
            />
            <StepRow
              icon={Film}
              label={t("selectProfile.stepMovies", "Movies")}
              count={counts.movies}
              state={stateFor("movies", step, !!error)}
              testId="progress-movies"
            />
            <StepRow
              icon={Clapperboard}
              label={t("selectProfile.stepSeries", "Series")}
              count={counts.series}
              state={stateFor("series", step, !!error)}
              testId="progress-series"
            />

            {error && (
              <motion.div
                initial={{ opacity: 0, y: 6 }}
                animate={{ opacity: 1, y: 0 }}
                className="mt-4 p-3 rounded-xl bg-destructive/15 border border-destructive/40 flex items-start gap-2"
                data-testid="select-profile-error"
              >
                <CircleAlert className="w-4 h-4 text-destructive mt-0.5 shrink-0" />
                <div className="flex-1 min-w-0">
                  <p className="text-destructive text-xs font-medium">
                    {t("selectProfile.errorTitle", "Could not connect")}
                  </p>
                  <p className="text-destructive/80 text-[11px] mt-0.5 break-words">
                    {error}
                  </p>
                  <div className="flex gap-2 mt-3">
                    <button
                      onClick={() => setSelecting(null)}
                      className="text-[11px] px-3 py-1.5 rounded-lg glass text-foreground hover:border-primary/40"
                      data-testid="select-profile-retry"
                    >
                      {t("selectProfile.back", "Back to list")}
                    </button>
                    <button
                      onClick={() => navigate("/", { replace: true })}
                      className="text-[11px] px-3 py-1.5 rounded-lg bg-primary/20 text-primary hover:bg-primary/30"
                    >
                      {t("selectProfile.skip", "Skip for now")}
                    </button>
                  </div>
                </div>
              </motion.div>
            )}

            {!error && step === "done" && (
              <motion.p
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                className="text-center text-primary text-xs mt-3 tracking-wide"
                data-testid="select-profile-done"
              >
                ✓ {t("selectProfile.allLoaded", "All loaded — let's go")}
              </motion.p>
            )}
          </div>
        )}
      </motion.div>
    </div>
  );
};

type RowState = "pending" | "active" | "done" | "error";

const stateFor = (
  me: Exclude<Step, "done">,
  current: Step,
  hasError: boolean,
): RowState => {
  const order: Step[] = ["channels", "movies", "series", "done"];
  const cur = order.indexOf(current);
  const my = order.indexOf(me);
  if (hasError && my === cur) return "error";
  if (my < cur) return "done";
  if (my === cur) return "active";
  return "pending";
};

const StepRow = ({
  icon: Icon,
  label,
  count,
  state,
  testId,
}: {
  icon: typeof Tv;
  label: string;
  count: number;
  state: RowState;
  testId: string;
}) => (
  <div
    className={`glass rounded-2xl px-4 py-3 flex items-center gap-3 border transition-colors ${
      state === "active"
        ? "border-primary/50"
        : state === "done"
          ? "border-primary/30"
          : state === "error"
            ? "border-destructive/50"
            : "border-transparent"
    }`}
    data-testid={testId}
    data-state={state}
  >
    <div className="w-9 h-9 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
      <Icon
        className={`w-4 h-4 ${state === "pending" ? "text-muted-foreground/50" : "text-primary"}`}
      />
    </div>
    <div className="flex-1 min-w-0">
      <p className="text-foreground text-sm font-medium">{label}</p>
      <p className="text-muted-foreground text-[11px] tabular-nums">
        {state === "done"
          ? `${count.toLocaleString()} items loaded`
          : state === "active"
            ? "Loading…"
            : state === "error"
              ? "Failed"
              : "Waiting"}
      </p>
    </div>
    <div className="w-5 h-5 flex items-center justify-center">
      {state === "active" && (
        <Loader2 className="w-4 h-4 animate-spin text-primary" />
      )}
      {state === "done" && <Check className="w-4 h-4 text-primary" />}
      {state === "error" && (
        <CircleAlert className="w-4 h-4 text-destructive" />
      )}
    </div>
  </div>
);

export default SelectProfile;
