"use client";

import type { BulkDomainFilters, BulkJob } from "@domainops/shared-types";
import { App, Button, Dropdown, Modal, Table, Tag } from "antd";
import { DownOutlined } from "@ant-design/icons";
import { useState } from "react";
import {
  bulkCheckAccess,
  bulkRequestGscVerification,
  bulkToggleRobots,
  bulkVerifyGsc,
} from "@/lib/api/bulkSeo";
import type { BulkSelection } from "@/lib/api/bulkSeo";
import { ApiError } from "@/lib/api/client";

type ResultRow = { domain_id: number; fqdn: string; outcome: string; detail?: string };

export function BulkSeoBar({
  selectedIds,
  filters,
  totalFiltered,
  onDone,
}: {
  selectedIds: number[];
  filters: BulkDomainFilters;
  totalFiltered: number;
  onDone: () => void;
}) {
  const { message, modal } = App.useApp();
  const [isBusy, setIsBusy] = useState(false);
  const [results, setResults] = useState<ResultRow[] | null>(null);
  const [resultsTitle, setResultsTitle] = useState("");

  const hasSelection = selectedIds.length > 0;
  const selection: BulkSelection = hasSelection ? { domain_ids: selectedIds } : { filters };
  const scopeLabel = hasSelection ? `${selectedIds.length} selected` : `all ${totalFiltered} matching the filter`;
  const canRunOnFilter = hasSelection || Object.values(filters).some((v) => v !== undefined && v !== "");

  function showJobResults(title: string, job: BulkJob, extract: (r: Record<string, unknown>) => { outcome: string; detail?: string }) {
    const rows = (job.payload?.results as Record<string, unknown>[] | undefined) ?? [];
    setResultsTitle(title);
    setResults(
      rows.map((r) => ({
        domain_id: r.domain_id as number,
        fqdn: r.fqdn as string,
        ...extract(r),
      })),
    );
  }

  async function runToggle(index: boolean) {
    setIsBusy(true);
    try {
      const job = await bulkToggleRobots(selection, index);
      message.success(`${job.done} of ${job.total} updated.`);
      showJobResults(index ? "Set indexable" : "Set noindex", job, (r) => ({
        outcome: r.success ? "success" : "failed",
        detail: r.message as string,
      }));
      onDone();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Bulk update failed.");
    } finally {
      setIsBusy(false);
    }
  }

  async function runCheckAccess() {
    setIsBusy(true);
    try {
      const rows = await bulkCheckAccess(selection);
      setResultsTitle("Check access");
      setResults(
        rows.map((r) => ({
          domain_id: r.domain_id,
          fqdn: r.fqdn,
          outcome: r.robots_txt,
          detail: `sitemap: ${r.sitemap_xml} · points to sitemap: ${r.robots_points_to_sitemap}`,
        })),
      );
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Bulk check failed.");
    } finally {
      setIsBusy(false);
    }
  }

  async function runGscRequest() {
    setIsBusy(true);
    try {
      const job = await bulkRequestGscVerification(selection);
      message.success(`Verification requested for ${job.total} domains.`);
      showJobResults("GSC verification requested", job, (r) => ({
        outcome: "token generated",
        detail: r.token as string,
      }));
      onDone();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Bulk request failed.");
    } finally {
      setIsBusy(false);
    }
  }

  async function runGscVerify() {
    setIsBusy(true);
    try {
      const job = await bulkVerifyGsc(selection);
      message.success(`${job.done} of ${job.total} verified.`);
      showJobResults("GSC verification check", job, (r) => ({
        outcome: r.verified ? "verified" : "not yet",
        detail: r.message as string | undefined,
      }));
      onDone();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Bulk verification check failed.");
    } finally {
      setIsBusy(false);
    }
  }

  function confirmAndRun(title: string, description: string, action: () => void) {
    modal.confirm({
      title,
      content: description,
      okText: "Run",
      onOk: action,
    });
  }

  const items = [
    {
      key: "index",
      label: `Set indexable (${scopeLabel})`,
      onClick: () => confirmAndRun("Set indexable?", `Applies to ${scopeLabel}.`, () => runToggle(true)),
    },
    {
      key: "noindex",
      label: `Set noindex (${scopeLabel})`,
      onClick: () => confirmAndRun("Set noindex?", `Applies to ${scopeLabel}.`, () => runToggle(false)),
    },
    { key: "check", label: `Check access (${scopeLabel})`, onClick: runCheckAccess },
    {
      key: "gsc-request",
      label: `Request GSC verification (${scopeLabel})`,
      onClick: () =>
        confirmAndRun("Request GSC verification?", `Generates a new token for ${scopeLabel}.`, runGscRequest),
    },
    { key: "gsc-verify", label: `Check GSC verification (${scopeLabel})`, onClick: runGscVerify },
  ];

  return (
    <>
      <Dropdown menu={{ items }} disabled={!canRunOnFilter || isBusy} trigger={["click"]} className="bulk-seo-bar">
        <Button loading={isBusy} className="dms_bulk_seo_actions_btn">
          Bulk SEO actions <DownOutlined />
        </Button>
      </Dropdown>

      <Modal
        title={resultsTitle}
        open={!!results}
        onCancel={() => setResults(null)}
        footer={null}
        width={600}
        className="bulk-seo-bar__results dms_bulk_seo_results_modal"
      >
        <Table<ResultRow>
          rowKey="domain_id"
          size="small"
          dataSource={results ?? []}
          pagination={false}
          className="dms_bulk_seo_results_table"
          columns={[
            { title: "Domain", dataIndex: "fqdn", render: (v: string) => <span className="font-mono text-xs">{v}</span> },
            {
              title: "Outcome",
              dataIndex: "outcome",
              render: (v: string) => (
                <Tag color={["success", "verified", "reachable", "token generated"].includes(v) ? "green" : "default"}>
                  {v}
                </Tag>
              ),
            },
            { title: "Detail", dataIndex: "detail", render: (v: string | undefined) => v ?? "—" },
          ]}
        />
      </Modal>
    </>
  );
}
