"use client";

import { useActionState, useEffect, useState } from "react";
import { useFormStatus } from "react-dom";
import { useRouter } from "next/navigation";
import { Pencil, Plus, UserPlus } from "lucide-react";
import { saveUserAction } from "@/app/actions/admin";
import type { ActionResult } from "@/app/actions/shared";
import { Badge, buttonClass, Callout, Card, CardHeader, Field, inputClass, selectClass, TableShell, Td, Th } from "@/components/ui";
import { useToast } from "@/components/toast";
import { formatDateTime, RoleBadge } from "@/components/status";
import { ROLES, ROLE_LABELS, type Role } from "@/types";

const initial: ActionResult = { ok: false, message: null };

interface UserView {
  id: string;
  email: string;
  full_name: string;
  role: Role;
  active: boolean;
  updated_at: string;
  program_id: string | null;
  program_code: string | null;
}

interface ProgramOption {
  id: string;
  code: string;
  name: string;
}

function Submit({ editing }: { editing: boolean }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className={buttonClass("primary", "sm")} disabled={pending}>
      <UserPlus className="h-3.5 w-3.5" aria-hidden />
      {pending ? "Saving…" : editing ? "Save account" : "Create account"}
    </button>
  );
}

export function UsersManager({ users, programs }: { users: UserView[]; programs: ProgramOption[] }) {
  const router = useRouter();
  const { toast } = useToast();
  const [state, action] = useActionState<ActionResult, FormData>(saveUserAction, initial);
  const [editing, setEditing] = useState<UserView | null>(null);
  const [showForm, setShowForm] = useState(false);

  useEffect(() => {
    if (!state.message) return;
    toast({ tone: state.ok ? "success" : "error", title: state.message });
    if (state.ok) {
      setShowForm(false);
      setEditing(null);
      router.refresh();
    }
  }, [state, toast, router]);

  return (
    <div className="space-y-5">
      <Card>
        <CardHeader
          title="Accounts"
          description={`${users.length} account(s). ${users.filter((u) => u.active).length} active.`}
          actions={
            <button
              type="button"
              onClick={() => {
                setEditing(null);
                setShowForm(true);
              }}
              className={buttonClass("primary", "sm")}
            >
              <Plus className="h-3.5 w-3.5" aria-hidden />
              Add account
            </button>
          }
        />
        <TableShell>
          <thead>
            <tr>
              <Th>Name</Th>
              <Th>Email</Th>
              <Th>Role</Th>
              <Th>Program</Th>
              <Th>Status</Th>
              <Th>Last updated</Th>
              <Th>Actions</Th>
            </tr>
          </thead>
          <tbody>
            {users.map((user) => (
              <tr key={user.id} className={user.active ? "hover:bg-ink-50" : "opacity-60 hover:bg-ink-50"}>
                <Td className="font-medium text-ink-900">{user.full_name}</Td>
                <Td className="text-[13px] text-ink-600">{user.email}</Td>
                <Td>
                  <RoleBadge role={user.role} />
                </Td>
                <Td>
                  {user.program_code ? (
                    <Badge tone="info">{user.program_code}</Badge>
                  ) : (
                    <Badge tone="brand" title="Sees every academic program">
                      All programs
                    </Badge>
                  )}
                </Td>
                <Td>{user.active ? <Badge tone="success">Active</Badge> : <Badge tone="neutral">Deactivated</Badge>}</Td>
                <Td className="whitespace-nowrap text-[12px] text-ink-500">{formatDateTime(user.updated_at)}</Td>
                <Td>
                  <button
                    type="button"
                    onClick={() => {
                      setEditing(user);
                      setShowForm(true);
                    }}
                    className={buttonClass("ghost", "sm")}
                  >
                    <Pencil className="h-3.5 w-3.5" aria-hidden />
                    Edit
                  </button>
                </Td>
              </tr>
            ))}
          </tbody>
        </TableShell>
      </Card>

      {showForm ? (
        <Card>
          <CardHeader title={editing ? `Edit account — ${editing.full_name}` : "New account"} />
          <form action={action} className="space-y-4 p-5">
            {editing ? <input type="hidden" name="user_id" value={editing.id} /> : null}

            <div className="grid gap-4 sm:grid-cols-2">
              <Field label="Full name" htmlFor="full_name" required error={state.fieldErrors?.full_name}>
                <input id="full_name" name="full_name" defaultValue={editing?.full_name ?? ""} className={inputClass} required />
              </Field>
              <Field label="Email address" htmlFor="email" required error={state.fieldErrors?.email}>
                <input
                  id="email"
                  name="email"
                  type="email"
                  defaultValue={editing?.email ?? ""}
                  className={inputClass}
                  required
                />
              </Field>
              <Field label="Role" htmlFor="role" required error={state.fieldErrors?.role}>
                <select id="role" name="role" defaultValue={editing?.role ?? "VIEWER"} className={selectClass}>
                  {ROLES.map((role) => (
                    <option key={role} value={role}>
                      {ROLE_LABELS[role]}
                    </option>
                  ))}
                </select>
              </Field>
              <Field
                label="Academic program"
                htmlFor="program_id"
                error={state.fieldErrors?.program_id}
                hint="An account with no program sees every program. Reserve that for Super Administrators."
              >
                <select
                  id="program_id"
                  name="program_id"
                  defaultValue={editing?.program_id ?? ""}
                  className={selectClass}
                >
                  <option value="">All programs (global access)</option>
                  {programs.map((program) => (
                    <option key={program.id} value={program.id}>
                      {program.code} — {program.name}
                    </option>
                  ))}
                </select>
              </Field>
              <Field
                label={editing ? "New password (leave blank to keep)" : "Password"}
                htmlFor="password"
                required={!editing}
                error={state.fieldErrors?.password}
                hint="At least 10 characters, with upper case, lower case and a digit."
              >
                <input
                  id="password"
                  name="password"
                  type="password"
                  autoComplete="new-password"
                  className={inputClass}
                  required={!editing}
                />
              </Field>
            </div>

            <label className="flex items-center gap-2 text-[13px] text-ink-700">
              <input
                type="checkbox"
                name="active"
                defaultChecked={editing ? editing.active : true}
                className="h-4 w-4 rounded border-ink-300 text-brand-600 focus:ring-brand-500"
              />
              Account is active
            </label>

            {editing ? (
              <Callout tone="info">
                Changing the password or deactivating the account immediately signs the user out of every device.
              </Callout>
            ) : null}

            <div className="flex gap-2 border-t border-ink-200 pt-4">
              <Submit editing={!!editing} />
              <button
                type="button"
                onClick={() => {
                  setShowForm(false);
                  setEditing(null);
                }}
                className={buttonClass("ghost", "sm")}
              >
                Cancel
              </button>
            </div>
          </form>
        </Card>
      ) : null}
    </div>
  );
}
