"use client";

import type { RegistrarAccount } from "@domainops/shared-types";
import { App, Form, Input, Modal, Select } from "antd";
import { useEffect, useState } from "react";
import { createRegistrar, updateRegistrar } from "@/lib/api/acquire";
import type { CreateRegistrarInput } from "@/lib/api/acquire";
import { ApiError } from "@/lib/api/client";
import { providerLabel } from "@/lib/utils/text";

type CredentialKey = "api_user" | "api_key" | "api_secret" | "whitelisted_ips";

interface CredentialField {
  key: CredentialKey;
  label: string;
  required: boolean;
  secret: boolean;
  placeholder?: string;
  help?: string;
}

const CREDENTIAL_KEYS: CredentialKey[] = ["api_user", "api_key", "api_secret", "whitelisted_ips"];

const WHITELIST_FIELD: CredentialField = {
  key: "whitelisted_ips",
  label: "Whitelist",
  required: false,
  secret: false,
  placeholder: "203.0.113.10",
  help: "The IP(s) you've whitelisted at the registrar for this account - for your own reference.",
};

/**
 * The credentials each registrar's API actually asks for - switching the
 * Provider swaps the fields below it to match. Values map onto the same
 * stored columns (api_user, api_key, api_secret, whitelisted_ips) for every
 * provider, so a new registrar is one entry here.
 */
const PROVIDER_FIELDS: Record<string, CredentialField[]> = {
  namecheap: [
    { key: "api_user", label: "API User", required: true, secret: false },
    { key: "api_key", label: "API Key", required: true, secret: true },
    WHITELIST_FIELD,
  ],
  godaddy: [
    { key: "api_key", label: "API Key", required: true, secret: false },
    { key: "api_secret", label: "API Secret", required: true, secret: true },
  ],
  custom: [
    { key: "api_user", label: "Username / Account ID", required: false, secret: false },
    { key: "api_key", label: "Password / API Key", required: false, secret: true },
    WHITELIST_FIELD,
  ],
  namesilo: [{ key: "api_key", label: "API Key", required: true, secret: true }],
  porkbun: [
    { key: "api_key", label: "API Key", required: true, secret: false },
    { key: "api_secret", label: "Secret API Key", required: true, secret: true },
  ],
  dynadot: [
    { key: "api_key", label: "API Production Key", required: true, secret: false },
    { key: "api_secret", label: "Secret Key", required: true, secret: true },
    WHITELIST_FIELD,
  ],
  gname: [
    { key: "api_user", label: "App ID", required: true, secret: false },
    { key: "api_key", label: "App Key", required: true, secret: true },
    WHITELIST_FIELD,
  ],
  enom: [
    { key: "api_user", label: "Account Login ID", required: true, secret: false },
    { key: "api_key", label: "Account Password", required: true, secret: true },
  ],
};

const DEFAULT_FIELDS: CredentialField[] = [
  { key: "api_user", label: "API User", required: false, secret: false },
  { key: "api_key", label: "API Key", required: true, secret: true },
];

export function RegistrarFormModal({
  open,
  account,
  supportedProviders,
  onClose,
  onSaved,
}: {
  open: boolean;
  account: RegistrarAccount | null;
  supportedProviders: string[];
  onClose: () => void;
  onSaved: () => void;
}) {
  const { message } = App.useApp();
  const [form] = Form.useForm<CreateRegistrarInput>();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const isEditing = !!account;
  const selectedProvider = Form.useWatch("provider", form);
  const provider = selectedProvider ?? account?.provider ?? "";
  const fields = PROVIDER_FIELDS[provider] ?? DEFAULT_FIELDS;

  useEffect(() => {
    if (!open) return;
    form.resetFields();
    if (account) {
      form.setFieldsValue({
        provider: account.provider,
        provider_name: account.provider_name ?? undefined,
        label: account.label,
        api_user: account.api_user ?? undefined,
        whitelisted_ips: account.whitelisted_ips ?? undefined,
        notes: account.notes ?? undefined,
      });
    }
  }, [open, account, form]);

  async function handleSubmit(values: CreateRegistrarInput) {
    const allowedKeys = new Set(fields.map((f) => f.key));
    const payload: CreateRegistrarInput = { ...values };
    CREDENTIAL_KEYS.filter((key) => !allowedKeys.has(key)).forEach((key) => delete payload[key]);

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

  return (
    <Modal
      title={isEditing ? `Edit Registrar Account - ${account?.label}` : "Add Registrar Account"}
      open={open}
      onCancel={onClose}
      onOk={() => form.submit()}
      confirmLoading={isSubmitting}
      okText="Save"
      destroyOnHidden
      className="dms_registrar_form_modal"
    >
      <Form<CreateRegistrarInput> form={form} layout="vertical" onFinish={handleSubmit} className="dms_registrar_form">
        <Form.Item name="provider" label="Provider" rules={[{ required: true, message: "Pick a provider" }]} className="dms_registrar_provider_field">
          <Select
            options={supportedProviders.map((p) => ({ value: p, label: providerLabel(p) }))}
            disabled={isEditing}
            placeholder="Pick a registrar"
            onChange={() => form.resetFields(CREDENTIAL_KEYS)}
          />
        </Form.Item>
        {provider === "custom" && (
          <Form.Item
            name="provider_name"
            label="Provider name"
            rules={[{ required: true, message: "Enter the registrar name" }]}
            extra="Record-keeping only - there is no live connection to a custom provider."
            className="dms_registrar_provider_name_field"
          >
            <Input placeholder="e.g. Gname" />
          </Form.Item>
        )}
        <Form.Item name="label" label="Label" rules={[{ required: true, message: "Give it a label" }]} className="dms_registrar_label_field">
          <Input placeholder="NC-SEO-01" autoFocus />
        </Form.Item>
        {provider &&
          fields.map((field) => {
            const isRequired = field.required && !(isEditing && field.secret);
            return (
              <Form.Item
                key={`${provider}-${field.key}`}
                name={field.key}
                label={field.label}
                rules={isRequired ? [{ required: true, message: `Enter the ${field.label.toLowerCase()}` }] : []}
                extra={isEditing && field.secret ? "Leave blank to keep the current value." : field.help}
                className={`dms_registrar_${field.key}_field`}
              >
                {field.secret ? <Input.Password autoComplete="new-password" /> : <Input placeholder={field.placeholder} />}
              </Form.Item>
            );
          })}
        <Form.Item name="notes" label="Remarks" className="dms_registrar_notes_field">
          <Input.TextArea rows={2} />
        </Form.Item>
      </Form>
    </Modal>
  );
}
