"use client";
import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import { StreamVideoClient } from "@stream-io/video-react-sdk";
import { Radio, RefreshCw, Plus, Video } from "lucide-react";
import { AnimatePresence, motion } from "framer-motion";
import { useAppSelector } from "@/store/hooks";
import { useGeneralSettings } from "@/lib/GeneralSettingsContext";
import { useLoginPrompt } from "@/lib/LoginPromptContext";
import { useTranslation } from "@/i18n";
import { LiveCard } from "./LiveCard";
import { MotionSection, MotionItem } from "@/components/motion/MotionSection";
import type { LiveUser } from "@/types/live";

/* Auto-refresh the list so streams that just ended disappear on their own */
const LIST_POLL_INTERVAL_MS = 20_000;

/* Dummy streams shown when is_live_streaming_fake = "1" */
const DUMMY_USERS: LiveUser[] = [
  {
    id: "dummy-1",
    callId: "dummy-1",
    hostName: "Priya Patel",
    hostImage:
      "https://images.unsplash.com/photo-1529626455594-4ff0802cfb7e?w=400&auto=format&fit=crop",
    viewerCount: 15400,
    isFake: true,
  },
  {
    id: "dummy-2",
    callId: "dummy-2",
    hostName: "Rahul Sharma",
    hostImage: "https://i.pravatar.cc/400?img=11",
    viewerCount: 8200,
    isFake: true,
  },
  {
    id: "dummy-3",
    callId: "dummy-3",
    hostName: "Anjali Desai",
    hostImage: "https://i.pravatar.cc/400?img=5",
    viewerCount: 21000,
    isFake: true,
  },
  {
    id: "dummy-4",
    callId: "dummy-4",
    hostName: "Jane Smith",
    hostImage:
      "https://images.unsplash.com/photo-1513207565459-d7f36bfa1222?w=400&auto=format&fit=crop",
    viewerCount: 21000,
    isFake: true,
  },
  {
    id: "dummy-5",
    callId: "dummy-5",
    hostName: "Alice Johnson",
    hostImage:
      "https://images.unsplash.com/photo-1533435137002-455932c8538f?w=400&auto=format&fit=crop",
    viewerCount: 15000,
    isFake: true,
  },
  {
    id: "dummy-6",
    callId: "dummy-6",
    hostName: "Bob Brown",
    hostImage:
      "https://plus.unsplash.com/premium_photo-1682614334089-da623bdcaf2d?w=400&auto=format&fit=crop",
    viewerCount: 1200,
    isFake: true,
  },
];

/* ── Skeleton card ─────────────────────────────────────────────────────── */
function LiveCardSkeleton() {
  return (
    <div
      className="rounded-2xl overflow-hidden animate-pulse"
      style={{
        background: "var(--card)",
        border: "1px solid var(--border-soft)",
      }}
    >
      <div
        className="animate-pulse"
        style={{ height: 180, background: "var(--deep)" }}
      />
      <div className="flex items-center gap-2 px-3 py-2.5">
        <div
          className="w-7 h-7 rounded-full shrink-0"
          style={{ background: "var(--deep)" }}
        />
        <div
          className="h-3 rounded-full flex-1"
          style={{ background: "var(--deep)", maxWidth: 100 }}
        />
      </div>
    </div>
  );
}

/* ── Stream history (current user's own past streams) ─────────────────── */
interface StreamHistoryItem {
  id: string;
  title?: string;
  hostImage: string;
  hostName: string;
  startedAt: number;
  endedAt: number;
}

function formatDuration(ms: number): string {
  const totalSec = Math.max(0, Math.round(ms / 1000));
  const h = Math.floor(totalSec / 3600);
  const m = Math.floor((totalSec % 3600) / 60);
  const s = totalSec % 60;
  if (h > 0) return `${h}h ${m}m`;
  if (m > 0) return `${m}m ${s}s`;
  return `${s}s`;
}

function formatDate(ms: number): string {
  return new Date(ms).toLocaleString(undefined, {
    month: "short",
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
  });
}

function HistoryCardSkeleton() {
  return (
    <div
      className="rounded-2xl overflow-hidden animate-pulse"
      style={{
        background: "var(--card)",
        border: "1px solid var(--border-soft)",
      }}
    >
      <div
        className="animate-pulse"
        style={{ height: 140, background: "var(--deep)" }}
      />
      <div className="px-3 py-2.5 flex flex-col gap-1.5">
        <div
          className="h-3 rounded-full"
          style={{ background: "var(--deep)", width: "70%" }}
        />
        <div
          className="h-2.5 rounded-full"
          style={{ background: "var(--deep)", width: "40%" }}
        />
      </div>
    </div>
  );
}

function HistoryCard({
  item,
  t,
}: {
  item: StreamHistoryItem;
  t: (k: string) => string;
}) {
  return (
    <div
      className="rounded-2xl overflow-hidden"
      style={{
        background: "var(--card)",
        border: "1px solid var(--border-soft)",
      }}
    >
      <div className="relative overflow-hidden" style={{ height: 140 }}>
        <div className="absolute inset-0 flex items-center justify-center">
          {item.hostImage ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={item.hostImage}
              alt={item.hostName}
              className=" object-cover"
              style={{
                flexShrink: 0,
                outline: "2px solid rgba(255,255,255,0.2)",
                outlineOffset: 3,
              }}
            />
          ) : (
            <div
              className="rounded-full flex items-center justify-center text-xl font-black text-white"
              style={{
                width: 56,
                height: 56,
                flexShrink: 0,
                background:
                  "linear-gradient(135deg, var(--accent), var(--accent-dark))",
              }}
            >
              {(item.title || item.hostName).charAt(0).toUpperCase()}
            </div>
          )}
        </div>
        <div
          className="absolute inset-0"
          style={{
            background:
              "linear-gradient(180deg, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0) 45%, rgba(0,0,0,0.5) 100%)",
          }}
        />
        <div
          className="absolute top-2.5 right-2.5 px-2.5 py-1 rounded-full text-[9px] font-black uppercase tracking-widest text-white"
          style={{
            background: "rgba(0,0,0,0.55)",
            backdropFilter: "blur(4px)",
          }}
        >
          {t("live_ended")}
        </div>
        <div
          className="absolute bottom-2 left-3 right-3 text-white text-xs font-bold truncate"
          style={{ textShadow: "0 1px 4px rgba(0,0,0,0.8)" }}
        >
          {item.title || item.hostName}
        </div>
      </div>
      <div className="px-3 py-2.5 flex items-center justify-between gap-2">
        <span className="text-[11px]" style={{ color: "var(--text-muted)" }}>
          {formatDate(item.startedAt)}
        </span>
        <span
          className="text-[11px] font-semibold"
          style={{ color: "var(--text-muted)" }}
        >
          {formatDuration(item.endedAt - item.startedAt)}
        </span>
      </div>
    </div>
  );
}

/* ── Main component ────────────────────────────────────────────────────── */
export function LivePage() {
  const [activeTab, setActiveTab] = useState<"live" | "history">("live");
  const [liveUsers, setLiveUsers] = useState<LiveUser[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [historyItems, setHistoryItems] = useState<StreamHistoryItem[]>([]);
  const [isHistoryLoading, setIsHistoryLoading] = useState(false);
  const [historyFetched, setHistoryFetched] = useState(false);
  const [showGoLiveModal, setShowGoLiveModal] = useState(false);
  const [liveTitle, setLiveTitle] = useState("");
  const [titleError, setTitleError] = useState(false);
  const router = useRouter();
  const { t } = useTranslation();
  const { settings } = useGeneralSettings();
  const user = useAppSelector((s) => s.auth.user);
  const isAuthenticated = useAppSelector((s) => s.auth.isAuthenticated);
  const { open: openLoginPrompt } = useLoginPrompt();

  const fetchStreams = useCallback(
    async (opts: { manual?: boolean; silent?: boolean } = {}) => {
      const { manual = false, silent = false } = opts;
      if (!silent) {
        if (manual) setIsRefreshing(true);
        else setIsLoading(true);
      }

      try {
        if (!settings?.streamApiKey || !user?.stream_token) {
          setLiveUsers(settings?.isLiveStreamingFake ? DUMMY_USERS : []);
          return;
        }

        const streamClient = new StreamVideoClient({
          apiKey: settings.streamApiKey,
          user: {
            id: String(user.id),
            name: user.channel_name || user.full_name,
            image: user.image,
          },
          token: user.stream_token,
        });

        try {
          const res = await (streamClient as any).queryCalls({
            filterConditions: {
              type: { $eq: "livestream" },
              ongoing: { $eq: true },
            },
            sort: [{ field: "created_at", direction: -1 }],
            watch: false,
            limit: 30,
          });

          // queryCalls() does NOT return raw JSON — the SDK transforms each
          // entry into a `Call` class instance internally (see
          // StreamVideoClient.queryCalls in the SDK source). The real data is
          // on call.state.* (a reactive store: backstage, endedAt, createdBy,
          // custom, session, thumbnails, createdAt) — call.call.* doesn't
          // exist on these objects, that shape only appears in the raw HTTP
          // response body, not in what JS code receives here.
          // Also don't fully trust the server-side `type`/`ongoing` filters —
          // observed responses include ended and non-livestream calls anyway —
          // so re-check client-side, mirroring the reference Flutter app's
          // proven filter: out of backstage, not yet ended, not your own
          // stream, and created within the last 12 hours (guards against a
          // call that never got a proper endedAt — e.g. host's app crashed —
          // from showing as "live" forever).
          //
          // backstage/endedAt alone aren't enough, though: a host whose
          // browser closed/crashed without our cleanup's endCall() running
          // leaves a "zombie" call — backstage:false, endedAt:null — but
          // with no actual active broadcast session (session: null,
          // current_session_id: ""). Require a real session too, or these
          // show up as a second fake "ON AIR" card for the same host with
          // nothing actually streaming behind it.
          const myUserId = String(user.id);
          const twelveHoursAgo = Date.now() - 12 * 60 * 60 * 1000;
          const calls: any[] = res?.calls ?? [];
          const items = calls.filter((call: any) => {
            const st = call.state;
            if (!st) return false;
            const createdAt = st.createdAt
              ? new Date(st.createdAt).getTime()
              : NaN;
            return (
              call.type === "livestream" &&
              st.backstage === false &&
              !st.endedAt &&
              !!st.session &&
              String(st.createdBy?.id) !== myUserId &&
              !Number.isNaN(createdAt) &&
              createdAt >= twelveHoursAgo
            );
          });
          const realStreams: LiveUser[] = items.map((call: any) => {
            const st = call.state;
            return {
              id: call.cid ?? call.id,
              callId: call.id,
              title: st.custom?.title || undefined,
              hostName: st.createdBy?.name ?? "Unknown",
              hostImage: st.createdBy?.image ?? "",
              viewerCount:
                st.session?.participants?.length ??
                st.participants?.length ??
                0,
              isFake: false,
            };
          });

          const fakeStreams = settings.isLiveStreamingFake ? DUMMY_USERS : [];
          setLiveUsers([...realStreams, ...fakeStreams]);
        } finally {
          streamClient.disconnectUser().catch(() => {});
        }
      } catch (e) {
        console.error("Failed to fetch live streams", e);
        if (!silent)
          setLiveUsers(settings?.isLiveStreamingFake ? DUMMY_USERS : []);
      } finally {
        if (!silent) {
          setIsLoading(false);
          setIsRefreshing(false);
        }
      }
    },
    [settings, user],
  );

  useEffect(() => {
    if (settings !== null) {
      fetchStreams();
    }
  }, [settings, fetchStreams]);

  /* Poll in the background so a stream that just ended drops off the list
     on its own, without the viewer needing to hit refresh. */
  useEffect(() => {
    if (settings === null) return;
    const interval = setInterval(() => {
      fetchStreams({ silent: true });
    }, LIST_POLL_INTERVAL_MS);
    return () => clearInterval(interval);
  }, [settings, fetchStreams]);

  const fetchHistory = useCallback(async () => {
    if (!settings?.streamApiKey || !user?.stream_token || !user?.id) return;
    setIsHistoryLoading(true);
    const myUserId = String(user.id);

    const streamClient = new StreamVideoClient({
      apiKey: settings.streamApiKey,
      user: {
        id: myUserId,
        name: user.channel_name || user.full_name,
        image: user.image,
      },
      token: user.stream_token,
    });

    try {
      const res = await (streamClient as any).queryCalls({
        filterConditions: { type: { $eq: "livestream" } },
        sort: [{ field: "created_at", direction: -1 }],
        watch: false,
        limit: 30,
      });

      // Same Call-instance shape as the live list — see fetchStreams above.
      const calls: any[] = res?.calls ?? [];
      const items: StreamHistoryItem[] = calls
        .filter((call: any) => {
          const st = call.state;
          return (
            st &&
            call.type === "livestream" &&
            String(st.createdBy?.id) === myUserId &&
            !!st.endedAt
          );
        })
        .map((call: any) => {
          const st = call.state;
          return {
            id: call.cid ?? call.id,
            title: st.custom?.title || undefined,
            hostImage: st.createdBy?.image ?? "",
            hostName: st.createdBy?.name ?? "",
            startedAt: new Date(st.createdAt).getTime(),
            endedAt: new Date(st.endedAt).getTime(),
          };
        });

      setHistoryItems(items);
    } catch (e) {
      console.error("Failed to fetch stream history", e);
      setHistoryItems([]);
    } finally {
      streamClient.disconnectUser().catch(() => {});
      setIsHistoryLoading(false);
      setHistoryFetched(true);
    }
  }, [settings, user]);

  useEffect(() => {
    if (activeTab === "history" && !historyFetched) {
      fetchHistory();
    }
  }, [activeTab, historyFetched, fetchHistory]);

  const handleGoLive = () => {
    if (!isAuthenticated) {
      openLoginPrompt();
      return;
    }
    setLiveTitle("");
    setTitleError(false);
    setShowGoLiveModal(true);
  };

  const handleStartLive = () => {
    const title = liveTitle.trim();
    if (!title) {
      setTitleError(true);
      return;
    }
    const callId = `stream_${Date.now()}`;
    setShowGoLiveModal(false);
    router.push(`/live/${callId}?host=true&title=${encodeURIComponent(title)}`);
  };

  const handleJoinStream = (live: LiveUser) => {
    if (!isAuthenticated) {
      openLoginPrompt();
      return;
    }
    if (live.isFake) {
      // Dummy streams just show a "not available" state for now
      router.push(`/live/${live.callId}?dummy=true`);
    } else {
      router.push(`/live/${live.callId}`);
    }
  };

  return (
    <div className="min-h-screen pb-24" style={{ background: "var(--bg)" }}>
      {/* ── Header ─────────────────────────────────────────────────────── */}
      <div
        className="sticky top-0 z-20 flex items-center justify-between px-5 py-4 border-b"
        style={{ background: "var(--bg)", borderColor: "var(--border-soft)" }}
      >
        <div className="flex items-center gap-2.5">
          <div
            className="w-8 h-8 rounded-lg flex items-center justify-center"
            style={{
              background: "rgba(220,38,38,0.12)",
              border: "1px solid rgba(220,38,38,0.25)",
            }}
          >
            <Radio size={16} color="#dc2626" />
          </div>
          <h1
            className="text-sm font-black tracking-tight"
            style={{ color: "var(--text-primary)" }}
          >
            {t("live_streaming")}
          </h1>
        </div>

        <div className="flex items-center gap-2">
          {/* Refresh */}
          <button
            onClick={() => fetchStreams({ manual: true })}
            disabled={isRefreshing}
            className="w-8 h-8 rounded-full flex items-center justify-center transition-all active:scale-90 disabled:opacity-50"
            style={{ background: "var(--card)", color: "var(--text-muted)" }}
          >
            <RefreshCw
              size={14}
              className={isRefreshing ? "animate-spin" : ""}
            />
          </button>

          {/* Go Live */}
          <button
            onClick={handleGoLive}
            className="flex items-center gap-1.5 px-3.5 py-1.5 rounded-xl text-xs font-black text-white transition-all active:scale-95"
            style={{
              background: "linear-gradient(135deg, #dc2626, #b91c1c)",
              boxShadow: "0 4px 18px rgba(220,38,38,0.35)",
            }}
          >
            <Plus size={13} strokeWidth={2.5} />
            {t("live_goLive")}
          </button>
        </div>
      </div>

      {/* ── Tabs ───────────────────────────────────────────────────────── */}
      <div
        className="flex items-center gap-2 px-4 pt-3"
        style={{ background: "var(--bg)" }}
      >
        {(["live", "history"] as const).map((tab) => (
          <button
            key={tab}
            onClick={() => setActiveTab(tab)}
            className="px-3.5 py-1.5 rounded-full text-xs font-bold transition-all active:scale-95"
            style={
              activeTab === tab
                ? {
                    background: "rgba(220,38,38,0.12)",
                    color: "#dc2626",
                    border: "1px solid rgba(220,38,38,0.3)",
                  }
                : {
                    background: "var(--card)",
                    color: "var(--text-muted)",
                    border: "1px solid var(--border-soft)",
                  }
            }
          >
            {tab === "live" ? t("live_streaming") : t("live_history")}
          </button>
        ))}
      </div>

      {/* ── Content ────────────────────────────────────────────────────── */}
      <div className="px-4 py-5">
        {activeTab === "live" ? (
          isLoading ? (
            <div className="grid grid-cols-2 gap-3">
              {Array.from({ length: 6 }).map((_, i) => (
                <LiveCardSkeleton key={i} />
              ))}
            </div>
          ) : liveUsers.length === 0 ? (
            /* Empty state */
            <div className="flex flex-col items-center justify-center py-24 gap-4">
              <div
                className="w-20 h-20 rounded-full flex items-center justify-center"
                style={{
                  background: "var(--card)",
                  border: "1px solid var(--border-soft)",
                }}
              >
                <Radio size={32} style={{ color: "var(--text-muted)" }} />
              </div>
              <div className="text-center">
                <p
                  className="text-sm font-semibold mb-1"
                  style={{ color: "var(--text-muted)" }}
                >
                  {t("live_noStreams")}
                </p>
                <p className="text-xs" style={{ color: "var(--text-muted)" }}>
                  {t("live_noStreamsDesc")}
                </p>
              </div>
              <button
                onClick={handleGoLive}
                className="flex items-center gap-1.5 px-4 py-2 rounded-xl text-xs font-bold text-white mt-2"
                style={{
                  background: "linear-gradient(135deg, #dc2626, #b91c1c)",
                }}
              >
                <Plus size={13} />
                {t("live_goLive")}
              </button>
            </div>
          ) : (
            <MotionSection className="grid grid-cols-2 gap-3">
              {liveUsers.map((live) => (
                <MotionItem key={live.id}>
                  <LiveCard
                    live={live}
                    onClick={() => handleJoinStream(live)}
                  />
                </MotionItem>
              ))}
            </MotionSection>
          )
        ) : isHistoryLoading ? (
          <div className="grid grid-cols-2 gap-3">
            {Array.from({ length: 6 }).map((_, i) => (
              <HistoryCardSkeleton key={i} />
            ))}
          </div>
        ) : historyItems.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-24 gap-4">
            <div
              className="w-20 h-20 rounded-full flex items-center justify-center"
              style={{
                background: "var(--card)",
                border: "1px solid var(--border-soft)",
              }}
            >
              <Radio size={32} style={{ color: "var(--text-muted)" }} />
            </div>
            <p
              className="text-sm font-semibold"
              style={{ color: "var(--text-muted)" }}
            >
              {t("live_noHistory")}
            </p>
          </div>
        ) : (
          <MotionSection className="grid grid-cols-2 gap-3">
            {historyItems.map((item) => (
              <MotionItem key={item.id}>
                <HistoryCard item={item} t={t} />
              </MotionItem>
            ))}
          </MotionSection>
        )}
      </div>

      {/* ── Go Live modal — collect a title before starting the stream ───── */}
      <AnimatePresence>
        {showGoLiveModal && (
          <>
            <motion.div
              className="fixed inset-0 z-[700]"
              style={{
                background: "rgba(0,0,0,0.7)",
                backdropFilter: "blur(8px)",
              }}
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              onClick={() => setShowGoLiveModal(false)}
            />
            <motion.div
              className="fixed z-[701] left-1/2 top-1/2 w-[min(340px,88vw)] rounded-3xl p-6 flex flex-col items-center gap-4"
              style={{
                background: "var(--card)",
                border: "1px solid var(--border)",
              }}
              initial={{
                opacity: 0,
                scale: 0.85,
                y: 20,
                x: "-50%",
                translateY: "-50%",
              }}
              animate={{
                opacity: 1,
                scale: 1,
                y: 0,
                x: "-50%",
                translateY: "-50%",
              }}
              exit={{
                opacity: 0,
                scale: 0.92,
                y: 10,
                x: "-50%",
                translateY: "-50%",
              }}
              transition={{ type: "spring", stiffness: 380, damping: 28 }}
            >
              <div
                className="w-16 h-16 rounded-full flex items-center justify-center"
                style={{
                  background: "rgba(220,38,38,0.12)",
                  border: "2px solid rgba(220,38,38,0.25)",
                }}
              >
                <Video size={28} color="#dc2626" />
              </div>
              <div className="text-center">
                <p
                  className="text-base font-black mb-1"
                  style={{ color: "var(--text-primary)" }}
                >
                  {t("live_streamTitle")}
                </p>
              </div>
              <div className="w-full">
                <input
                  autoFocus
                  value={liveTitle}
                  onChange={(e) => {
                    setLiveTitle(e.target.value);
                    if (titleError) setTitleError(false);
                  }}
                  onKeyDown={(e) => e.key === "Enter" && handleStartLive()}
                  placeholder={t("live_titlePlaceholder")}
                  maxLength={100}
                  className="w-full h-11 px-4 rounded-2xl text-sm outline-none"
                  style={{
                    background: "var(--deep)",
                    color: "var(--text-primary)",
                    border: `1px solid ${titleError ? "#dc2626" : "var(--border)"}`,
                  }}
                />
                {titleError && (
                  <p
                    className="text-xs mt-1.5 pl-1"
                    style={{ color: "#dc2626" }}
                  >
                    {t("live_titleRequired")}
                  </p>
                )}
              </div>

              <div className="w-full flex flex-col gap-2.5">
                <button
                  onClick={handleStartLive}
                  className="h-11 rounded-2xl text-sm font-black text-white transition-all active:scale-95"
                  style={{
                    background: "linear-gradient(135deg, #dc2626, #b91c1c)",
                  }}
                >
                  {t("live_startLive")}
                </button>
                <button
                  onClick={() => setShowGoLiveModal(false)}
                  className="h-11 rounded-2xl text-sm font-semibold transition-all active:scale-95"
                  style={{
                    background: "var(--deep)",
                    color: "var(--text-muted)",
                    border: "1px solid var(--border)",
                  }}
                >
                  {t("live_cancel")}
                </button>
              </div>
            </motion.div>
          </>
        )}
      </AnimatePresence>
    </div>
  );
}
