"use client";

import type { CloudflareAccount } from "@domainops/shared-types";
import { App, Button, Card, Popconfirm, Table, Tag, Tooltip, Typography } from "antd";
import { ApiOutlined, DeleteOutlined, EditOutlined, PlusOutlined, SyncOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import { useCallback, useEffect, useState } from "react";
import {
  deleteCloudflareAccount,
  listCloudflareAccounts,
  syncCloudflareAccount,
  testCloudflareConnection,
} from "@/lib/api/cloudflare";
import { ApiError } from "@/lib/api/client";
import { PageGuide } from "@/components/features/PageGuide";
import { CLOUDFLARE_ACCOUNTS_GUIDES } from "@/lib/guides/cloudflare";
import { SORT_DIRECTIONS, textCompare } from "@/lib/utils/sort";
import { PAGE_SIZE_OPTIONS } from "@/lib/hooks/useServerPagination";
import { CloudflareFormModal } from "./CloudflareFormModal";
import { LinkedDomainsPanel } from "./LinkedDomainsPanel";
import { ZonesModal } from "./ZonesModal";

export default function CloudflarePage() {
  const { message, modal } = App.useApp();
  const [accounts, setAccounts] = useState<CloudflareAccount[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isFormOpen, setIsFormOpen] = useState(false);
  const [editingAccount, setEditingAccount] = useState<CloudflareAccount | null>(null);
  const [zonesAccount, setZonesAccount] = useState<CloudflareAccount | null>(null);
  const [testingId, setTestingId] = useState<number | null>(null);
  const [syncingId, setSyncingId] = useState<number | null>(null);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [isBulkWorking, setIsBulkWorking] = useState(false);

  const load = useCallback(async () => {
    setIsLoading(true);
    try {
      setAccounts(await listCloudflareAccounts());
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't load Cloudflare accounts.");
    } finally {
      setIsLoading(false);
    }
  }, [message]);

  useEffect(() => {
    // Cloudflare accounts live on the Laravel API - a client fetch on
    // mount, not a state-sync bug.
    // eslint-disable-next-line react-hooks/set-state-in-effect
    void load();
  }, [load]);

  async function handleTest(account: CloudflareAccount) {
    setTestingId(account.id);
    try {
      await testCloudflareConnection(account.id);
      message.success("Connected successfully.");
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Connection failed.");
    } finally {
      setTestingId(null);
      void load();
    }
  }

  async function handleSync(account: CloudflareAccount) {
    setSyncingId(account.id);
    try {
      const result = await syncCloudflareAccount(account.id);
      message.success(
        `Linked ${result.domains_linked}, added ${result.domains_added} new (${result.gsc_records} Search Console record(s) found), against ${result.zones} zone(s).`,
      );
      void load();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't sync this account.");
    } finally {
      setSyncingId(null);
    }
  }

  function handleDelete(account: CloudflareAccount) {
    modal.confirm({
      title: `Delete ${account.label}?`,
      content: "Domains already provisioned through it stay in inventory; this just removes the account.",
      okButtonProps: { danger: true },
      onOk: async () => {
        try {
          await deleteCloudflareAccount(account.id);
          message.success(`${account.label} deleted.`);
          void load();
        } catch (err) {
          message.error(err instanceof ApiError ? err.message : "Couldn't delete that account.");
        }
      },
    });
  }

  const selectedAccounts = accounts.filter((a) => selectedIds.includes(a.id));

  async function runBulk(targets: CloudflareAccount[], action: (a: CloudflareAccount) => Promise<unknown>, successLabel: string) {
    setIsBulkWorking(true);
    try {
      const results = await Promise.allSettled(targets.map(action));
      const succeeded = results.filter((r) => r.status === "fulfilled").length;
      const failed = results.length - succeeded;
      if (succeeded > 0) message.success(`${successLabel} for ${succeeded} account${succeeded === 1 ? "" : "s"}.`);
      if (failed > 0) message.error(`Failed for ${failed} account${failed === 1 ? "" : "s"}.`);
      setSelectedIds([]);
      void load();
    } finally {
      setIsBulkWorking(false);
    }
  }

  async function handleBulkTest() {
    await runBulk(selectedAccounts, (a) => testCloudflareConnection(a.id), "Tested");
  }

  async function handleBulkSync() {
    await runBulk(selectedAccounts, (a) => syncCloudflareAccount(a.id), "Synced");
  }

  async function handleBulkDelete() {
    await runBulk(selectedAccounts, (a) => deleteCloudflareAccount(a.id), "Deleted");
  }

  const columns: ColumnsType<CloudflareAccount> = [
    { title: "Label", dataIndex: "label", sorter: (a, b) => textCompare(a.label, b.label), sortDirections: SORT_DIRECTIONS, render: (v: string) => <span className="font-semibold">{v}</span> },
    { title: "CF Email", dataIndex: "cf_email", render: (v: string | null) => v ?? "—" },
    {
      title: "Projects",
      render: (_, account) => (account.brands?.length ? account.brands.map((b) => b.name).join(", ") : "—"),
    },
    {
      title: "Zones",
      dataIndex: "zone_count",
      render: (count: number, account) => (
        <Button
          type="link"
          size="small"
          onClick={() => setZonesAccount(account)}
          className="dms_cloudflare_zones_count_btn"
        >
          {count}
        </Button>
      ),
    },
    {
      title: "Last Test",
      render: (_, account) =>
        account.last_test_succeeded === null ? (
          "—"
        ) : (
          <Tag color={account.last_test_succeeded ? "green" : "red"}>
            {account.last_test_succeeded ? "OK" : "Failed"}
          </Tag>
        ),
    },
    {
      title: "Actions",
      render: (_, account) => (
        <div className="flex gap-2">
          <Tooltip title="Edit">
            <Button
              size="small"
              icon={<EditOutlined />}
              onClick={() => {
                setEditingAccount(account);
                setIsFormOpen(true);
              }}
              className="dms_cloudflare_edit_account_btn"
            />
          </Tooltip>
          <Tooltip title="Test Connection">
            <Button
              size="small"
              icon={<ApiOutlined />}
              loading={testingId === account.id}
              onClick={() => handleTest(account)}
              className="dms_cloudflare_test_connection_btn"
            />
          </Tooltip>
          <Tooltip title="Sync Domains & Zones From Cloudflare">
            <Button
              size="small"
              icon={<SyncOutlined />}
              loading={syncingId === account.id}
              onClick={() => handleSync(account)}
              className="dms_cloudflare_sync_btn"
            />
          </Tooltip>
          <Tooltip title="Delete">
            <Button
              size="small"
              danger
              icon={<DeleteOutlined />}
              onClick={() => handleDelete(account)}
              className="dms_cloudflare_delete_account_btn"
            />
          </Tooltip>
        </div>
      ),
    },
  ];

  return (
    <div className="flex flex-col gap-4 page page-cloudflare">
      <div className="flex items-center gap-2">
        <Typography.Title level={4} style={{ margin: 0 }}>
          Cloudflare
        </Typography.Title>
        <PageGuide guides={CLOUDFLARE_ACCOUNTS_GUIDES} label="Cloudflare accounts guide" />
      </div>

      <Card
        title="Accounts"
        className="cloudflare-accounts-card dms_cloudflare_accounts_card"
        extra={
          <Button
            size="small"
            icon={<PlusOutlined />}
            onClick={() => {
              setEditingAccount(null);
              setIsFormOpen(true);
            }}
            className="dms_cloudflare_add_account_btn"
          >
            Add Account
          </Button>
        }
      >
        {selectedIds.length > 0 && (
          <div className="flex items-center gap-2 flex-wrap mb-3 dms_cloudflare_bulk_bar">
            <Typography.Text>{selectedIds.length} selected</Typography.Text>
            <Popconfirm title="Test connection for the selected accounts?" onConfirm={handleBulkTest}>
              <Button size="small" icon={<ApiOutlined />} loading={isBulkWorking} className="dms_cloudflare_bulk_test_btn">
                Test Connection
              </Button>
            </Popconfirm>
            <Popconfirm title="Sync the selected accounts?" onConfirm={handleBulkSync}>
              <Button size="small" icon={<SyncOutlined />} loading={isBulkWorking} className="dms_cloudflare_bulk_sync_btn">
                Sync
              </Button>
            </Popconfirm>
            <Popconfirm title="Delete the selected accounts?" onConfirm={handleBulkDelete}>
              <Button size="small" danger icon={<DeleteOutlined />} loading={isBulkWorking} className="dms_cloudflare_bulk_delete_btn">
                Delete
              </Button>
            </Popconfirm>
            <Button size="small" onClick={() => setSelectedIds([])} className="dms_cloudflare_bulk_clear_btn">
              Clear
            </Button>
          </div>
        )}
        <Table<CloudflareAccount>
          rowKey="id"
          columns={columns}
          dataSource={accounts}
          loading={isLoading}
          rowSelection={{
            selectedRowKeys: selectedIds,
            onChange: (keys) => setSelectedIds(keys as number[]),
          }}
          pagination={{ showSizeChanger: true, pageSizeOptions: PAGE_SIZE_OPTIONS, showTotal: (count) => `${count} accounts` }}
          expandable={{ expandedRowRender: (account) => <LinkedDomainsPanel account={account} /> }}
          className="dms_cloudflare_accounts_table"
        />
        <CloudflareFormModal
          open={isFormOpen}
          account={editingAccount}
          onClose={() => setIsFormOpen(false)}
          onSaved={() => {
            setIsFormOpen(false);
            void load();
          }}
        />
        <ZonesModal open={!!zonesAccount} account={zonesAccount} onClose={() => setZonesAccount(null)} />
      </Card>
    </div>
  );
}
