import { useTranslation } from "react-i18next";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { UserPlus } from "lucide-react";
import { api, type DiscoveredChannel } from "../lib/api";
import { accountKey, LS } from "../lib/storage";
import { formatCountOrDash } from "../lib/format";
import { subsColumn } from "./channelColumns";
import { notify } from "../lib/notifications";
import { notifyYouTubeActionError } from "../lib/youtubeErrors";
import Tooltip from "./Tooltip";
import ChannelLink from "./ChannelLink";
import DataTable, { type Column } from "./DataTable";
import { useConfirm } from "./ConfirmProvider";

// The Channel manager's "Discovery" tab: channels that turn up in the user's playlists but
// that they don't subscribe to. Subscribing here only creates the subscription + enriches
// the channel's metadata — the scheduler pulls its videos on its next run (see backend).
export default function ChannelDiscovery({
  canWrite,
  onOpenWizard,
  onViewChannel,
}: {
  canWrite: boolean;
  onOpenWizard: () => void;
  onViewChannel: (id: string, name: string) => void;
}) {
  const { t } = useTranslation();
  const qc = useQueryClient();
  const confirm = useConfirm();

  const query = useQuery({
    queryKey: ["discovered-channels"],
    queryFn: api.discoveredChannels,
  });

  const subscribe = useMutation({
    mutationFn: (c: DiscoveredChannel) => api.subscribeChannel(c.id),
    onSuccess: (_data, c) => {
      // The channel moves from "discovery" to "subscribed", and its videos will start
      // arriving — refresh both lists plus the per-user status.
      qc.invalidateQueries({ queryKey: ["discovered-channels"] });
      qc.invalidateQueries({ queryKey: ["channels"] });
      qc.invalidateQueries({ queryKey: ["my-status"] });
      const name = c.title ?? c.id;
      // Name the channel and ship a typed payload so the inbox can offer "open in the
      // Channel manager" / "open on YouTube" links — kept after reload, when live
      // callbacks are gone (see ChannelSubscribedMeta).
      notify({
        level: "success",
        title: t("channels.discovery.subscribedTitle"),
        message: t("channels.discovery.subscribedBody", { name }),
        meta: { kind: "channel-subscribed", channelId: c.id, channelName: name },
      });
    },
    onError: (err: unknown) =>
      notifyYouTubeActionError(err, t("channels.discovery.subscribeFailed"), onOpenWizard),
  });

  // Subscribing changes the user's real YouTube account and spends a little quota — confirm
  // first (mirrors the unsubscribe guard in the Subscriptions tab).
  const onSubscribe = async (c: DiscoveredChannel) => {
    const ok = await confirm({
      title: t("channels.discovery.subscribe"),
      message: t("channels.discovery.confirmSubscribe", { name: c.title ?? c.id }),
      confirmLabel: t("channels.discovery.subscribe"),
    });
    if (ok) subscribe.mutate(c);
  };

  const rows = query.data ?? [];

  const columns: Column<DiscoveredChannel>[] = [
    {
      key: "channel",
      header: t("channels.cols.channel"),
      sortable: true,
      sortValue: (c) => (c.title ?? c.id).toLowerCase(),
      filter: { kind: "text", get: (c) => `${c.title ?? ""} ${c.handle ?? ""}` },
      cardPrimary: true,
      render: (c) => (
        <ChannelLink
          id={c.id}
          title={c.title}
          handle={c.handle}
          thumbnailUrl={c.thumbnail_url}
          onView={() => onViewChannel(c.id, c.title ?? c.id)}
        />
      ),
    },
    subsColumn<DiscoveredChannel>(t),
    {
      key: "videos",
      header: t("channels.discovery.cols.totalVideos"),
      align: "right",
      nowrap: true,
      sortable: true,
      sortValue: (c) => c.video_count ?? -1,
      render: (c) => (
        <span className="text-muted tabular-nums">{formatCountOrDash(c.video_count)}</span>
      ),
    },
    {
      key: "inPlaylists",
      header: t("channels.discovery.cols.inPlaylists"),
      align: "right",
      nowrap: true,
      sortable: true,
      sortValue: (c) => c.playlist_video_count,
      render: (c) => (
        <Tooltip
          hint={t("channels.discovery.cols.inPlaylistsHint", {
            videos: c.playlist_video_count,
            playlists: c.playlist_count,
          })}
        >
          <span className="text-muted tabular-nums cursor-help">
            {c.playlist_video_count} / {c.playlist_count}
          </span>
        </Tooltip>
      ),
    },
    {
      key: "actions",
      header: t("channels.cols.actions"),
      align: "right",
      nowrap: true,
      width: "120px",
      cardLabel: false,
      render: (c) => (
        <Tooltip
          hint={
            canWrite
              ? t("channels.discovery.subscribeHint")
              : t("channels.discovery.needWriteHint")
          }
        >
          <button
            onClick={() => onSubscribe(c)}
            disabled={!canWrite || subscribe.isPending}
            className="glass-card glass-hover inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs disabled:opacity-50 transition"
          >
            <UserPlus className="w-3.5 h-3.5" />
            {t("channels.discovery.subscribe")}
          </button>
        </Tooltip>
      ),
    },
  ];

  return (
    <div className="px-4 pb-4 pt-3 max-w-7xl mx-auto">
      <p className="text-xs text-muted mb-4 leading-relaxed">
        {t("channels.discovery.intro")}
      </p>
      {query.isLoading ? (
        <div className="text-muted py-8">{t("channels.discovery.loading")}</div>
      ) : (
        <DataTable
          rows={rows}
          columns={columns}
          rowKey={(c) => c.id}
          persistKey={accountKey(LS.channelDiscoveryTable) ?? undefined}
          controlsPosition="top"
          emptyText={t("channels.discovery.empty")}
        />
      )}
    </div>
  );
}
