"use client";

import type { Domain, DomainPurchaseRecord, PurchaseRecordType } from "@domainops/shared-types";
import { App, Button, Card, DatePicker, Form, Input, InputNumber, Modal, Popconfirm, Select, Table, Tag, Tooltip } from "antd";
import { DeleteOutlined, PlusOutlined } from "@ant-design/icons";
import type { Dayjs } from "dayjs";
import { useCallback, useEffect, useState } from "react";
import { createPurchaseRecord, deletePurchaseRecord, listPurchaseRecords } from "@/lib/api/domains";
import { ApiError } from "@/lib/api/client";

interface RecordFormValues {
  type: PurchaseRecordType;
  occurred_on: Dayjs;
  price?: number;
  expires_before?: Dayjs;
  expires_after?: Dayjs;
  registrar_label?: string;
  note?: string;
}

const TYPE_LABELS: Record<PurchaseRecordType, string> = {
  purchase: "Purchase",
  renewal: "Renewal",
  expiry_change: "Expiry changed",
};

const TYPE_COLORS: Record<PurchaseRecordType, string> = {
  purchase: "blue",
  renewal: "green",
  expiry_change: "gold",
};

const TYPE_OPTIONS = (Object.keys(TYPE_LABELS) as PurchaseRecordType[]).map((value) => ({ value, label: TYPE_LABELS[value] }));

function formatDate(value: string | null): string {
  return value ? new Date(value).toLocaleDateString() : "—";
}

export function PurchaseHistoryCard({ domain }: { domain: Domain }) {
  const { message } = App.useApp();
  const [records, setRecords] = useState<DomainPurchaseRecord[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isOpen, setIsOpen] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [form] = Form.useForm<RecordFormValues>();

  const load = useCallback(async () => {
    setIsLoading(true);
    try {
      setRecords(await listPurchaseRecords(domain.id));
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't load the purchase history.");
    } finally {
      setIsLoading(false);
    }
  }, [domain.id, message]);

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

  async function handleSave(values: RecordFormValues) {
    setIsSaving(true);
    try {
      await createPurchaseRecord(domain.id, {
        type: values.type,
        occurred_on: values.occurred_on.format("YYYY-MM-DD"),
        price: values.price,
        expires_before: values.expires_before?.format("YYYY-MM-DD"),
        expires_after: values.expires_after?.format("YYYY-MM-DD"),
        registrar_label: values.registrar_label || undefined,
        note: values.note || undefined,
      });
      message.success("Record added.");
      setIsOpen(false);
      form.resetFields();
      void load();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't add that record.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleDelete(record: DomainPurchaseRecord) {
    try {
      await deletePurchaseRecord(domain.id, record.id);
      message.success("Record removed.");
      void load();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't remove that record.");
    }
  }

  return (
    <Card
      title="Purchase history"
      className="dms_domain_purchase_history_card"
      extra={
        <Button size="small" icon={<PlusOutlined />} onClick={() => setIsOpen(true)} className="dms_domain_purchase_history_add_btn">
          Add record
        </Button>
      }
    >
      <p className="text-sm mb-3" style={{ color: "var(--dms-muted)" }}>
        When this domain was bought, every renewal and every change to its expiry date. Purchases and renewals are recorded automatically; add older ones by hand.
      </p>
      <Table<DomainPurchaseRecord>
        size="small"
        rowKey="id"
        loading={isLoading}
        pagination={false}
        dataSource={records}
        locale={{ emptyText: "No purchase history yet." }}
        scroll={{ x: "max-content" }}
        columns={[
          { title: "Date", dataIndex: "occurred_on", render: (v: string) => formatDate(v) },
          { title: "Type", dataIndex: "type", render: (v: PurchaseRecordType) => <Tag color={TYPE_COLORS[v]}>{TYPE_LABELS[v]}</Tag> },
          { title: "Price", dataIndex: "price", render: (v: string | null) => (v === null ? "—" : Number(v).toFixed(2)) },
          {
            title: "Expiry",
            render: (_, record) =>
              record.expires_before || record.expires_after ? `${formatDate(record.expires_before)} → ${formatDate(record.expires_after)}` : "—",
          },
          { title: "Registrar", dataIndex: "registrar_label", render: (v: string | null) => v ?? "—" },
          { title: "Note", dataIndex: "note", render: (v: string | null) => v ?? "—" },
          { title: "Source", dataIndex: "source", render: (v: string) => (v === "auto" ? "Automatic" : "Manual") },
          {
            title: "",
            render: (_, record) => (
              <Popconfirm title="Remove this record?" okText="Remove" okButtonProps={{ danger: true }} onConfirm={() => void handleDelete(record)}>
                <Tooltip title="Remove">
                  <Button size="small" danger icon={<DeleteOutlined />} aria-label="Remove record" className="dms_domain_purchase_history_delete_btn" />
                </Tooltip>
              </Popconfirm>
            ),
          },
        ]}
        className="dms_domain_purchase_history_table"
      />

      <Modal
        title="Add purchase record"
        open={isOpen}
        onCancel={() => setIsOpen(false)}
        mask={{ closable: false }}
        destroyOnHidden
        footer={[
          <Button key="close" onClick={() => setIsOpen(false)}>
            Close
          </Button>,
          <Button key="save" type="primary" loading={isSaving} onClick={() => form.submit()}>
            Save
          </Button>,
        ]}
        className="dms_domain_purchase_history_modal"
      >
        <Form<RecordFormValues> form={form} layout="vertical" requiredMark onFinish={handleSave} initialValues={{ type: "renewal", registrar_label: domain.registrar_label ?? undefined }}>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-4">
            <Form.Item name="type" label="Type" rules={[{ required: true }]}>
              <Select options={TYPE_OPTIONS} />
            </Form.Item>
            <Form.Item name="occurred_on" label="Date" rules={[{ required: true, message: "Pick the date it happened" }]}>
              <DatePicker className="w-full" />
            </Form.Item>
            <Form.Item name="expires_before" label="Expiry before">
              <DatePicker className="w-full" />
            </Form.Item>
            <Form.Item name="expires_after" label="Expiry after">
              <DatePicker className="w-full" />
            </Form.Item>
            <Form.Item name="price" label="Price">
              <InputNumber min={0} className="w-full" />
            </Form.Item>
            <Form.Item name="registrar_label" label="Registrar">
              <Input />
            </Form.Item>
          </div>
          <Form.Item name="note" label="Note">
            <Input.TextArea rows={2} maxLength={500} />
          </Form.Item>
        </Form>
      </Modal>
    </Card>
  );
}
