"use client";

import type { WpSite, WpSiteUser, WpUserRole } from "@domainops/shared-types";
import { App, Button, Drawer, Form, Input, Select, Space, Table, Tag } from "antd";
import { PlusOutlined, SyncOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import { useState } from "react";
import { addWpUser, syncWpUsers } from "@/lib/api/wordpress";
import type { NewWpUserInput } from "@/lib/api/wordpress";
import { ApiError } from "@/lib/api/client";
import { titleCase } from "@/lib/utils/text";
import { PasswordCell } from "./PasswordCell";

const ROLE_OPTIONS: { value: WpUserRole; label: string }[] = [
  { value: "administrator", label: "Administrator" },
  { value: "editor", label: "Editor" },
  { value: "author", label: "Author" },
  { value: "contributor", label: "Contributor" },
  { value: "subscriber", label: "Subscriber" },
];

/**
 * The logins of one WordPress site: the first administrator made at setup
 * plus any added later with their own role, each with its password to show,
 * change or reset. "Add a user" slides a form in from the right; new users
 * are created on the live site (WP-CLI) before they are saved here, and
 * "Refresh from WordPress" pulls in users that were created inside WordPress
 * itself. Used in the WordPress page's drawer and beside the install form on a
 * domain's Deploy tab.
 */
export function WpUsersPanel({
  site,
  fqdn,
  canReveal,
  canManage,
  onChanged,
}: {
  site: WpSite;
  fqdn: string;
  canReveal: boolean;
  canManage: boolean;
  onChanged: () => void;
}) {
  const { message } = App.useApp();
  const [form] = Form.useForm<NewWpUserInput>();
  const [isAddOpen, setIsAddOpen] = useState(false);
  const [isAdding, setIsAdding] = useState(false);
  const [isSyncing, setIsSyncing] = useState(false);

  async function handleAdd(values: NewWpUserInput) {
    setIsAdding(true);
    try {
      await addWpUser(site.id, { ...values, password: values.password || undefined });
      message.success(`${values.username} created on ${fqdn}.`);
      form.resetFields();
      setIsAddOpen(false);
      onChanged();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't create that user.");
    } finally {
      setIsAdding(false);
    }
  }

  async function handleSync() {
    setIsSyncing(true);
    try {
      const result = await syncWpUsers(site.id);
      message.success(`Refreshed from WordPress: ${result.added} added, ${result.updated} updated.`);
      onChanged();
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't read the users from WordPress.");
    } finally {
      setIsSyncing(false);
    }
  }

  const columns: ColumnsType<WpSiteUser> = [
    {
      title: "User",
      className: "dms_wp_users_col_user",
      render: (_, user) => (
        <div className="dms_wp_users_user_cell">
          <span className="font-semibold dms_wp_users_user_name">{user.username}</span>{" "}
          {user.is_primary && <Tag color="blue" className="dms_wp_users_main_tag">Main</Tag>}
          <div className="text-xs opacity-70 dms_wp_users_user_email">{user.email ?? "-"}</div>
        </div>
      ),
    },
    {
      title: "Role",
      dataIndex: "role",
      className: "dms_wp_users_col_role",
      render: (role: string) => <Tag className="dms_wp_users_role_tag">{titleCase(role)}</Tag>,
    },
    {
      title: "Password",
      className: "dms_wp_users_col_password",
      render: (_, user) => <PasswordCell user={user} canReveal={canReveal} canManage={canManage} onChanged={onChanged} />,
    },
  ];

  return (
    <div className="dms_wp_users_panel">
      {canManage && (
        <div className="flex justify-end gap-2 mb-2 dms_wp_users_toolbar">
          <Button size="small" icon={<SyncOutlined />} loading={isSyncing} onClick={() => void handleSync()} className="dms_wp_users_sync_btn">
            Refresh from WordPress
          </Button>
          <Button size="small" type="primary" icon={<PlusOutlined />} onClick={() => setIsAddOpen(true)} className="dms_wp_users_add_btn">
            Add a user
          </Button>
        </div>
      )}

      <Table<WpSiteUser>
        rowKey="id"
        size="small"
        columns={columns}
        dataSource={site.users ?? []}
        pagination={false}
        className="dms_wp_users_table"
      />

      <Drawer
        title={`Add a user - ${fqdn}`}
        placement="right"
        open={isAddOpen}
        onClose={() => setIsAddOpen(false)}
        size={420}
        mask={{ closable: false }}
        destroyOnHidden
        className="dms_wp_add_user_drawer"
        footer={
          <Space className="flex justify-end dms_wp_add_user_footer">
            <Button onClick={() => setIsAddOpen(false)} className="dms_wp_add_user_cancel_btn">
              Cancel
            </Button>
            <Button type="primary" icon={<PlusOutlined />} loading={isAdding} onClick={() => form.submit()} className="dms_wp_add_user_submit_btn">
              Create user
            </Button>
          </Space>
        }
      >
        <Form<NewWpUserInput> form={form} layout="vertical" onFinish={handleAdd} initialValues={{ role: "editor" }} className="dms_wp_add_user_form">
          <Form.Item name="username" label="Username" rules={[{ required: true, message: "Enter a username" }]} className="dms_wp_add_user_username_field">
            <Input autoComplete="off" autoFocus className="dms_wp_add_user_username_input" />
          </Form.Item>
          <Form.Item name="email" label="Email" rules={[{ required: true, type: "email", message: "Enter a valid email" }]} className="dms_wp_add_user_email_field">
            <Input autoComplete="off" className="dms_wp_add_user_email_input" />
          </Form.Item>
          <Form.Item name="role" label="Role" rules={[{ required: true }]} className="dms_wp_add_user_role_field">
            <Select options={ROLE_OPTIONS} className="dms_wp_add_user_role_select" />
          </Form.Item>
          <Form.Item
            name="password"
            label="Password"
            extra="Leave empty to generate a strong one."
            rules={[{ min: 8, message: "At least 8 characters" }]}
            className="dms_wp_add_user_password_field"
          >
            <Input.Password autoComplete="new-password" className="dms_wp_add_user_password_input" />
          </Form.Item>
        </Form>
      </Drawer>
    </div>
  );
}
