// src/components/backlink/domain-profile-container.tsx
"use client";

import { ChevronDownIcon, ImportIcon } from "lucide-react";
import { parseAsInteger, parseAsStringEnum, useQueryState } from "nuqs";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { QuotaNotice } from "@/components/billing/quota-notice";
import { StatCard } from "@/components/keywords/overview/stat-card";
import { Button } from "@/components/ui/button";
import { DataTable } from "@/components/ui/data-table";
import {
  ActiveFilterChips,
  FacetDropdown,
  ToolbarMetaRow,
  ToolbarPanel,
  ToolbarRow,
} from "@/components/ui/design-toolbar";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  getDomainBacklinksPageAction,
  getDomainProfileStatsAction,
} from "@/lib/backlink/domain-profile-actions";
import type {
  DomainBacklink,
  DomainBacklinksPage,
  DomainProfileStats,
} from "@/lib/backlink/domain-profile-types";
import { BACKLINK_SOURCES, type BacklinkSource } from "@/lib/backlink/types";
import type { QuotaExceeded } from "@/lib/billing/quotas";
import { useActiveSite } from "@/lib/keywords/site-context";
import { domainProfileColumns } from "./domain-profile-columns";

const PAGE_SIZE = 50;
type Filter = "all" | "dofollow" | "new" | "lost";

const FILTER_LABELS: Record<Exclude<Filter, "all">, string> = {
  dofollow: "Dofollow",
  new: "Nouveaux",
  lost: "Perdus",
};

export function BacklinkProfileContainer({
  initialStats,
  initialPage,
}: {
  initialStats: DomainProfileStats | null;
  initialPage: DomainBacklinksPage;
}) {
  const { activeSiteId } = useActiveSite();
  const inputRef = useRef<HTMLInputElement>(null);
  // Provider chosen in the « Importer ▾ » menu before opening the file picker.
  const pendingSource = useRef<BacklinkSource>("semrush");
  // The server already provided stats + page 0 (filter "all") for this site.
  // Track the loaded params so we never refetch on mount — a boolean ref is
  // defeated by React Strict Mode's double-invoked effects; a key is not.
  const loadedKey = useRef(`${activeSiteId}|0|all`);
  const [stats, setStats] = useState<DomainProfileStats | null>(initialStats);
  const [rows, setRows] = useState<DomainBacklink[]>(initialPage.rows);
  const [total, setTotal] = useState(initialPage.total);
  // URL-synced filter + page. Defaults (page=0 / filter="all") are cleared from
  // the URL, so the first load has no query params and the mount key below
  // still equals loadedKey.current → no fetch on initial mount.
  const [page, setPage] = useQueryState(
    "page",
    parseAsInteger.withDefault(0).withOptions({ clearOnDefault: true }),
  );
  const [filter, setFilter] = useQueryState(
    "filter",
    parseAsStringEnum<Filter>(["all", "dofollow", "new", "lost"])
      .withDefault("all")
      .withOptions({ clearOnDefault: true }),
  );
  const [busy, setBusy] = useState(false);
  const [note, setNote] = useState<string | null>(null);
  const [quota, setQuota] = useState<QuotaExceeded | null>(null);

  const load = useCallback(async () => {
    if (!activeSiteId) return;
    const opts: {
      dofollow?: boolean;
      status?: "new" | "lost";
      page: number;
      pageSize: number;
    } = { page, pageSize: PAGE_SIZE };
    if (filter === "dofollow") opts.dofollow = true;
    if (filter === "new") opts.status = "new";
    if (filter === "lost") opts.status = "lost";
    const [s, p] = await Promise.all([
      getDomainProfileStatsAction(activeSiteId),
      getDomainBacklinksPageAction(activeSiteId, opts),
    ]);
    setStats(s);
    setRows(p.rows);
    setTotal(p.total);
  }, [activeSiteId, page, filter]);

  useEffect(() => {
    // Only refetch when params actually change (site/page/filter) — never on
    // mount. Firing a read server action on mount triggers an implicit route
    // revalidation that races and deadlocks the next client navigation.
    const key = `${activeSiteId}|${page}|${filter}`;
    if (key === loadedKey.current) return;
    loadedKey.current = key;
    void load().catch(() => {});
  }, [activeSiteId, page, filter, load]);

  async function onFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file || !activeSiteId) return;
    setBusy(true);
    setNote(null);
    setQuota(null);
    try {
      const fd = new FormData();
      fd.set("siteId", activeSiteId);
      fd.set("source", pendingSource.current);
      fd.set("file", file);
      const res = await fetch("/backlink/profile/import", {
        method: "POST",
        body: fd,
      });
      const json = (await res.json()) as {
        ok: boolean;
        imported?: number;
        refDomains?: number;
        error?: string;
        quota?: QuotaExceeded;
      };
      if (!json.ok) {
        if (json.quota) {
          // Localized inline (QuotaNotice renders the message + upgrade link).
          setQuota(json.quota);
          return;
        }
        const message = json.error ?? "Import échoué";
        setNote(message);
        toast.error(message);
      } else {
        setNote(
          `Importé : ${json.imported} liens · ${json.refDomains} domaines`,
        );
        toast.success(`Importé : ${json.imported} liens`);
        setPage(0);
        await load();
      }
    } catch {
      setNote("Import impossible.");
      toast.error("Import impossible.");
    } finally {
      setBusy(false);
    }
  }

  const pages = Math.max(1, Math.ceil(total / PAGE_SIZE));

  return (
    <div className="space-y-4 p-4">
      <h1 className="font-semibold text-lg">Profil backlink</h1>
      {quota ? <QuotaNotice quota={quota} kind="import" /> : null}
      {note ? (
        <p className="text-muted-foreground text-sm" aria-live="polite">
          {note}
        </p>
      ) : null}

      {stats ? (
        <div className="grid grid-cols-2 gap-3 md:grid-cols-6">
          <StatCard
            label="Backlinks"
            value={stats.backlinks.toLocaleString("fr-FR")}
          />
          <StatCard
            label="Ref. domains"
            value={stats.refDomains.toLocaleString("fr-FR")}
          />
          <StatCard label="% dofollow" value={`${stats.dofollowPct}%`} />
          <StatCard label="% sitewide" value={`${stats.sitewidePct}%`} />
          <StatCard
            label="Nouveaux"
            value={stats.newCount.toLocaleString("fr-FR")}
          />
          <StatCard
            label="Perdus"
            value={stats.lostCount.toLocaleString("fr-FR")}
          />
        </div>
      ) : null}

      {/* Design panel: toolbar / chips / meta (server pagination) / table. */}
      <ToolbarPanel>
        <ToolbarRow>
          <div className="flex min-w-0 flex-1 flex-wrap items-center gap-2.5">
            <FacetDropdown
              label="Liens"
              allLabel="Tous les liens"
              ariaLabel="Filtrer les backlinks"
              value={filter}
              options={(
                Object.keys(FILTER_LABELS) as Exclude<Filter, "all">[]
              ).map((f) => ({ value: f, label: FILTER_LABELS[f] }))}
              onChange={(v) => {
                void setPage(0);
                void setFilter(v as Filter);
              }}
            />
          </div>
          <div className="flex shrink-0 items-center gap-2.5">
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button
                  className="group h-10 rounded-[11px] bg-blue-600 px-4 font-semibold text-[13px] text-white shadow-[0_1px_10px_rgba(61,90,254,0.35)] hover:bg-blue-500"
                  disabled={busy}
                >
                  <ImportIcon className="size-4" aria-hidden />
                  {busy ? "Import…" : "Importer"}
                  <ChevronDownIcon
                    className="size-3.5 text-white/75 transition-transform group-data-[state=open]:rotate-180"
                    aria-hidden
                  />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent
                align="end"
                className="w-56 rounded-[14px] p-1.5"
              >
                <DropdownMenuLabel className="px-2.5 pt-2 pb-1.5 font-semibold text-[10.5px] text-muted-foreground/70 uppercase tracking-[0.07em]">
                  Importer des backlinks
                </DropdownMenuLabel>
                {BACKLINK_SOURCES.map((s) => (
                  <DropdownMenuItem
                    key={s.id}
                    disabled={!s.ready}
                    onSelect={() => {
                      if (!s.ready) return;
                      pendingSource.current = s.id;
                      inputRef.current?.click();
                    }}
                    className="justify-between gap-3 rounded-[9px]"
                  >
                    <span className="font-medium">{s.label}</span>
                    {s.ready ? (
                      <span className="text-[10.5px] text-muted-foreground">
                        CSV
                      </span>
                    ) : (
                      <span className="rounded-[5px] border bg-muted px-1.5 py-px font-semibold text-[9.5px] text-muted-foreground uppercase">
                        Bientôt
                      </span>
                    )}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuContent>
            </DropdownMenu>
            <input
              ref={inputRef}
              type="file"
              accept=".csv,text/csv"
              className="hidden"
              onChange={onFile}
            />
          </div>
        </ToolbarRow>
        <ActiveFilterChips
          chips={
            filter === "all"
              ? []
              : [
                  {
                    key: "filter",
                    category: "Liens",
                    value: FILTER_LABELS[filter],
                    onRemove: () => {
                      void setPage(0);
                      void setFilter("all");
                    },
                  },
                ]
          }
          onClearAll={() => {
            void setPage(0);
            void setFilter("all");
          }}
        />
        <ToolbarMetaRow
          resultCount={total}
          filterCount={filter === "all" ? 0 : 1}
          pagination={{
            pageIndex: page,
            pageCount: pages,
            pageSize: PAGE_SIZE,
            // Server pagination is fixed at PAGE_SIZE — single option, no-op.
            pageSizeOptions: [PAGE_SIZE],
            onPageSizeChange: () => {},
            onPrevious: () => void setPage((p) => Math.max(0, p - 1)),
            onNext: () => void setPage((p) => Math.min(pages - 1, p + 1)),
          }}
        />
        <DataTable
          columns={domainProfileColumns}
          data={rows}
          getRowId={(r) => r.id}
          caption="Backlinks du domaine du site actif"
          containerClassName="rounded-none border-0 border-t"
        />
      </ToolbarPanel>
    </div>
  );
}
