"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import MainTitle from "@/components/layout/dashboard/main-title";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { PasswordInput } from "@/components/ui/password-input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import DataService from "@/config/axios";
import { useRequireSuperAdmin } from "@/hooks/use-require-super-admin";
import { getApiErrorMessage } from "@/lib/api-error";
import { toast } from "sonner";
import { Pencil, Trash2 } from "lucide-react";

type RoleOpt = { _id: string; name: string };
type AdminUser = {
  _id: string;
  username: string;
  email: string;
  firstName?: string;
  lastName?: string;
  type: string;
  status: string;
  role?: RoleOpt | null;
  /** Effective permissions from role (or all for super_admin) */
  permissions?: { all?: boolean; names?: string[] };
};

function formatPermissions(p?: AdminUser["permissions"]) {
  if (!p) return "—";
  if (p.all) {
    const n = p.names?.length;
    return n ? `All (${n})` : "All";
  }
  const n = p.names || [];
  if (n.length === 0) return "—";
  const show = n.slice(0, 4).join(", ");
  return n.length > 4 ? `${show}…` : show;
}

const emptyForm = {
  firstName: "",
  lastName: "",
  email: "",
  username: "",
  password: "",
  type: "user",
  roleId: "",
  status: "active",
};

export default function AdminUsersBlock() {
  const ready = useRequireSuperAdmin();
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [assignableRoles, setAssignableRoles] = useState<RoleOpt[]>([]);
  const [actorIsSuperAdmin, setActorIsSuperAdmin] = useState(true);
  const [loading, setLoading] = useState(true);
  const [open, setOpen] = useState(false);
  const [editing, setEditing] = useState<AdminUser | null>(null);
  const [form, setForm] = useState(emptyForm);

  const roleChoices = useMemo(() => {
    if (!editing?.role?._id) return assignableRoles;
    const has = assignableRoles.some((r) => r._id === editing.role!._id);
    if (has) return assignableRoles;
    return [
      ...assignableRoles,
      { _id: editing.role._id, name: editing.role.name },
    ];
  }, [assignableRoles, editing]);

  const load = useCallback(async () => {
    try {
      const [uRes, arRes, meRes] = await Promise.all([
        DataService.get("/admin/users"),
        DataService.get("/user/assignable-roles"),
        DataService.get("/user/me"),
      ]);
      setUsers(uRes.data?.data || []);
      setAssignableRoles(arRes.data?.data || []);
      setActorIsSuperAdmin(meRes.data?.data?.type === "super_admin");
    } catch (e) {
      toast.error(getApiErrorMessage(e, "Failed to load users"));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    if (ready) load();
  }, [ready, load]);

  useEffect(() => {
    if (!actorIsSuperAdmin) {
      setForm((f) => (f.type === "super_admin" ? { ...f, type: "user" } : f));
    }
  }, [actorIsSuperAdmin]);

  const openCreate = () => {
    setEditing(null);
    setForm(emptyForm);
    setOpen(true);
  };

  const openEdit = (u: AdminUser) => {
    setEditing(u);
    setForm({
      firstName: u.firstName || "",
      lastName: u.lastName || "",
      email: u.email,
      username: u.username,
      password: "",
      type: u.type || "user",
      roleId: u.role?._id || "",
      status: u.status || "active",
    });
    setOpen(true);
  };

  const save = async () => {
    try {
      if (editing) {
        const body: Record<string, unknown> = {
          firstName: form.firstName,
          lastName: form.lastName,
          email: form.email,
          type: form.type,
          status: form.status,
          role: form.roleId || null,
        };
        if (form.password) body.password = form.password;
        await DataService.patch(`/admin/users/${editing._id}`, body);
        toast.success("User updated");
      } else {
        await DataService.post("/admin/users", {
          firstName: form.firstName,
          lastName: form.lastName,
          email: form.email,
          username: form.username || undefined,
          password: form.password,
          type: form.type,
          status: form.status,
          role: form.roleId || undefined,
        });
        toast.success("User created");
      }
      setOpen(false);
      load();
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not save user"));
    }
  };

  const remove = async (u: AdminUser) => {
    if (!confirm(`Delete user ${u.username}?`)) return;
    try {
      await DataService.delete(`/admin/users/${u._id}`);
      toast.success("User deleted");
      load();
    } catch (e) {
      toast.error(getApiErrorMessage(e, "Could not delete user"));
    }
  };

  if (!ready || loading) {
    return (
      <div className="rounded-md border bg-white p-8 text-center text-gray-500">Loading…</div>
    );
  }

  return (
    <div>
      <MainTitle title="Users (Super admin)">
        <Button onClick={openCreate}>Add user</Button>
      </MainTitle>

      <p className="mb-4 text-sm text-gray-600">
        <strong>Super admins</strong> see every role and can create super admin accounts. Other
        admins only see roles whose <em>Visible to</em> matches their own role (often a small set,
        e.g. three roles for a &quot;User&quot; manager). Roles with no <em>Visible to</em> are
        only assignable by super admins.
      </p>

      <div className="rounded-md border bg-white">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Username</TableHead>
              <TableHead>Email</TableHead>
              <TableHead>Name</TableHead>
              <TableHead>Type</TableHead>
              <TableHead>Role</TableHead>
              <TableHead>Permissions (via role)</TableHead>
              <TableHead>Status</TableHead>
              <TableHead className="w-[100px]" />
            </TableRow>
          </TableHeader>
          <TableBody>
            {users.length === 0 ? (
              <TableRow>
                <TableCell colSpan={8} className="text-center text-gray-400">
                  No users
                </TableCell>
              </TableRow>
            ) : (
              users.map((u) => (
                <TableRow key={u._id}>
                  <TableCell className="font-medium">{u.username}</TableCell>
                  <TableCell>{u.email}</TableCell>
                  <TableCell>
                    {u.firstName} {u.lastName}
                  </TableCell>
                  <TableCell>{u.type}</TableCell>
                  <TableCell>{u.role?.name || "—"}</TableCell>
                  <TableCell className="max-w-[200px] text-xs text-gray-600">
                    {formatPermissions(u.permissions)}
                  </TableCell>
                  <TableCell>{u.status}</TableCell>
                  <TableCell className="flex gap-2">
                    <Button variant="outline" size="icon" onClick={() => openEdit(u)}>
                      <Pencil className="size-4" />
                    </Button>
                    <Button variant="outline" size="icon" onClick={() => remove(u)}>
                      <Trash2 className="size-4 text-red-600" />
                    </Button>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{editing ? "Edit user" : "Add user"}</DialogTitle>
          </DialogHeader>
          <div className="grid gap-3 py-2">
            <div className="grid gap-2">
              <Label htmlFor="firstName">First name</Label>
              <Input
                id="firstName"
                value={form.firstName}
                onChange={(e) => setForm({ ...form, firstName: e.target.value })}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="lastName">Last name</Label>
              <Input
                id="lastName"
                value={form.lastName}
                onChange={(e) => setForm({ ...form, lastName: e.target.value })}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="email">Email</Label>
              <Input
                id="email"
                type="email"
                value={form.email}
                onChange={(e) => setForm({ ...form, email: e.target.value })}
              />
            </div>
            {!editing && (
              <div className="grid gap-2">
                <Label htmlFor="username">Username (optional)</Label>
                <Input
                  id="username"
                  value={form.username}
                  onChange={(e) => setForm({ ...form, username: e.target.value })}
                />
              </div>
            )}
            <div className="grid gap-2">
              <Label htmlFor="password">
                Password {editing ? "(leave blank to keep)" : ""}
              </Label>
              <PasswordInput
                id="password"
                value={form.password}
                onChange={(e) => setForm({ ...form, password: e.target.value })}
                autoComplete="new-password"
              />
            </div>
            <div className="grid gap-2">
              <Label>Account type</Label>
              <Select value={form.type} onValueChange={(v) => setForm({ ...form, type: v })}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="user">user</SelectItem>
                  {actorIsSuperAdmin && (
                    <SelectItem value="super_admin">super_admin</SelectItem>
                  )}
                </SelectContent>
              </Select>
              {!actorIsSuperAdmin && (
                <p className="text-xs text-gray-500">Only super admins can create super admin accounts.</p>
              )}
            </div>
            <div className="grid gap-2">
              <Label>Role</Label>
              <Select
                value={form.roleId || "__none__"}
                onValueChange={(v) => setForm({ ...form, roleId: v === "__none__" ? "" : v })}
              >
                <SelectTrigger>
                  <SelectValue placeholder="None" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="__none__">None</SelectItem>
                  {roleChoices.map((r) => (
                    <SelectItem key={r._id} value={r._id}>
                      {r.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {!actorIsSuperAdmin && (
                <p className="text-xs text-gray-500">
                  Only roles marked visible for your role appear here.
                </p>
              )}
            </div>
            <div className="grid gap-2">
              <Label>Status</Label>
              <Select value={form.status} onValueChange={(v) => setForm({ ...form, status: v })}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">active</SelectItem>
                  <SelectItem value="inactive">inactive</SelectItem>
                  <SelectItem value="suspended">suspended</SelectItem>
                  <SelectItem value="expired">expired</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setOpen(false)}>
              Cancel
            </Button>
            <Button onClick={save}>{editing ? "Save" : "Create"}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
