"use client";

import { FormEvent, useState } from "react";
import { Pencil, Plus, Power, Send } from "lucide-react";
import { useRouter } from "next/navigation";

import { Button } from "@/components/ui/button";
import { Dialog } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Select } from "@/components/ui/select";
import type { ApiResult } from "@/modules/core/server/api";
import type { Organization, RoleDefinition } from "@/modules/core/types";
import { OrganizationInviteDialog } from "@/modules/settings/components/OrganizationInviteDialog";

export function OrganizationManagementClient(): React.ReactElement {
  const router = useRouter();
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [message, setMessage] = useState("");
  const [isPending, setIsPending] = useState(false);

  function openCreateDialog(): void {
    setMessage("");
    setIsCreateOpen(true);
  }

  function closeCreateDialog(): void {
    if (isPending) {
      return;
    }

    setIsCreateOpen(false);
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>): Promise<void> {
    event.preventDefault();
    setMessage("");
    setIsPending(true);
    const formData = new FormData(event.currentTarget);
    const response = await fetch("/api/organizations", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({
        name: String(formData.get("name") ?? ""),
        slug: String(formData.get("slug") ?? ""),
      }),
    });
    const result = (await response.json()) as ApiResult<{ organization: Organization }>;
    setIsPending(false);

    if (!result.success) {
      setMessage(result.reason);
      return;
    }

    setMessage(result.reason);
    setIsCreateOpen(false);
    event.currentTarget.reset();
    router.refresh();
  }

  return (
    <>
      <Button onClick={openCreateDialog} type="button">
        <Plus className="size-4" aria-hidden="true" />
        新增机构
      </Button>
      <Dialog
        description="创建后会自动初始化机构内置角色。"
        onClose={closeCreateDialog}
        open={isCreateOpen}
        title="新增机构"
      >
        <form className="grid gap-4" onSubmit={handleSubmit}>
          <Input label="机构名称" name="name" placeholder="机构名称" required />
          <Input
            label="机构标识"
            name="slug"
            pattern="[a-z0-9][a-z0-9-]{1,47}"
            placeholder="sunrise-care"
            required
          />
          {message ? (
            <p className="rounded-md bg-secondary px-3 py-2 text-sm text-secondary-foreground" role="status">
              {message}
            </p>
          ) : null}
          <div className="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
            <Button disabled={isPending} onClick={closeCreateDialog} type="button" variant="outline">
              取消
            </Button>
            <Button disabled={isPending} type="submit">
              <Plus className="size-4" aria-hidden="true" />
              新增机构
            </Button>
          </div>
        </form>
      </Dialog>
    </>
  );
}

type OrganizationRowActionsProps = {
  canInvite: boolean;
  organization: Organization;
  roles: RoleDefinition[];
};

export function OrganizationRowActions({
  canInvite,
  organization,
  roles,
}: OrganizationRowActionsProps): React.ReactElement {
  const router = useRouter();
  const [isEditOpen, setIsEditOpen] = useState(false);
  const [isInviteOpen, setIsInviteOpen] = useState(false);
  const [message, setMessage] = useState("");
  const [isPending, setIsPending] = useState(false);

  async function updateOrganization(payload: Record<string, string>): Promise<void> {
    setMessage("");
    setIsPending(true);
    const response = await fetch(`/api/organizations/${organization.id}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(payload),
    });
    const result = (await response.json()) as ApiResult<{ organization: Organization }>;
    setIsPending(false);

    if (!result.success) {
      setMessage(result.reason);
      return;
    }

    setMessage(result.reason);
    setIsEditOpen(false);
    router.refresh();
  }

  async function disableOrganization(): Promise<void> {
    setMessage("");
    setIsPending(true);
    const response = await fetch(`/api/organizations/${organization.id}`, {
      method: "DELETE",
    });
    const result = (await response.json()) as ApiResult<{ organization: Organization }>;
    setIsPending(false);

    if (!result.success) {
      setMessage(result.reason);
      return;
    }

    router.refresh();
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>): Promise<void> {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    await updateOrganization({
      name: String(formData.get("name") ?? ""),
      slug: String(formData.get("slug") ?? ""),
      status: String(formData.get("status") ?? ""),
    });
  }

  return (
    <div className="flex flex-wrap items-center justify-end gap-2">
      <Button onClick={() => setIsEditOpen(true)} size="sm" type="button" variant="outline">
        <Pencil className="size-4" aria-hidden="true" />
        编辑
      </Button>
      {canInvite ? (
        <Button onClick={() => setIsInviteOpen(true)} size="sm" type="button" variant="outline">
          <Send className="size-4" aria-hidden="true" />
          邀请
        </Button>
      ) : null}
      {organization.status === "disabled" ? (
        <Button
          disabled={isPending}
          onClick={() => void updateOrganization({ status: "active" })}
          size="sm"
          type="button"
          variant="outline"
        >
          <Power className="size-4" aria-hidden="true" />
          启用
        </Button>
      ) : (
        <Button disabled={isPending} onClick={() => void disableOrganization()} size="sm" type="button" variant="destructive">
          <Power className="size-4" aria-hidden="true" />
          停用
        </Button>
      )}
      <Dialog
        description="编辑机构名称、唯一标识和启停状态。"
        onClose={() => setIsEditOpen(false)}
        open={isEditOpen}
        title="编辑机构"
      >
        <form className="grid gap-4" onSubmit={handleSubmit}>
          <Input defaultValue={organization.name} label="机构名称" name="name" required />
          <Input
            defaultValue={organization.slug}
            label="机构标识"
            name="slug"
            pattern="[a-z0-9][a-z0-9-]{1,47}"
            required
          />
          <Select
            defaultValue={organization.status}
            label="状态"
            name="status"
            options={[
              { value: "active", label: "启用" },
              { value: "disabled", label: "停用" },
            ]}
          />
          {message ? (
            <p className="rounded-md bg-secondary px-3 py-2 text-sm text-secondary-foreground" role="status">
              {message}
            </p>
          ) : null}
          <div className="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
            <Button onClick={() => setIsEditOpen(false)} type="button" variant="outline">
              取消
            </Button>
            <Button disabled={isPending} type="submit">
              保存
            </Button>
          </div>
        </form>
      </Dialog>
      <OrganizationInviteDialog
        onClose={() => setIsInviteOpen(false)}
        open={isInviteOpen}
        organization={organization}
        roles={roles}
      />
    </div>
  );
}
