import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useQueryClient } from "@tanstack/react-query";
import { Check, ExternalLink, FolderPlus, ListPlus, Play, RotateCcw, Star, X } from "lucide-react";
import { api, type PlexFilters, type PlexItemDetail } from "../lib/api";
import { formatRuntime } from "../lib/format";
import { DetailCustomizeMenu, Filterable, PrefToggle, useArtBackdrop, useDetailPrefs } from "../lib/plexDetailUi";
import PlexCollectionEditor from "./PlexCollectionEditor";
import PlexPlaylistAdd from "./PlexPlaylistAdd";

// The rich "media info" surface for a Plex item — poster/art, IMDb score + link, content rating,
// genres, director, cast (with photos), summary. Reused in TWO places: a full-page view opened from
// a card's "i" button (variant="page", with a big Play/Resume + watch controls), and a lean overlay
// over the running player (variant="overlay", opened with "i"). Two GUI elements are user-toggleable
// personal preferences, persisted in users.preferences: the faint art backdrop and the cast row.

type Props = {
  detail: PlexItemDetail;
  variant: "page" | "overlay";
  onPlay?: () => void; // page: start/resume playback
  onClose?: () => void; // overlay: dismiss
  onStateChange?: () => void; // after a watch-state change, let the opener refresh
  // When provided, metadata (year/genre/director/cast/studio/rating) becomes clickable and sets
  // the corresponding Plex filter (then the opener navigates to the filtered grid).
  onFilter?: (patch: Partial<PlexFilters>) => void;
  // Play a sibling title from a collection strip (opens its player).
  onPlayItem?: (id: string) => void;
  // The item's library key — enables the admin "Manage collections" editor (page variant, movies).
  library?: string;
};

export default function PlexInfo({
  detail,
  variant,
  onPlay,
  onClose,
  onStateChange,
  onFilter,
  onPlayItem,
  library,
}: Props) {
  const { t } = useTranslation();
  const qc = useQueryClient();

  // Personal display prefs (default ON), shared with the series detail pages via useDetailPrefs:
  // artBg/showCast + their toggles and the raw savePref persister. The collection-strip source hiding
  // is PlexInfo-specific state, persisted through the same savePref.
  const { artBg, showCast, toggleArtBg, toggleCast, savePref } = useDetailPrefs();
  const prefs = (qc.getQueryData<{ preferences?: Record<string, unknown> }>(["me"])?.preferences ??
    {}) as { plexHiddenStripSources?: string[] };
  // Which collection-strip source buckets the user has HIDDEN (default: none → all shown). Toggled
  // per type in the customize menu (Collections / IMDb / TMDb / …), only for sources present here.
  const [hiddenSources, setHiddenSources] = useState<string[]>(
    Array.isArray(prefs.plexHiddenStripSources) ? prefs.plexHiddenStripSources : [],
  );
  const toggleSource = (src: string) => {
    setHiddenSources((cur) => {
      const next = cur.includes(src) ? cur.filter((s) => s !== src) : [...cur, src];
      savePref({ plexHiddenStripSources: next });
      return next;
    });
  };
  const isAdmin = (qc.getQueryData<{ role?: string }>(["me"])?.role) === "admin";
  const [editorOpen, setEditorOpen] = useState(false);
  const [playlistOpen, setPlaylistOpen] = useState(false);

  // Faint art backdrop, HTPC-style (page variant only) — the shared hook paints the item's art as a
  // fixed background on <main> and clears it on unmount / when disabled / in the overlay variant.
  useArtBackdrop(detail.art, variant !== "overlay" && artBg);

  const inProgress = (detail.position_seconds ?? 0) > 0 && detail.status !== "watched";
  const setState = async (status: "new" | "watched") => {
    await api.plexSetState(detail.id, status).catch(() => {});
    qc.invalidateQueries({ queryKey: ["plex-item", detail.id] });
    qc.invalidateQueries({ queryKey: ["plex-library"] });
    qc.invalidateQueries({ queryKey: ["plex-show"] });
    onStateChange?.();
  };

  const cast = showCast ? detail.cast : [];
  const overlay = variant === "overlay";
  const mutedCls = overlay ? "text-white/70" : "text-muted";

  // Distinct strip-source buckets present on THIS item, in strip order — one toggle each.
  const presentSources = (detail.collections ?? []).reduce<string[]>((acc, c) => {
    if (!acc.includes(c.source)) acc.push(c.source);
    return acc;
  }, []);
  const sourceLabel = (src: string) =>
    t(`plex.info.stripSource.${src}`, { defaultValue: src.toUpperCase() });

  return (
    <div className={overlay ? "relative w-full max-w-3xl" : "relative glass-media"}>
      <div className={overlay ? "p-5" : "flex flex-col gap-4 p-3 sm:p-4"}>
        {/* Hero block: floats as a frosted glass panel over the fixed art backdrop (page variant). */}
        <div
          className={overlay ? "" : "glass rounded-2xl p-4 sm:p-6"}
        >
        {/* Header: close (overlay) / customize */}
        <div className="mb-4 flex items-start gap-3">
          <div className="min-w-0 flex-1">
            <h1 className={overlay ? "text-lg font-bold text-white" : "text-2xl font-bold"}>
              {detail.kind === "episode" && detail.show_title ? detail.show_title : detail.title}
            </h1>
            {detail.kind === "episode" && (
              <p className={`text-sm ${overlay ? "text-white/70" : "text-muted"}`}>
                S{detail.season_number}·E{detail.episode_number} — {detail.title}
              </p>
            )}
          </div>
          <DetailCustomizeMenu
            overlay={overlay}
            artBg={artBg}
            onToggleArtBg={toggleArtBg}
            showCast={showCast}
            onToggleCast={toggleCast}
            hasCast={detail.cast.length > 0}
            extra={presentSources.map((src) => (
              <PrefToggle
                key={src}
                label={sourceLabel(src)}
                on={!hiddenSources.includes(src)}
                onClick={() => toggleSource(src)}
              />
            ))}
          />
          {overlay && onClose && (
            <button
              onClick={onClose}
              className="shrink-0 p-1.5 rounded-lg text-white/80 hover:bg-white/15"
              aria-label={t("plex.player.back")}
            >
              <X className="w-5 h-5" />
            </button>
          )}
        </div>

        <div className="flex gap-4 sm:gap-6">
          {/* Poster */}
          <img
            src={detail.thumb}
            alt=""
            className={`shrink-0 rounded-xl border border-border object-cover ${overlay ? "w-24 sm:w-28" : "w-32 sm:w-44"} aspect-[2/3]`}
          />

          <div className={`min-w-0 flex-1 ${overlay ? "text-white/90" : ""}`}>
            {/* Meta line + IMDb rating/link (each value can set the matching filter). */}
            <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-sm">
              {detail.year != null && (
                <Filterable
                  className={mutedCls}
                  title={onFilter ? t("plex.info.filterYear", { year: detail.year }) : undefined}
                  onClick={onFilter ? () => onFilter({ yearMin: detail.year, yearMax: detail.year }) : undefined}
                >
                  {detail.year}
                </Filterable>
              )}
              {detail.content_rating && (
                <Filterable
                  className={mutedCls}
                  onClick={onFilter ? () => onFilter({ contentRatings: [detail.content_rating!] }) : undefined}
                >
                  {detail.content_rating}
                </Filterable>
              )}
              {detail.duration_seconds ? <span className={mutedCls}>{formatRuntime(detail.duration_seconds)}</span> : null}
              {detail.studio && (
                <Filterable
                  className={mutedCls}
                  onClick={onFilter ? () => onFilter({ studios: [detail.studio!] }) : undefined}
                >
                  {detail.studio}
                </Filterable>
              )}
              {detail.imdb_rating != null && (
                <span className="inline-flex items-center gap-1 rounded-md bg-amber-400/15 px-1.5 py-0.5 font-semibold text-amber-500">
                  <button
                    onClick={onFilter ? () => onFilter({ ratingMin: Math.floor(detail.imdb_rating!) }) : undefined}
                    className={`inline-flex items-center gap-1 ${onFilter ? "cursor-pointer hover:opacity-80" : "cursor-default"}`}
                    title={onFilter ? t("plex.info.filterRating", { n: Math.floor(detail.imdb_rating!) }) : undefined}
                  >
                    <Star className="w-3.5 h-3.5 fill-current" />
                    {detail.imdb_rating.toFixed(1)}
                  </button>
                  {detail.imdb_url && (
                    <a href={detail.imdb_url} target="_blank" rel="noopener noreferrer" title={t("plex.info.openImdb")}>
                      <ExternalLink className="w-3 h-3 opacity-70 hover:opacity-100" />
                    </a>
                  )}
                </span>
              )}
            </div>

            {detail.tagline && (
              <p className={`mt-2 text-sm italic ${overlay ? "text-white/60" : "text-muted"}`}>
                {detail.tagline}
              </p>
            )}

            {detail.genres.length > 0 && (
              <div className="mt-2 flex flex-wrap gap-1.5">
                {detail.genres.map((g) => (
                  <Filterable
                    key={g}
                    className={`rounded-full px-2 py-0.5 text-xs ${overlay ? "bg-white/10" : "bg-surface text-muted"}`}
                    onClick={onFilter ? () => onFilter({ genres: [g] }) : undefined}
                  >
                    {g}
                  </Filterable>
                ))}
              </div>
            )}

            {detail.directors.length > 0 && (
              <p className={`mt-2 text-sm ${mutedCls}`}>
                {t("plex.info.director")}:{" "}
                {detail.directors.map((d, i) => (
                  <span key={d}>
                    <Filterable
                      className="font-medium"
                      onClick={onFilter ? () => onFilter({ directors: [d] }) : undefined}
                    >
                      {d}
                    </Filterable>
                    {i < detail.directors.length - 1 ? ", " : ""}
                  </span>
                ))}
              </p>
            )}

            {detail.summary && (
              <p className={`mt-3 text-sm leading-relaxed ${overlay ? "text-white/85 line-clamp-5" : ""}`}>
                {detail.summary}
              </p>
            )}

            {/* Page actions: Play/Resume + watch controls */}
            {!overlay && (
              <div className="mt-4 flex flex-wrap items-center gap-2">
                {onPlay && (
                  <button
                    onClick={onPlay}
                    className="inline-flex items-center gap-2 rounded-xl bg-accent px-4 py-2 font-medium text-white hover:opacity-90"
                  >
                    <Play className="w-5 h-5 fill-current" />
                    {inProgress ? t("plex.resume") : t("plex.play")}
                  </button>
                )}
                {detail.status === "watched" ? (
                  <button
                    onClick={() => setState("new")}
                    className="glass-card glass-hover inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm hover:text-accent"
                  >
                    <RotateCcw className="w-4 h-4" />
                    {t("plex.info.markUnwatched")}
                  </button>
                ) : (
                  <button
                    onClick={() => setState("watched")}
                    className="glass-card glass-hover inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm hover:text-accent"
                  >
                    <Check className="w-4 h-4" />
                    {t("plex.info.markWatched")}
                  </button>
                )}
                {inProgress && (
                  <button
                    onClick={() => setState("new")}
                    className="glass-card glass-hover inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm hover:text-accent"
                  >
                    <RotateCcw className="w-4 h-4" />
                    {t("plex.info.clearResume")}
                  </button>
                )}
                {detail.kind === "movie" && (
                  <button
                    onClick={() => setPlaylistOpen(true)}
                    className="glass-card glass-hover inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm hover:text-accent"
                  >
                    <ListPlus className="w-4 h-4" />
                    {t("plex.playlistAdd.manage")}
                  </button>
                )}
                {isAdmin && detail.kind === "movie" && library && (
                  <button
                    onClick={() => setEditorOpen(true)}
                    className="glass-card glass-hover inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm hover:text-accent"
                  >
                    <FolderPlus className="w-4 h-4" />
                    {t("plex.collEditor.manage")}
                  </button>
                )}
              </div>
            )}
          </div>
        </div>
        </div>
        {/* End hero panel. */}

        {/* Cast row (toggleable), circular photos. */}
        {cast.length > 0 && (
          <div
            className={overlay ? "mt-5" : "glass-card rounded-2xl p-4 sm:p-5"}
          >
            <h2 className={`mb-2 text-sm font-semibold ${overlay ? "text-white/80" : ""}`}>
              {t("plex.info.cast")}
            </h2>
            <div className="flex gap-3 overflow-x-auto pb-2">
              {cast.map((c, i) => {
                const inner = (
                  <>
                    <div
                      className={`mx-auto mb-1 h-20 w-20 overflow-hidden rounded-full border ${
                        overlay ? "border-white/15 bg-white/10" : "border-border bg-surface"
                      } ${onFilter ? "group-hover/cast:border-accent" : ""}`}
                    >
                      {c.thumb ? (
                        <img src={c.thumb} alt="" className="h-full w-full object-cover" />
                      ) : (
                        <div className="grid h-full w-full place-items-center text-lg opacity-40">
                          {c.name.charAt(0)}
                        </div>
                      )}
                    </div>
                    <div
                      className={`truncate text-xs font-medium ${overlay ? "text-white/90" : ""} ${
                        onFilter ? "group-hover/cast:text-accent" : ""
                      }`}
                    >
                      {c.name}
                    </div>
                    {c.role && (
                      <div className={`truncate text-[11px] ${overlay ? "text-white/55" : "text-muted"}`}>
                        {c.role}
                      </div>
                    )}
                  </>
                );
                return onFilter ? (
                  <button
                    key={i}
                    onClick={() => onFilter({ actors: [c.name] })}
                    title={t("plex.info.filterActor", { name: c.name })}
                    className="group/cast w-20 shrink-0 text-center"
                  >
                    {inner}
                  </button>
                ) : (
                  <div key={i} className="w-20 shrink-0 text-center">
                    {inner}
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {/* Collection strips — the other titles in this movie's collection(s), directly playable.
            Each source bucket (Collections / IMDb / TMDb / smart / …) is independently hideable. */}
        {detail.collections
          ?.filter((col) => !hiddenSources.includes(col.source))
          .map((col) => (
          <div
            key={col.id}
            className={overlay ? "mt-6" : "glass-card rounded-2xl p-4 sm:p-5"}
          >
            <div className="mb-2 flex items-center justify-between gap-3">
              <h2 className={`text-sm font-semibold ${overlay ? "text-white/80" : ""}`}>{col.title}</h2>
              {onFilter && (
                <button
                  onClick={() => onFilter({ collection: col.id, collectionTitle: col.title })}
                  className="shrink-0 text-xs text-muted hover:text-accent"
                >
                  {t("plex.info.browseCollection")}
                </button>
              )}
            </div>
            <div className="flex gap-3 overflow-x-auto pb-2">
              {col.items.map((m) => (
                <button
                  key={m.id}
                  onClick={() => onPlayItem?.(m.id)}
                  disabled={!onPlayItem}
                  className="group/col w-28 shrink-0 text-left"
                >
                  <div className="relative aspect-[2/3] overflow-hidden rounded-lg border border-border bg-surface">
                    <img
                      src={m.thumb}
                      alt=""
                      className="h-full w-full object-cover transition group-hover/col:scale-105"
                    />
                    {m.status === "watched" && (
                      <span className="absolute right-1 top-1 rounded bg-black/70 px-1 text-[9px] text-white">✓</span>
                    )}
                    {onPlayItem && (
                      <div className="absolute inset-0 grid place-items-center bg-black/40 opacity-0 transition group-hover/col:opacity-100">
                        <Play className="h-8 w-8 text-white" fill="currentColor" />
                      </div>
                    )}
                    {(m.position_seconds ?? 0) > 0 && m.status !== "watched" && m.duration_seconds ? (
                      <div className="absolute inset-x-0 bottom-0 h-0.5 bg-black/40">
                        <div
                          className="h-full bg-accent"
                          style={{ width: `${Math.min(100, ((m.position_seconds ?? 0) / m.duration_seconds) * 100)}%` }}
                        />
                      </div>
                    ) : null}
                  </div>
                  <div className={`mt-1 truncate text-xs font-medium ${overlay ? "text-white/90" : ""}`}>
                    {m.title}
                  </div>
                  {m.year ? <div className="text-[11px] text-muted">{m.year}</div> : null}
                </button>
              ))}
            </div>
          </div>
        ))}
      </div>
      {editorOpen && library && (
        <PlexCollectionEditor
          item={{ id: detail.id, title: detail.title }}
          library={library}
          memberOf={(detail.collections ?? []).map((c) => c.id)}
          onClose={() => setEditorOpen(false)}
          onChanged={() => onStateChange?.()}
        />
      )}
      {playlistOpen && (
        <PlexPlaylistAdd
          target={{ kind: "single", ratingKey: detail.id, title: detail.title }}
          onClose={() => setPlaylistOpen(false)}
        />
      )}
    </div>
  );
}
