import { Play, X } from "lucide-react";
import type { TFunction } from "i18next";
import type { Video } from "../lib/api";
import { formatDuration } from "../lib/format";
import type { Column } from "./tableHeader";

// Column definitions for the playlist detail table, in their own file like `channelColumns.tsx`.
//
// The `grip` column carries no renderer: the drag handle needs the `useSortable` attributes that
// only exist inside the row component, which a `render(row)` closure can't reach. It stays in the
// list anyway so ONE column array drives both the header and the body — the row renderer fills
// that cell itself. Everything else is an ordinary cell.
export const GRIP_KEY = "grip";

export function playlistColumns({
  t,
  indexOf,
  onPlay,
  onRemove,
  canEdit,
}: {
  t: TFunction;
  /** Position in the STORED order (1-based on screen) — not the row's position in the current view,
   * so a view-sort never renumbers the playlist under the reader. */
  indexOf: (v: Video) => number;
  onPlay: (v: Video) => void;
  onRemove: (v: Video) => void;
  canEdit: boolean;
}): Column<Video>[] {
  const cols: Column<Video>[] = [
    { key: GRIP_KEY, header: "", width: "2.25rem", render: () => null, hideInCard: true },
    {
      key: "pos",
      header: "#",
      align: "right",
      width: "4.5rem",
      nowrap: true,
      hideInCard: true,
      // Sorting by "#" ascending is the stored order itself — that is what makes it a truthful
      // default for the header arrow, and a one-click way back from any other sort.
      sortable: true,
      sortValue: indexOf,
      render: (v) => <span className="text-xs text-muted tabular-nums">{indexOf(v) + 1}</span>,
    },
    {
      key: "title",
      header: t("playlists.colTitle"),
      // The flexible column: under `table-fixed` (see Playlists.tsx) width:100% hands it every
      // pixel the fixed columns don't claim. Auto layout could not do this — a `truncate` cell is
      // `white-space: nowrap`, so its MIN-content width is the whole title, and the column grew
      // until Length and the remove button hung off the page scroller.
      width: "100%",
      sortable: true,
      sortValue: (v) => v.title ?? "",
      filter: { kind: "text", get: (v) => v.title ?? "" },
      cardPrimary: true,
      render: (v) => (
        <div className="flex items-center gap-2.5 min-w-0">
          <button
            onClick={() => onPlay(v)}
            aria-label={`${t("card.play")} — ${v.title}`}
            className="relative w-[62px] h-[35px] rounded overflow-hidden bg-surface shrink-0 group"
          >
            {v.thumbnail_url && (
              <img src={v.thumbnail_url} alt="" className="w-full h-full object-cover" />
            )}
            <span className="absolute inset-0 grid place-items-center bg-black/40 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100 transition">
              <Play className="w-4 h-4 text-white fill-current" />
            </span>
          </button>
          <button onClick={() => onPlay(v)} className="min-w-0 flex-1 text-left">
            <span className="block text-[13px] text-fg truncate">{v.title}</span>
          </button>
        </div>
      ),
    },
    {
      key: "channel",
      header: t("playlists.colChannel"),
      width: "12rem",
      nowrap: true,
      sortable: true,
      sortValue: (v) => v.channel_title ?? "",
      filter: { kind: "text", get: (v) => v.channel_title ?? "" },
      render: (v) => (
        <span className="text-[13px] text-muted truncate block">{v.channel_title}</span>
      ),
    },
    {
      key: "duration",
      header: t("playlists.colDuration"),
      align: "right",
      width: "5rem",
      nowrap: true,
      sortable: true,
      // Nulls (live/upcoming, or not yet enriched) sort last in BOTH directions in the old
      // comparator; sortRows is a plain numeric compare, so park them at the end of an ascending
      // sort with a large sentinel rather than letting them read as zero-length.
      sortValue: (v) => v.duration_seconds ?? Number.MAX_SAFE_INTEGER,
      render: (v) =>
        v.duration_seconds != null ? (
          <span className="text-[11px] text-muted tabular-nums">
            {formatDuration(v.duration_seconds)}
          </span>
        ) : v.live_status === "live" || v.live_status === "upcoming" ? (
          <span
            className={`text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded ${
              v.live_status === "live"
                ? "bg-red-500/90 text-white"
                : "bg-card border border-border text-muted"
            }`}
          >
            {t(`card.${v.live_status}`)}
          </span>
        ) : null,
    },
  ];

  if (canEdit) {
    cols.push({
      key: "actions",
      header: "",
      align: "right",
      width: "2.5rem",
      nowrap: true,
      render: (v) => (
        <button
          onClick={() => onRemove(v)}
          title={t("playlists.removeItem")}
          aria-label={t("playlists.removeItemOf", { title: v.title })}
          className="text-muted hover:text-fg p-1"
        >
          <X className="w-4 h-4" />
        </button>
      ),
    });
  }

  return cols;
}
