"use client";

import type { Brand, Domain, GscState } from "@domainops/shared-types";
import { App, Button, Input, Select, Space, Switch, Table, Tag, Tooltip, Typography } from "antd";
import { ExportOutlined, ReloadOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { listBrands, listDomains } from "@/lib/api/domains";
import { checkSeoLive, toggleRobots } from "@/lib/api/seo";
import { ApiError } from "@/lib/api/client";
import { searchConsoleUrl } from "@/lib/utils/searchConsole";
import { confirmRobotsChange } from "@/lib/utils/robotsConfirm";
import { SORT_DIRECTIONS } from "@/lib/utils/sort";
import { serverPaginationConfig, useServerPagination } from "@/lib/hooks/useServerPagination";
import { titleCase } from "@/lib/utils/text";
import { formatDate } from "@/lib/utils/date";
import { PageGuide } from "@/components/features/PageGuide";
import { SEO_CONTROLS_GUIDES } from "@/lib/guides/seo";
import { BulkSeoBar } from "../domains/BulkSeoBar";

const GSC_COLORS: Record<GscState, string> = {
  not_started: "default",
  pending: "gold",
  verified: "green",
};

/**
 * A dedicated SEO-focused view of the same domain inventory
 * (domains/page.tsx), reusing its filters/BulkSeoBar rather than a parallel
 * implementation - see domainops-mockup.html's #view-seo for the shape this
 * follows: robots state front and center, with a quick per-row toggle.
 */
export default function SeoControlsPage() {
  const { message, modal } = App.useApp();
  const [domains, setDomains] = useState<Domain[]>([]);
  const [brands, setBrands] = useState<Brand[]>([]);
  const [total, setTotal] = useState(0);
  const { page, pageSize, setPage, onChange: onPageChange } = useServerPagination();
  const [sortOrder, setSortOrder] = useState<"ascend" | "descend" | undefined>();
  const [search, setSearch] = useState("");
  const [brandId, setBrandId] = useState<number | undefined>();
  const [gscState, setGscState] = useState<GscState | undefined>();
  const [isLoading, setIsLoading] = useState(true);
  const [togglingId, setTogglingId] = useState<number | null>(null);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [checkingLiveId, setCheckingLiveId] = useState<number | null>(null);
  const [liveStatuses, setLiveStatuses] = useState<Record<number, string>>({});

  const load = useCallback(async () => {
    setIsLoading(true);
    try {
      const result = await listDomains({ search, brand_id: brandId, gsc_state: gscState, page, per_page: pageSize, sort: sortOrder ? "fqdn" : undefined, order: sortOrder });
      setDomains(result.data);
      setTotal(result.meta.total);
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't load domains.");
    } finally {
      setIsLoading(false);
    }
  }, [search, brandId, gscState, sortOrder, page, pageSize, message]);

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    void load();
  }, [load]);

  useEffect(() => {
    void listBrands().then(setBrands);
  }, []);

  async function handleCheckLive(domain: Domain) {
    setCheckingLiveId(domain.id);
    try {
      const { status } = await checkSeoLive(domain.id);
      setLiveStatuses((current) => ({ ...current, [domain.id]: status }));
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't check that domain.");
    } finally {
      setCheckingLiveId(null);
    }
  }

  async function handleToggleRobots(domain: Domain, index: boolean) {
    setTogglingId(domain.id);
    try {
      await toggleRobots(domain.id, index);
      message.success(`${domain.fqdn} set to ${index ? "index" : "noindex"}.`);
      void load();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't change that domain's robots state.");
    } finally {
      setTogglingId(null);
    }
  }

  const columns: ColumnsType<Domain> = [
    {
      title: "Domain",
      dataIndex: "fqdn",
      sorter: true,
      sortOrder: sortOrder ?? null,
      sortDirections: SORT_DIRECTIONS,
      render: (fqdn: string, domain) => (
        <Link href={`/domains/${domain.id}`} className="font-mono">
          {fqdn}
        </Link>
      ),
    },
    { title: "Project", render: (_, domain) => domain.brand?.name ?? "—" },
    {
      title: "Website Visibility - click to toggle",
      dataIndex: "robots_state",
      render: (value: Domain["robots_state"], domain) => (
        <div className="flex items-center gap-2">
          <Tooltip title={value === "index" ? "Click to set noindex, nofollow" : "Click to set index, follow"}>
            <Switch
              checked={value === "index"}
              loading={togglingId === domain.id}
              onChange={(checked) => confirmRobotsChange(modal, domain.fqdn, checked, () => handleToggleRobots(domain, checked))}
              className="dms_seo_robots_toggle"
            />
          </Tooltip>
          <Typography.Text>{value === "index" ? "Index, Follow" : "Noindex, Nofollow"}</Typography.Text>
        </div>
      ),
    },
    {
      title: "GSC",
      dataIndex: "gsc_state",
      render: (value: GscState, domain) => (
        <div className="flex items-center gap-2">
          <Tag color={GSC_COLORS[value]} className="!m-0">
            {titleCase(value.replace("_", " "))}
          </Tag>
          <Tooltip title="Open this domain in Google Search Console">
            <Button
              size="small"
              icon={<ExportOutlined />}
              href={searchConsoleUrl(domain.fqdn, !!domain.parent_domain_id)}
              target="_blank"
              rel="noopener noreferrer"
              aria-label="Open in Google Search Console"
              className="dms_seo_open_gsc_btn"
            />
          </Tooltip>
        </div>
      ),
    },
    {
      title: "GSC verified",
      dataIndex: "gsc_verified_at",
      render: (v: string | null) => formatDate(v),
    },
    {
      title: "Live",
      render: (_, domain) => {
        const status = liveStatuses[domain.id];
        return (
          <div className="flex items-center gap-2">
            {status && (
              <Tag color={status === "reachable" ? "green" : "red"}>{status}</Tag>
            )}
            <Tooltip title="Check if the site is currently reachable">
              <Button
                size="small"
                icon={<ReloadOutlined />}
                loading={checkingLiveId === domain.id}
                onClick={() => void handleCheckLive(domain)}
                className="dms_seo_check_live_btn"
              />
            </Tooltip>
          </div>
        );
      },
    },
  ];

  return (
    <div className="flex flex-col gap-4 page page-seo">
      <div className="flex items-center gap-2 dms_seo_title_row">
        <Typography.Title level={4} style={{ margin: 0 }}>
          SEO Controls
        </Typography.Title>
        <PageGuide guides={SEO_CONTROLS_GUIDES} label="SEO Controls guide" />
      </div>
      <Typography.Paragraph type="secondary" style={{ marginTop: -8 }}>
        One place to see and manage indexability and Search Console verification across your whole portfolio.
      </Typography.Paragraph>

      <Space wrap>
        <Input.Search
          placeholder="Search domains…"
          allowClear
          onSearch={(value) => {
            setPage(1);
            setSearch(value);
          }}
          style={{ width: 240 }}
        />
        <Select
          allowClear
          placeholder="Project"
          style={{ width: 180 }}
          options={brands.map((b) => ({ value: b.id, label: b.name }))}
          onChange={(value) => {
            setPage(1);
            setBrandId(value);
          }}
        />
        <Select
          allowClear
          placeholder="GSC state"
          style={{ width: 160 }}
          options={[
            { value: "not_started", label: "Not Started" },
            { value: "pending", label: "Pending" },
            { value: "verified", label: "Verified" },
          ]}
          onChange={(value) => {
            setPage(1);
            setGscState(value);
          }}
        />
        <BulkSeoBar
          selectedIds={selectedIds}
          filters={{ search: search || undefined, brand_id: brandId, gsc_state: gscState }}
          totalFiltered={total}
          onDone={() => {
            setSelectedIds([]);
            void load();
          }}
        />
      </Space>

      <Table<Domain>
        rowKey="id"
        columns={columns}
        dataSource={domains}
        loading={isLoading}
        rowSelection={{
          selectedRowKeys: selectedIds,
          onChange: (keys) => setSelectedIds(keys as number[]),
        }}
        onChange={(_pagination, _filters, sorter, extra) => {
          if (extra.action !== "sort") return;
          const active = Array.isArray(sorter) ? sorter[0] : sorter;
          setPage(1);
          setSortOrder(active?.order ?? undefined);
        }}
        pagination={serverPaginationConfig(total, page, pageSize, onPageChange, "domains")}
        className="dms_seo_table"
      />
    </div>
  );
}
