"use client";

import type { ExpiringDomain } from "@domainops/shared-types";
import { App, Button, Select, Table, Tabs, Tag, Typography } from "antd";
import type { ColumnsType } from "antd/es/table";
import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { listExpiringDomains } from "@/lib/api/acquire";
import { ApiError } from "@/lib/api/client";
import { SORT_DIRECTIONS, textCompare } from "@/lib/utils/sort";
import { titleCase } from "@/lib/utils/text";
import { PAGE_SIZE_OPTIONS } from "@/lib/hooks/useServerPagination";
import { PageGuide } from "@/components/features/PageGuide";
import { REGISTRARS_GUIDES } from "@/lib/guides/registrars";

const DAY_WINDOWS = [30, 60, 90];

function providerOf(domain: ExpiringDomain): string {
  return domain.registrar_account?.provider ?? domain.registrar_label ?? "Unlabeled";
}

function daysUntil(expiresAt: string | null): number | null {
  if (!expiresAt) return null;
  return Math.ceil((new Date(expiresAt).getTime() - Date.now()) / 86_400_000);
}

export default function ExpiringDomainsPage() {
  const { message } = App.useApp();
  const [domains, setDomains] = useState<ExpiringDomain[]>([]);
  const [days, setDays] = useState(30);
  const [isLoading, setIsLoading] = useState(true);

  const load = useCallback(async () => {
    setIsLoading(true);
    try {
      setDomains(await listExpiringDomains(days));
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't load expiring domains.");
    } finally {
      setIsLoading(false);
    }
  }, [days, message]);

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

  const providers = Array.from(new Set(domains.map(providerOf))).sort();

  const columns: ColumnsType<ExpiringDomain> = [
    {
      title: "Domain",
      dataIndex: "fqdn",
      sorter: (a, b) => textCompare(a.fqdn, b.fqdn),
      sortDirections: SORT_DIRECTIONS,
      render: (fqdn: string, domain) => (
        <Link href={`/domains/${domain.id}`} className="font-mono">
          {fqdn}
        </Link>
      ),
    },
    {
      title: "Registrar",
      render: (_, domain) => domain.registrar_account?.label ?? domain.registrar_label ?? "—",
    },
    {
      title: "Expires",
      dataIndex: "expires_at",
      render: (v: string | null) => {
        if (!v) return "—";
        const remaining = daysUntil(v);
        return (
          <span className="flex items-center gap-2">
            {new Date(v).toLocaleDateString()}
            {remaining !== null && (
              <Tag color={remaining <= 7 ? "red" : remaining <= 30 ? "orange" : "default"}>{remaining}d</Tag>
            )}
          </span>
        );
      },
    },
    { title: "Status", dataIndex: "status", render: (v: string) => titleCase(v.replace(/_/g, " ")) },
  ];

  function tableFor(provider: string | null) {
    const rows = provider ? domains.filter((d) => providerOf(d) === provider) : domains;
    return (
      <Table<ExpiringDomain>
        rowKey="id"
        columns={columns}
        dataSource={rows}
        loading={isLoading}
        pagination={{ showSizeChanger: true, pageSizeOptions: PAGE_SIZE_OPTIONS, showTotal: (count) => `${count} domains` }}
        className="dms_expiring_domains_table"
      />
    );
  }

  return (
    <div className="flex flex-col gap-4 page page-expiring-domains">
      <div className="flex items-center justify-between flex-wrap gap-2">
        <div className="flex items-center gap-2">
          <Typography.Title level={4} style={{ margin: 0 }}>
            Expiring Domains
          </Typography.Title>
          <PageGuide guides={REGISTRARS_GUIDES} defaultKey="expiring-domains" label="Expiring domains guide" />
        </div>
        <Link href="/registrars">
          <Button className="dms_expiring_domains_back_btn">Back to Registrars</Button>
        </Link>
      </div>

      <div className="flex items-center gap-2">
        <Typography.Text>Within</Typography.Text>
        <Select
          value={days}
          onChange={setDays}
          options={DAY_WINDOWS.map((d) => ({ value: d, label: `${d} days` }))}
          style={{ width: 120 }}
          className="dms_expiring_domains_window_select"
        />
      </div>

      <Tabs
        items={[
          { key: "all", label: `All (${domains.length})`, children: tableFor(null) },
          ...providers.map((provider) => ({
            key: provider,
            label: `${provider} (${domains.filter((d) => providerOf(d) === provider).length})`,
            children: tableFor(provider),
          })),
        ]}
        className="dms_expiring_domains_tabs"
      />
    </div>
  );
}
