import { FormEvent, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import { api } from "../../api/client";
import { Modal } from "../../components/Modal";
import { Page } from "../../components/Page";
import { Table } from "../../components/Table";

const columns = [
  { key: "username", label: "Username" },
  { key: "name", label: "Display name" },
  { key: "email", label: "Email" },
  { key: "role", label: "Role" },
  { key: "status", label: "Status" },
  { key: "actions", label: "Actions" }
];

export function UsersPage() {
  const queryClient = useQueryClient();
  const query = useQuery({
    queryKey: ["users"],
    queryFn: api.users
  });
  const [form, setForm] = useState({
    username: "",
    display_name: "",
    email: "",
    password: "",
    role: "user"
  });
  const [editingUserId, setEditingUserId] = useState<string | null>(null);
  const [editForm, setEditForm] = useState({
    display_name: "",
    email: "",
    role: "user",
    password: "",
    is_active: true
  });

  const createMutation = useMutation({
    mutationFn: api.createUser,
    onSuccess: () => {
      setForm({ username: "", display_name: "", email: "", password: "", role: "user" });
      void queryClient.invalidateQueries({ queryKey: ["users"] });
    }
  });

  const updateMutation = useMutation({
    mutationFn: ({ userId, payload }: { userId: string; payload: typeof editForm }) => api.updateUser(userId, payload),
    onSuccess: () => {
      setEditingUserId(null);
      setEditForm({ display_name: "", email: "", role: "user", password: "", is_active: true });
      void queryClient.invalidateQueries({ queryKey: ["users"] });
    }
  });

  const deleteMutation = useMutation({
    mutationFn: api.deleteUser,
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["users"] });
    }
  });

  const rows = query.data?.map((user) => ({
    id: user.id,
    username: user.username,
    name: user.display_name,
    email: user.email || "-",
    role: user.role,
    status: user.is_active ? "active" : "disabled"
  })) ?? [];

  function onSubmit(event: FormEvent) {
    event.preventDefault();
    createMutation.mutate(form);
  }

  function startEdit(userId: string) {
    const user = query.data?.find((item) => item.id === userId);
    if (!user) {
      return;
    }
    setEditingUserId(userId);
    setEditForm({
      display_name: user.display_name,
      email: user.email || "",
      role: user.role,
      password: "",
      is_active: user.is_active
    });
  }

  function onEditSubmit(event: FormEvent) {
    event.preventDefault();
    if (!editingUserId) {
      return;
    }
    updateMutation.mutate({
      userId: editingUserId,
      payload: editForm
    });
  }

  return (
    <Page
      title="Users"
      subtitle="Create, disable, and manage platform identities."
      actions={<span className="pill">Admin managed</span>}
    >
      <form className="inline-form" onSubmit={onSubmit}>
        <input placeholder="username" value={form.username} onChange={(event) => setForm((value) => ({ ...value, username: event.target.value }))} />
        <input placeholder="display name" value={form.display_name} onChange={(event) => setForm((value) => ({ ...value, display_name: event.target.value }))} />
        <input placeholder="email" value={form.email} onChange={(event) => setForm((value) => ({ ...value, email: event.target.value }))} />
        <input placeholder="password" type="password" value={form.password} onChange={(event) => setForm((value) => ({ ...value, password: event.target.value }))} />
        <select value={form.role} onChange={(event) => setForm((value) => ({ ...value, role: event.target.value }))}>
          <option value="user">user</option>
          <option value="admin">admin</option>
        </select>
        <button className="button" type="submit" disabled={createMutation.isPending}>Create user</button>
      </form>
      {query.isError ? <p className="notice">Unable to load users from the API.</p> : null}
      {createMutation.isError ? <p className="notice">Unable to create user.</p> : null}
      {updateMutation.isError ? <p className="notice">Unable to update user.</p> : null}
      {deleteMutation.isError ? <p className="notice">Unable to delete user.</p> : null}
      <Table
        columns={columns}
        rows={rows}
        renderCell={(row, column) => {
          if (column.key === "actions") {
            return (
              <div className="action-row">
                <button className="ghost-button" type="button" onClick={() => startEdit(row.id)}>Edit</button>
                <button className="ghost-button" type="button" onClick={() => deleteMutation.mutate(row.id)}>Delete</button>
              </div>
            );
          }
          return <span>{row[column.key as keyof (typeof rows)[number]]}</span>;
        }}
      />
      {editingUserId ? (
        <Modal title="Edit user" subtitle="Update role, contact details, and account state." onClose={() => setEditingUserId(null)}>
          <form className="stacked-form" onSubmit={onEditSubmit}>
            <input placeholder="display name" value={editForm.display_name} onChange={(event) => setEditForm((value) => ({ ...value, display_name: event.target.value }))} />
            <input placeholder="email" value={editForm.email} onChange={(event) => setEditForm((value) => ({ ...value, email: event.target.value }))} />
            <select value={editForm.role} onChange={(event) => setEditForm((value) => ({ ...value, role: event.target.value }))}>
              <option value="user">user</option>
              <option value="admin">admin</option>
            </select>
            <input placeholder="new password (optional)" type="password" value={editForm.password} onChange={(event) => setEditForm((value) => ({ ...value, password: event.target.value }))} />
            <label className="checkbox">
              <input type="checkbox" checked={editForm.is_active} onChange={(event) => setEditForm((value) => ({ ...value, is_active: event.target.checked }))} />
              Active
            </label>
            <div className="action-row">
              <button className="button" type="submit" disabled={updateMutation.isPending}>Save user</button>
              <button className="ghost-button" type="button" onClick={() => setEditingUserId(null)}>Cancel</button>
            </div>
          </form>
        </Modal>
      ) : null}
    </Page>
  );
}
