"use client";

import type { Brand, CloudflareAccount } from "@domainops/shared-types";
import { App, Button, Divider, Form, Input, Modal, Select, Typography } from "antd";
import { useEffect, useState } from "react";
import { createCloudflareAccount, updateCloudflareAccount } from "@/lib/api/cloudflare";
import type { CreateCloudflareAccountInput } from "@/lib/api/cloudflare";
import { listBrands } from "@/lib/api/domains";
import { ApiError } from "@/lib/api/client";

const GLOBAL_KEY_PATTERN = /^[0-9a-f]{37}$/i;

export function CloudflareFormModal({
  open,
  account,
  onClose,
  onSaved,
}: {
  open: boolean;
  account: CloudflareAccount | null;
  onClose: () => void;
  onSaved: () => void;
}) {
  const { message } = App.useApp();
  const [form] = Form.useForm<CreateCloudflareAccountInput>();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [brands, setBrands] = useState<Brand[]>([]);
  const isEditing = !!account;

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

  useEffect(() => {
    if (!open) return;
    form.resetFields();
    if (account) {
      form.setFieldsValue({
        label: account.label,
        account_id: account.account_id,
        cf_email: account.cf_email ?? undefined,
        brand_ids: account.brands?.map((b) => b.id) ?? [],
      });
    }
  }, [open, account, form]);

  async function handleSubmit(rawValues: CreateCloudflareAccountInput) {
    const values = Object.fromEntries(
      Object.entries(rawValues).filter(([key, value]) => key === "brand_ids" || (value !== undefined && value !== "")),
    ) as unknown as CreateCloudflareAccountInput;

    setIsSubmitting(true);
    try {
      if (account) {
        await updateCloudflareAccount(account.id, values);
        message.success(`${values.label} updated.`);
      } else {
        await createCloudflareAccount(values);
        message.success(`${values.label} added.`);
      }
      onSaved();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't save that Cloudflare account.");
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <Modal
      title={isEditing ? `Edit Cloudflare Account - ${account?.label}` : "Add Cloudflare Account"}
      open={open}
      onCancel={onClose}
      mask={{ closable: false }}
      destroyOnHidden
      width={620}
      className="dms_cloudflare_form_modal"
      footer={[
        <Button key="close" onClick={onClose} className="dms_cloudflare_form_close_button">
          Close
        </Button>,
        <Button
          key="save"
          type="primary"
          loading={isSubmitting}
          onClick={() => form.submit()}
          className="dms_cloudflare_form_save_button"
        >
          Save
        </Button>,
      ]}
    >
      <Form<CreateCloudflareAccountInput>
        form={form}
        layout="vertical"
        requiredMark
        onFinish={handleSubmit}
        className="dms_cloudflare_form_form"
      >
        <Divider titlePlacement="start" className="dms_cloudflare_form_identity_divider">
          Account
        </Divider>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-4">
          <Form.Item
            name="label"
            label="Label"
            rules={[{ required: true, message: "Give it a label" }]}
            className="dms_cloudflare_form_label_field"
          >
            <Input placeholder="Acme-Brand-CF" autoFocus />
          </Form.Item>
          <Form.Item
            name="cf_email"
            label="CF Email / Username"
            rules={[{ type: "email", message: "Enter a valid email" }]}
            extra="Required when the credential below is a Global API Key."
            className="dms_cloudflare_form_cf_email_field"
          >
            <Input placeholder="ops@example.com" />
          </Form.Item>
        </div>
        <Form.Item
          name="account_id"
          label="Cloudflare Account ID"
          rules={[{ required: true, message: "The account this zone gets created under" }]}
          extra="The 32-character Account ID in the right sidebar of the Cloudflare dashboard's Overview page - not a Zone ID."
          className="dms_cloudflare_form_account_id_field"
        >
          <Input placeholder="32-character Account ID" />
        </Form.Item>

        <Divider titlePlacement="start" className="dms_cloudflare_form_access_divider">
          API access
        </Divider>
        <Form.Item
          name="api_credential"
          label="API Token / Key"
          dependencies={["cf_email"]}
          rules={[
            { required: !isEditing, message: "Paste an API Token or a Global API Key" },
            ({ getFieldValue }) => ({
              validator(_, value?: string) {
                const isGlobalKey = !!value && GLOBAL_KEY_PATTERN.test(value.trim());
                if (isGlobalKey && !getFieldValue("cf_email")) {
                  return Promise.reject(new Error("Enter the CF Email above - a Global API Key needs it"));
                }
                return Promise.resolve();
              },
            }),
          ]}
          extra={
            isEditing
              ? "Leave blank to keep the current credential."
              : "Paste either one - it is detected automatically and used for every sync. An API Token needs an Account-level permission (e.g. Zone: Read on all zones from an account)."
          }
          className="dms_cloudflare_form_api_credential_field"
        >
          <Input.Password
            placeholder={isEditing ? "Unchanged" : "API Token or Global API Key"}
            autoComplete="new-password"
          />
        </Form.Item>

        <Divider titlePlacement="start" className="dms_cloudflare_form_record_divider">
          For your records
        </Divider>
        <Typography.Paragraph type="secondary" className="dms_cloudflare_form_record_note">
          Optional. Stored for reference only - never used by the app.
        </Typography.Paragraph>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-4">
          <Form.Item name="cf_password" label="Cloudflare Password" className="dms_cloudflare_form_cf_password_field">
            <Input.Password placeholder={isEditing ? "Unchanged" : "Optional"} autoComplete="new-password" />
          </Form.Item>
          <Form.Item
            name="recovery_email_password"
            label="Recovery Email Password"
            className="dms_cloudflare_form_recovery_email_password_field"
          >
            <Input.Password placeholder={isEditing ? "Unchanged" : "Optional"} autoComplete="new-password" />
          </Form.Item>
        </div>

        <Divider titlePlacement="start" className="dms_cloudflare_form_projects_divider">
          Projects
        </Divider>
        <Form.Item name="brand_ids" label="Linked Projects" className="dms_cloudflare_form_brand_field">
          <Select
            mode="multiple"
            allowClear
            placeholder="No project link"
            options={brands.map((b) => ({ value: b.id, label: b.name }))}
          />
        </Form.Item>
      </Form>
    </Modal>
  );
}
