import {
  ArrowUpRight,
  BookOpenText,
  Headphones,
  MessageCircle,
  Music2,
  Pause,
  Play,
  Radio,
  Send,
  UsersRound,
} from "lucide-react";
import { AnimatePresence, motion, useReducedMotion } from "framer-motion";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useSearchParams } from "react-router-dom";
import { directoriesApi } from "../shared/api/endpoints";
import { toList } from "../shared/api/normalize";
import { queryKeys } from "../shared/api/queryKeys";
import { Badge } from "../shared/ui/Badge";
import { Button } from "../shared/ui/Button";
import { EmptyState, ErrorState, Skeleton } from "../shared/ui/States";
import { cn } from "../shared/lib/cn";

const tabs = [
  { id: "radio", label: "Радио", icon: Radio },
  { id: "magazines", label: "Журналы", icon: BookOpenText },
  { id: "social", label: "Соцсети", icon: UsersRound },
];

function normalizeMedia(payload) {
  return toList(payload).map((item) => ({
    ...item,
    id: item.id ?? item.slug ?? item.url ?? item.title ?? item.name,
    type: String(item.type ?? item.kind ?? item.category ?? "").toLowerCase(),
    title: item.title ?? item.name ?? "Медиа",
    text: item.text ?? item.description ?? item.summary ?? "",
    url: item.url ?? item.link ?? item.href,
    handle: item.handle ?? item.username ?? item.slug,
    audience: item.audience ?? item.followers ?? item.subscribers,
    time: item.time ?? item.startsAt ?? item.startTime,
    host: item.host ?? item.author ?? item.speaker,
    issue: item.issue ?? item.number ?? item.publishedAt,
  }));
}

function filtered(items, aliases) {
  return items.filter((item) => aliases.some((alias) => item.type.includes(alias)));
}

function ExternalLink({ href, children }) {
  if (!href) {
    return (
      <Button className="mt-5" variant="secondary" disabled icon={<ArrowUpRight className="size-4" />}>
        {children}
      </Button>
    );
  }

  return (
    <a
      className="mt-5 inline-flex h-11 items-center justify-center gap-2 rounded-md border border-line bg-surface px-5 text-sm font-semibold text-ink transition hover:border-primary hover:text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent"
      href={href}
      target="_blank"
      rel="noreferrer"
    >
      <ArrowUpRight className="size-4" />
      {children}
    </a>
  );
}

function RadioTab({ items }) {
  const [playing, setPlaying] = useState(false);
  const [station, ...schedule] = items;

  if (!station) {
    return <EmptyState title="Радио пока не добавлено" text="Записи типа radio появятся здесь после ответа backend." />;
  }

  return (
    <div className="grid gap-6 lg:grid-cols-[minmax(0,3fr)_minmax(18rem,1fr)]">
      <section className="overflow-hidden rounded-xl bg-primary text-white">
        <div className="grid gap-8 p-6 sm:p-8 md:grid-cols-[minmax(0,3fr)_minmax(9rem,1fr)] md:items-end lg:p-10">
          <div>
            <Badge className="bg-white/12 text-white">{station.status ?? "Сейчас в эфире"}</Badge>
            <h2 className="mt-5 font-serif text-3xl sm:text-4xl md:text-5xl">{station.title}</h2>
            <p className="mt-4 max-w-xl text-sm leading-7 text-white/70 sm:text-base">{station.text}</p>
            <div className="mt-7 flex flex-wrap items-center gap-3">
              <Button
                className="bg-white text-primary hover:bg-paper"
                icon={playing ? <Pause className="size-4" /> : <Play className="size-4" />}
                onClick={() => setPlaying((value) => !value)}
              >
                {playing ? "Пауза" : "Слушать эфир"}
              </Button>
              {station.audience && (
                <span className="flex items-center gap-2 text-sm text-white/60">
                  <span className={cn("size-2 rounded-full bg-accent", playing && "animate-pulse")} />
                  {station.audience}
                </span>
              )}
            </div>
          </div>
          <div className="relative mx-auto grid aspect-square w-40 place-items-center rounded-full border border-white/20 md:mx-0">
            <div className={cn("absolute inset-4 rounded-full border border-white/15", playing && "animate-spin")} />
            <Headphones className="size-16 text-white/85" />
          </div>
        </div>
        <div className="flex h-16 items-end gap-1 border-t border-white/10 px-6 pb-4">
          {Array.from({ length: 16 }, (_, index) => (
            <span
              key={index}
              className="flex-1 rounded-t bg-white/25"
              style={{ height: playing ? `${24 + ((index * 17) % 58)}%` : "18%" }}
            />
          ))}
        </div>
      </section>

      <aside className="rounded-xl border border-line bg-surface p-5 sm:p-6">
        <div className="flex items-center gap-3">
          <Music2 className="size-5 text-accent" />
          <h2 className="font-serif text-2xl">Программа дня</h2>
        </div>
        {schedule.length === 0 ? (
          <p className="mt-5 text-sm leading-6 text-muted">Расписание появится после добавления дополнительных записей radio.</p>
        ) : (
          <div className="mt-5 divide-y divide-line">
            {schedule.map((show) => (
              <article key={show.id} className="py-4 first:pt-0">
                <div className="flex gap-4">
                  <span className="font-semibold text-accent">{show.time}</span>
                  <div>
                    <h3 className="font-semibold">{show.title}</h3>
                    <p className="mt-1 text-xs text-muted">{show.host}</p>
                    <p className="mt-2 text-sm leading-6 text-muted">{show.text}</p>
                  </div>
                </div>
              </article>
            ))}
          </div>
        )}
      </aside>
    </div>
  );
}

function MagazinesTab({ items }) {
  if (items.length === 0) {
    return <EmptyState title="Журналы пока не добавлены" text="Записи типа magazine появятся здесь после ответа backend." />;
  }

  return (
    <div className="grid gap-5 md:grid-cols-2 lg:grid-cols-3">
      {items.map((magazine, index) => (
        <article key={magazine.id} className="group overflow-hidden rounded-xl border border-line bg-surface">
          <div className={cn("relative flex aspect-[4/5] flex-col justify-between p-6 text-white sm:p-8", index % 2 ? "bg-accent" : "bg-primary")}>
            <span className="text-xs font-bold uppercase tracking-[0.16em] text-white/60">Журнал ДГТУ Медиа</span>
            <div>
              <span className="font-serif text-7xl text-white/15">{String(index + 1).padStart(2, "0")}</span>
              <h2 className="mt-2 font-serif text-4xl leading-tight">{magazine.title}</h2>
              <p className="mt-3 text-sm text-white/60">{magazine.issue}</p>
            </div>
          </div>
          <div className="p-5 sm:p-6">
            <p className="leading-7 text-muted">{magazine.text}</p>
            <ExternalLink href={magazine.url}>Открыть выпуск</ExternalLink>
          </div>
        </article>
      ))}
    </div>
  );
}

function SocialTab({ items }) {
  if (items.length === 0) {
    return <EmptyState title="Соцсети пока не добавлены" text="Записи типа social появятся здесь после ответа backend." />;
  }

  return (
    <div className="grid gap-5 md:grid-cols-2 lg:grid-cols-3">
      {items.map((channel, index) => {
        const Icon = index % 2 ? Send : MessageCircle;
        return (
          <article key={channel.id} className="rounded-xl border border-line bg-surface p-5 sm:p-6">
            <div className="flex items-start justify-between gap-4">
              <div className="grid size-12 place-items-center rounded-lg bg-accent-soft text-accent">
                <Icon className="size-6" />
              </div>
              {channel.audience && <Badge>{channel.audience}</Badge>}
            </div>
            <h2 className="mt-7 font-serif text-3xl">{channel.title}</h2>
            {channel.handle && <p className="mt-1 text-sm font-semibold text-primary">{channel.handle}</p>}
            <p className="mt-4 leading-7 text-muted">{channel.text}</p>
            <ExternalLink href={channel.url}>Перейти</ExternalLink>
          </article>
        );
      })}
    </div>
  );
}

export function MediaChannelsPage() {
  const [params, setParams] = useSearchParams();
  const reduceMotion = useReducedMotion();
  const mediaQuery = useQuery({
    queryKey: queryKeys.media,
    queryFn: directoriesApi.media,
  });
  const media = normalizeMedia(mediaQuery.data);
  const active = tabs.some((tab) => tab.id === params.get("tab"))
    ? params.get("tab")
    : "radio";
  const radioItems = filtered(media, ["radio", "радио"]);
  const magazineItems = filtered(media, ["magazine", "journal", "журнал"]);
  const socialItems = filtered(media, ["social", "соц"]);

  return (
    <div className="page-shell-wide py-9 md:py-12">
      <header className="grid gap-6 border-b border-line pb-8 md:grid-cols-2 md:items-end">
        <div>
          <p className="text-xs font-bold uppercase tracking-widest text-accent">Экосистема ДГТУ Медиа</p>
          <h1 className="mt-3 font-serif text-4xl sm:text-5xl md:text-6xl">Медиаканалы</h1>
        </div>
        <p className="max-w-xl text-base leading-7 text-muted md:justify-self-end md:text-lg">
          Радиоэфир, университетские журналы и официальные сообщества загружаются через `/api/media`.
        </p>
      </header>

      <div className="mt-7 flex gap-2 overflow-x-auto pb-2" role="tablist" aria-label="Медиаканалы">
        {tabs.map(({ id, label, icon: Icon }) => (
          <button
            key={id}
            type="button"
            role="tab"
            aria-selected={active === id}
            onClick={() => setParams({ tab: id })}
            className={cn(
              "flex h-11 shrink-0 items-center gap-2 rounded-md border px-4 text-sm font-semibold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent",
              active === id
                ? "border-primary bg-primary text-white"
                : "border-line bg-surface text-ink hover:border-primary",
            )}
          >
            <Icon className="size-4" />
            {label}
          </button>
        ))}
      </div>

      <div className="mt-7">
        {mediaQuery.isLoading && <Skeleton className="h-96" />}
        {mediaQuery.isError && <ErrorState retry={() => mediaQuery.refetch()} />}
        {mediaQuery.isSuccess && (
          <AnimatePresence mode="wait" initial={false}>
            <motion.div
              key={active}
              initial={reduceMotion ? false : { opacity: 0, y: 12 }}
              animate={{ opacity: 1, y: 0 }}
              exit={reduceMotion ? { opacity: 1 } : { opacity: 0, y: -8 }}
              transition={{ duration: reduceMotion ? 0 : 0.28, ease: [0.2, 0, 0, 1] }}
            >
              {active === "radio" && <RadioTab items={radioItems} />}
              {active === "magazines" && <MagazinesTab items={magazineItems} />}
              {active === "social" && <SocialTab items={socialItems} />}
            </motion.div>
          </AnimatePresence>
        )}
      </div>
    </div>
  );
}
