// @File: src/pages/admin/cms/CmsAdminUsers.tsx
// @Desc: Admin CMS page at /admin/users. Lists local + platform users,
//        supports search/role/provider filters, and exposes four admin
//        actions per row: promote/demote admin, enable/disable, and
//        reset password (local accounts only). All calls go through the
//        protected /api/v1/admin/users endpoints.
import { FormEvent, useCallback, useEffect, useMemo, useState } from "react";
import {
  AlertCircle,
  CheckCircle2,
  KeyRound,
  Loader2,
  RefreshCw,
  Search,
  ShieldCheck,
  ShieldOff,
  UserCheck,
  UserX,
  Users as UsersIcon,
  X,
} from "lucide-react";
import CmsLayout from "./CmsLayout";
import { PageHeader, SectionCard } from "./ui";
import {
  AdminUserRow,
  adminResetLocalUserPassword,
  listAdminUsers,
  updateAdminUserActive,
  updateAdminUserRole,
} from "@/lib/adminApi";

type FlashKind = "success" | "error";
interface Flash {
  kind: FlashKind;
  message: string;
}

function formatDate(value: string | null): string {
  if (!value) return "—";
  try {
    return new Date(value).toLocaleString();
  } catch {
    return value;
  }
}

function Badge({
  tone,
  children,
}: {
  tone: "green" | "gray" | "blue" | "red" | "amber";
  children: React.ReactNode;
}) {
  const tones: Record<string, string> = {
    green: "bg-emerald-50 text-emerald-700 border-emerald-200",
    gray: "bg-slate-50 text-slate-600 border-slate-200",
    blue: "bg-sky-50 text-sky-700 border-sky-200",
    red: "bg-red-50 text-red-700 border-red-200",
    amber: "bg-amber-50 text-amber-700 border-amber-200",
  };
  return (
    <span
      className={`inline-flex items-center px-2 py-0.5 rounded-full border text-[11px] font-semibold ${tones[tone]}`}
    >
      {children}
    </span>
  );
}

function ResetPasswordDialog({
  user,
  onClose,
  onSuccess,
}: {
  user: AdminUserRow;
  onClose: () => void;
  onSuccess: (message: string) => void;
}) {
  const [password, setPassword] = useState("");
  const [confirm, setConfirm] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    setError(null);
    if (password.length < 8) {
      setError("Password must be at least 8 characters.");
      return;
    }
    if (password !== confirm) {
      setError("Passwords do not match.");
      return;
    }
    setSubmitting(true);
    try {
      await adminResetLocalUserPassword(user.id, password);
      onSuccess(`Password updated for ${user.email}.`);
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Could not reset password.");
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="fixed inset-0 z-50 bg-black/50 flex items-center justify-center px-4">
      <div className="bg-white rounded-2xl shadow-xl w-full max-w-md">
        <div className="flex items-center justify-between px-5 py-4 border-b border-slate-200">
          <div className="flex items-center gap-2">
            <KeyRound className="w-5 h-5 text-[#0b6e3e]" />
            <h3 className="font-bold text-slate-900">Reset password</h3>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="p-1.5 rounded hover:bg-slate-100 text-slate-500"
            aria-label="Close"
          >
            <X className="w-4 h-4" />
          </button>
        </div>
        <form onSubmit={handleSubmit} className="p-5 space-y-4">
          <p className="text-sm text-slate-600">
            Set a new password for <strong>{user.email}</strong>. The user will need to sign in
            with this password.
          </p>
          {error && (
            <div
              role="alert"
              className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700 flex items-start gap-2"
            >
              <AlertCircle className="w-4 h-4 mt-0.5 shrink-0" />
              <span>{error}</span>
            </div>
          )}
          <div>
            <label className="block text-sm font-medium text-slate-700 mb-1">New password</label>
            <input
              type="password"
              minLength={8}
              required
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-[#0b6e3e] focus:ring-2 focus:ring-[#0b6e3e]/20 outline-none"
              placeholder="At least 8 characters"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-slate-700 mb-1">Confirm password</label>
            <input
              type="password"
              minLength={8}
              required
              value={confirm}
              onChange={(e) => setConfirm(e.target.value)}
              className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-[#0b6e3e] focus:ring-2 focus:ring-[#0b6e3e]/20 outline-none"
              placeholder="Re-enter password"
            />
          </div>
          <div className="flex justify-end gap-2 pt-2">
            <button
              type="button"
              onClick={onClose}
              className="px-4 py-2 text-sm font-medium rounded-lg border border-slate-300 text-slate-700 hover:bg-slate-50"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={submitting}
              className="inline-flex items-center gap-2 px-4 py-2 text-sm font-semibold rounded-lg bg-[#0b6e3e] text-white hover:bg-[#084e2c] disabled:opacity-60"
            >
              {submitting && <Loader2 className="w-4 h-4 animate-spin" />}
              Update password
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default function CmsAdminUsers() {
  const [rows, setRows] = useState<AdminUserRow[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [pendingId, setPendingId] = useState<string | null>(null);
  const [flash, setFlash] = useState<Flash | null>(null);
  const [resetTarget, setResetTarget] = useState<AdminUserRow | null>(null);

  // Filters
  const [search, setSearch] = useState("");
  const [role, setRole] = useState<"" | "admin" | "user">("");
  const [provider, setProvider] = useState<"" | "local" | "platform">("");
  const [page, setPage] = useState(1);
  const pageSize = 50;

  const showFlash = useCallback((kind: FlashKind, message: string) => {
    setFlash({ kind, message });
    window.setTimeout(() => setFlash((current) => (current?.message === message ? null : current)), 4000);
  }, []);

  const loadUsers = useCallback(async () => {
    setLoading(true);
    try {
      const data = await listAdminUsers({
        search: search.trim() || undefined,
        role: role || undefined,
        provider: provider || undefined,
        page,
        pageSize,
      });
      setRows(data.items);
      setTotal(data.total);
    } catch (err) {
      showFlash("error", err instanceof Error ? err.message : "Failed to load users.");
    } finally {
      setLoading(false);
    }
  }, [page, provider, role, search, showFlash]);

  useEffect(() => {
    loadUsers();
  }, [loadUsers]);

  const totalPages = useMemo(() => Math.max(1, Math.ceil(total / pageSize)), [total]);

  async function handleToggleRole(user: AdminUserRow) {
    const nextRole = user.role === "admin" ? "user" : "admin";
    setPendingId(user.id);
    try {
      const updated = await updateAdminUserRole(user.id, nextRole);
      setRows((prev) => prev.map((r) => (r.id === updated.id ? updated : r)));
      showFlash(
        "success",
        nextRole === "admin"
          ? `${updated.email} is now an admin.`
          : `${updated.email} is no longer an admin.`,
      );
    } catch (err) {
      showFlash("error", err instanceof Error ? err.message : "Could not update role.");
    } finally {
      setPendingId(null);
    }
  }

  async function handleToggleActive(user: AdminUserRow) {
    const nextActive = !user.is_active;
    setPendingId(user.id);
    try {
      const updated = await updateAdminUserActive(user.id, nextActive);
      setRows((prev) => prev.map((r) => (r.id === updated.id ? updated : r)));
      showFlash(
        "success",
        nextActive ? `${updated.email} is now enabled.` : `${updated.email} has been disabled.`,
      );
    } catch (err) {
      showFlash("error", err instanceof Error ? err.message : "Could not update account.");
    } finally {
      setPendingId(null);
    }
  }

  function handleSearchSubmit(e: FormEvent) {
    e.preventDefault();
    setPage(1);
    loadUsers();
  }

  function resetFilters() {
    setSearch("");
    setRole("");
    setProvider("");
    setPage(1);
  }

  return (
    <CmsLayout>
      <PageHeader
        title="Admin Users"
        description="Manage local and platform user accounts — promote admins, disable accounts, and reset local passwords."
      />

      {flash && (
        <div
          role="alert"
          className={`mb-4 rounded-lg border px-4 py-3 text-sm flex items-start gap-2 ${
            flash.kind === "success"
              ? "border-emerald-200 bg-emerald-50 text-emerald-800"
              : "border-red-200 bg-red-50 text-red-700"
          }`}
        >
          {flash.kind === "success" ? (
            <CheckCircle2 className="w-4 h-4 mt-0.5 shrink-0" />
          ) : (
            <AlertCircle className="w-4 h-4 mt-0.5 shrink-0" />
          )}
          <span>{flash.message}</span>
        </div>
      )}

      <SectionCard
        title="Users"
        description={`${total} total account${total === 1 ? "" : "s"}`}
        actions={
          <button
            type="button"
            onClick={loadUsers}
            className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold rounded-lg border border-slate-300 text-slate-700 hover:bg-slate-50"
          >
            <RefreshCw className="w-3.5 h-3.5" /> Refresh
          </button>
        }
      >
        <form
          onSubmit={handleSearchSubmit}
          className="flex flex-wrap items-center gap-2 pb-1"
        >
          <div className="relative flex-1 min-w-[220px]">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
            <input
              type="search"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search by email or name"
              className="w-full rounded-lg border border-slate-300 pl-9 pr-3 py-2 text-sm focus:border-[#0b6e3e] focus:ring-2 focus:ring-[#0b6e3e]/20 outline-none"
            />
          </div>
          <select
            value={role}
            onChange={(e) => {
              setRole(e.target.value as "" | "admin" | "user");
              setPage(1);
            }}
            className="rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-[#0b6e3e] focus:ring-2 focus:ring-[#0b6e3e]/20 outline-none"
          >
            <option value="">All roles</option>
            <option value="admin">Admins</option>
            <option value="user">Users</option>
          </select>
          <select
            value={provider}
            onChange={(e) => {
              setProvider(e.target.value as "" | "local" | "platform");
              setPage(1);
            }}
            className="rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-[#0b6e3e] focus:ring-2 focus:ring-[#0b6e3e]/20 outline-none"
          >
            <option value="">All providers</option>
            <option value="local">Local (email/password)</option>
            <option value="platform">Platform / SSO</option>
          </select>
          <button
            type="submit"
            className="px-4 py-2 text-sm font-semibold rounded-lg bg-[#0b6e3e] text-white hover:bg-[#084e2c]"
          >
            Apply
          </button>
          {(search || role || provider) && (
            <button
              type="button"
              onClick={resetFilters}
              className="px-3 py-2 text-sm text-slate-600 hover:text-slate-900"
            >
              Clear
            </button>
          )}
        </form>

        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs font-semibold text-slate-500 uppercase tracking-wide border-b border-slate-200">
                <th className="py-3 pr-4">User</th>
                <th className="py-3 pr-4">Role</th>
                <th className="py-3 pr-4">Provider</th>
                <th className="py-3 pr-4">Status</th>
                <th className="py-3 pr-4">Last login</th>
                <th className="py-3 pr-4 text-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              {loading && rows.length === 0 ? (
                <tr>
                  <td colSpan={6} className="py-10 text-center text-slate-500">
                    <Loader2 className="w-5 h-5 animate-spin inline mr-2" />
                    Loading users…
                  </td>
                </tr>
              ) : rows.length === 0 ? (
                <tr>
                  <td colSpan={6} className="py-10 text-center text-slate-500">
                    <UsersIcon className="w-6 h-6 inline mr-2 text-slate-400" />
                    No users match your filters.
                  </td>
                </tr>
              ) : (
                rows.map((user) => {
                  const busy = pendingId === user.id;
                  const isAdmin = user.role === "admin";
                  const isLocal = user.auth_provider === "local";
                  return (
                    <tr key={user.id} className="border-b border-slate-100 last:border-0">
                      <td className="py-3 pr-4">
                        <div className="font-semibold text-slate-900">{user.name || "—"}</div>
                        <div className="text-xs text-slate-500">{user.email}</div>
                      </td>
                      <td className="py-3 pr-4">
                        {isAdmin ? (
                          <Badge tone="green">Admin</Badge>
                        ) : (
                          <Badge tone="gray">User</Badge>
                        )}
                      </td>
                      <td className="py-3 pr-4">
                        {isLocal ? (
                          <Badge tone="blue">Local</Badge>
                        ) : (
                          <Badge tone="amber">Platform</Badge>
                        )}
                      </td>
                      <td className="py-3 pr-4">
                        {user.is_active ? (
                          <Badge tone="green">Active</Badge>
                        ) : (
                          <Badge tone="red">Disabled</Badge>
                        )}
                      </td>
                      <td className="py-3 pr-4 text-xs text-slate-600">
                        {formatDate(user.last_login)}
                      </td>
                      <td className="py-3 pr-4">
                        <div className="flex flex-wrap justify-end gap-1.5">
                          <button
                            type="button"
                            disabled={busy}
                            onClick={() => handleToggleRole(user)}
                            className="inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-semibold rounded-lg border border-slate-300 text-slate-700 hover:bg-slate-50 disabled:opacity-50"
                            title={isAdmin ? "Demote to user" : "Promote to admin"}
                          >
                            {isAdmin ? (
                              <>
                                <ShieldOff className="w-3.5 h-3.5" /> Demote
                              </>
                            ) : (
                              <>
                                <ShieldCheck className="w-3.5 h-3.5" /> Promote
                              </>
                            )}
                          </button>
                          <button
                            type="button"
                            disabled={busy}
                            onClick={() => handleToggleActive(user)}
                            className={`inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-semibold rounded-lg border disabled:opacity-50 ${
                              user.is_active
                                ? "border-red-200 text-red-700 hover:bg-red-50"
                                : "border-emerald-200 text-emerald-700 hover:bg-emerald-50"
                            }`}
                            title={user.is_active ? "Disable account" : "Enable account"}
                          >
                            {user.is_active ? (
                              <>
                                <UserX className="w-3.5 h-3.5" /> Disable
                              </>
                            ) : (
                              <>
                                <UserCheck className="w-3.5 h-3.5" /> Enable
                              </>
                            )}
                          </button>
                          <button
                            type="button"
                            disabled={busy || !isLocal}
                            onClick={() => setResetTarget(user)}
                            className="inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-semibold rounded-lg border border-slate-300 text-slate-700 hover:bg-slate-50 disabled:opacity-40 disabled:cursor-not-allowed"
                            title={
                              isLocal
                                ? "Reset local password"
                                : "Only local accounts can have their password reset"
                            }
                          >
                            <KeyRound className="w-3.5 h-3.5" /> Reset password
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>

        {totalPages > 1 && (
          <div className="flex items-center justify-between pt-4">
            <div className="text-xs text-slate-500">
              Page {page} of {totalPages}
            </div>
            <div className="flex gap-2">
              <button
                type="button"
                disabled={page <= 1 || loading}
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                className="px-3 py-1.5 text-xs font-semibold rounded-lg border border-slate-300 text-slate-700 hover:bg-slate-50 disabled:opacity-40"
              >
                Previous
              </button>
              <button
                type="button"
                disabled={page >= totalPages || loading}
                onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                className="px-3 py-1.5 text-xs font-semibold rounded-lg border border-slate-300 text-slate-700 hover:bg-slate-50 disabled:opacity-40"
              >
                Next
              </button>
            </div>
          </div>
        )}
      </SectionCard>

      {resetTarget && (
        <ResetPasswordDialog
          user={resetTarget}
          onClose={() => setResetTarget(null)}
          onSuccess={(msg) => showFlash("success", msg)}
        />
      )}
    </CmsLayout>
  );
}