"use client";

import Link from "next/link";
import { useQuery } from "@tanstack/react-query";
import { Tv } from "lucide-react";
import { api, ApiRequestError } from "@/lib/api";
import { useChannels } from "@/hooks/use-channels";
import { useAuthContext } from "@/context/auth-context";
import type { ChannelResponse, ScheduledSlotResponse } from "@/lib/types";

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function fmtTime(iso: string) {
  return new Date(iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
}

function fmtDuration(secs: number) {
  const h = Math.floor(secs / 3600);
  const m = Math.floor((secs % 3600) / 60);
  return h > 0 ? `${h}h ${m}m` : `${m}m`;
}

function slotLabel(slot: ScheduledSlotResponse) {
  const { item } = slot;
  if (item.content_type === "episode" && item.series_name) {
    const ep = [
      item.season_number != null ? `S${item.season_number}` : "",
      item.episode_number != null ? `E${String(item.episode_number).padStart(2, "0")}` : "",
    ]
      .filter(Boolean)
      .join("");
    return ep
      ? `${item.series_name} ${ep} – ${item.title}`
      : `${item.series_name} – ${item.title}`;
  }
  return item.year ? `${item.title} (${item.year})` : item.title;
}

// ---------------------------------------------------------------------------
// ChannelRow — fetches its own EPG slice and renders current + upcoming
// ---------------------------------------------------------------------------

function ChannelRow({ channel }: { channel: ChannelResponse }) {
  const { token, isLoaded } = useAuthContext();

  const { data: slots, isError, error, isPending, isFetching } = useQuery({
    queryKey: ["guide-epg", channel.id, token],
    queryFn: () => {
      const now = new Date();
      const from = now.toISOString();
      const until = new Date(now.getTime() + 4 * 60 * 60 * 1000).toISOString();
      return api.schedule.getEpg(channel.id, token ?? "", from, until);
    },
    enabled: isLoaded,
    refetchInterval: 30_000,
    retry: false,
  });

  const now = Date.now();

  const current = slots?.find(
    (s) =>
      new Date(s.start_at).getTime() <= now && now < new Date(s.end_at).getTime(),
  );
  const upcoming = slots?.filter((s) => new Date(s.start_at).getTime() > now).slice(0, 3) ?? [];

  const progress = current
    ? (now - new Date(current.start_at).getTime()) /
      (new Date(current.end_at).getTime() - new Date(current.start_at).getTime())
    : 0;

  const remaining = current
    ? Math.ceil((new Date(current.end_at).getTime() - now) / 60_000)
    : 0;

  return (
    <div className="overflow-hidden rounded-xl border border-zinc-800 bg-zinc-900">
      {/* Channel header */}
      <div className="flex items-center justify-between border-b border-zinc-800 px-4 py-3">
        <div className="flex min-w-0 items-center gap-2">
          <Tv className="size-3.5 shrink-0 text-zinc-600" />
          <span className="truncate text-sm font-semibold text-zinc-100">{channel.name}</span>
          {channel.description && (
            <span className="hidden truncate text-xs text-zinc-600 sm:block">
              — {channel.description}
            </span>
          )}
        </div>
        <Link
          href={`/tv?channel=${channel.id}`}
          className="ml-4 shrink-0 rounded-md px-2.5 py-1 text-xs text-zinc-400 transition-colors hover:bg-zinc-800 hover:text-zinc-100"
        >
          Watch →
        </Link>
      </div>

      <div className="space-y-3 px-4 py-3">
        {/* Currently airing */}
        {current ? (
          <div className="space-y-1.5">
            <div className="flex items-baseline justify-between gap-4">
              <div className="flex min-w-0 items-baseline gap-2">
                <span className="shrink-0 rounded bg-red-600/20 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-red-400">
                  Now
                </span>
                <span className="truncate text-sm font-medium text-zinc-100">
                  {slotLabel(current)}
                </span>
              </div>
              <span className="shrink-0 text-xs text-zinc-500">{remaining}m left</span>
            </div>
            <div className="h-1 w-full overflow-hidden rounded-full bg-zinc-800">
              <div
                className="h-full rounded-full bg-red-600 transition-all duration-1000"
                style={{ width: `${Math.round(progress * 100)}%` }}
              />
            </div>
          </div>
        ) : isPending && isFetching ? (
          <p className="text-xs italic text-zinc-600">Loading…</p>
        ) : isError && error instanceof ApiRequestError && error.status === 401 ? (
          <p className="text-xs italic text-zinc-600">Sign in to view this channel</p>
        ) : (
          <p className="text-xs italic text-zinc-600">
            {isError || !slots?.length
              ? "No signal — schedule may not be generated yet"
              : "Nothing airing right now"}
          </p>
        )}

        {/* Upcoming */}
        {upcoming.length > 0 && (
          <ul className="space-y-1.5 border-t border-zinc-800 pt-2.5">
            {upcoming.map((slot) => (
              <li key={slot.id} className="flex items-baseline justify-between gap-4">
                <div className="flex min-w-0 items-baseline gap-2">
                  <span className="shrink-0 font-mono text-[11px] text-zinc-500">
                    {fmtTime(slot.start_at)}
                  </span>
                  <span className="truncate text-xs text-zinc-400">{slotLabel(slot)}</span>
                </div>
                <span className="shrink-0 font-mono text-[11px] text-zinc-600">
                  {fmtDuration(slot.item.duration_secs)}
                </span>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Page
// ---------------------------------------------------------------------------

export default function GuidePage() {
  const { data: channels, isLoading } = useChannels();

  const now = new Date();
  const timeLabel = now.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
  const dateLabel = now.toLocaleDateString([], {
    weekday: "long",
    month: "long",
    day: "numeric",
  });

  return (
    <div className="mx-auto w-full max-w-4xl space-y-6 px-6 py-8">
      <div className="flex items-baseline gap-3">
        <h1 className="text-xl font-semibold text-zinc-100">Channel Guide</h1>
        <span className="text-sm text-zinc-500">
          {dateLabel} · {timeLabel}
        </span>
      </div>

      {isLoading && <p className="text-sm text-zinc-600">Loading channels…</p>}

      {!isLoading && channels?.length === 0 && (
        <p className="text-sm text-zinc-600">
          No channels yet.{" "}
          <Link href="/dashboard" className="text-zinc-400 underline">
            Create one in the dashboard.
          </Link>
        </p>
      )}

      <div className="space-y-3">
        {channels?.map((channel) => (
          <ChannelRow key={channel.id} channel={channel} />
        ))}
      </div>
    </div>
  );
}
