import { useMemo, useState } from "react";
import { ApiError } from "../../api/client";
import type { UserAdmin } from "../../api/types";
import { useAuth } from "../../auth/AuthContext";
import { PageHeader } from "../../components/layout/PageHeader";
import {
  EditIcon,
  PlusIcon,
  RefreshIcon,
  SearchIcon,
  TrashIcon,
} from "../../components/layout/icons";
import { Badge } from "../../components/ui/Badge";
import { Button } from "../../components/ui/Button";
import { Input } from "../../components/ui/Input";
import { Panel } from "../../components/ui/Panel";
import { EmptyState, ErrorState } from "../../components/ui/States";
import { StatusDot } from "../../components/ui/StatusDot";
import {
  roleLabel,
  roleTone,
  userStatusLabel,
  userStatusTone,
} from "../../components/ui/status";
import { Table, type Column } from "../../components/ui/Table";
import { TableSkeleton } from "../../components/ui/TableSkeleton";
import { absoluteTime, relativeTime } from "../../lib/time";
import { CreateUserModal } from "./CreateUserModal";
import { DeleteUserDialog } from "./DeleteUserDialog";
import { EditUserModal } from "./EditUserModal";
import { useUsers } from "./hooks";
import "./users.css";

/** Compact permissions summary: admins are implicit-all; others list the set. */
function permissionsSummary(user: UserAdmin): string {
  if (user.role === "admin") return "All permissions";
  if (user.permissions.length === 0) return "No permissions";
  return user.permissions.join(", ");
}

export function UsersPage() {
  const { user: currentUser } = useAuth();
  const usersQuery = useUsers();
  const [filter, setFilter] = useState("");

  const [createOpen, setCreateOpen] = useState(false);
  const [editFor, setEditFor] = useState<UserAdmin | null>(null);
  const [deleteFor, setDeleteFor] = useState<UserAdmin | null>(null);

  const { data } = usersQuery;
  const users = useMemo(() => data ?? [], [data]);

  const filtered = useMemo(() => {
    const q = filter.trim().toLowerCase();
    if (!q) return users;
    return users.filter(
      (u) =>
        u.username.toLowerCase().includes(q) ||
        (u.email?.toLowerCase().includes(q) ?? false) ||
        u.role.toLowerCase().includes(q),
    );
  }, [users, filter]);

  const adminCount = useMemo(
    () => users.filter((u) => u.role === "admin").length,
    [users],
  );

  const columns: Column<UserAdmin>[] = [
    {
      key: "status",
      header: "",
      cellClass: "dt__status",
      render: (u) => (
        <StatusDot
          tone={userStatusTone(u.enabled)}
          label={userStatusLabel(u.enabled)}
        />
      ),
    },
    {
      key: "username",
      header: "User",
      render: (u) => (
        <span className="userrow__id">
          <span className="dt__strong">
            {u.username}
            {currentUser?.id === u.id && (
              <span className="userrow__you">You</span>
            )}
          </span>
          {u.email && <span className="userrow__email">{u.email}</span>}
        </span>
      ),
    },
    {
      key: "role",
      header: "Role",
      render: (u) => <Badge tone={roleTone(u.role)}>{roleLabel(u.role)}</Badge>,
    },
    {
      key: "permissions",
      header: "Permissions",
      render: (u) => (
        <span className="userrow__perms" title={permissionsSummary(u)}>
          {permissionsSummary(u)}
        </span>
      ),
    },
    {
      key: "status_label",
      header: "Status",
      render: (u) => (
        <Badge tone={userStatusTone(u.enabled)} dot>
          {userStatusLabel(u.enabled)}
        </Badge>
      ),
    },
    {
      key: "created_at",
      header: "Created",
      render: (u) => (
        <span className="dt__mono" title={absoluteTime(u.created_at)}>
          {relativeTime(u.created_at)}
        </span>
      ),
    },
    {
      key: "last_login",
      header: "Last login",
      render: (u) => (
        <span
          className="dt__mono"
          title={u.last_login ? absoluteTime(u.last_login) : "Never signed in"}
        >
          {u.last_login ? relativeTime(u.last_login) : "never"}
        </span>
      ),
    },
    {
      key: "actions",
      header: "",
      cellClass: "dt__actions",
      render: (u) => {
        const isSelf = currentUser?.id === u.id;
        return (
          <span
            className="dt__rowactions"
            onClick={(e) => e.stopPropagation()}
          >
            <Button
              variant="ghost"
              size="sm"
              onClick={() => setEditFor(u)}
              aria-label={`Edit ${u.username}`}
            >
              <EditIcon width={14} height={14} />
              Edit
            </Button>
            {/* Self-delete is blocked client- and server-side; hide it on the
                signed-in admin's own row so it is never offered. */}
            {!isSelf && (
              <Button
                variant="danger"
                size="sm"
                onClick={() => setDeleteFor(u)}
                aria-label={`Delete ${u.username}`}
              >
                <TrashIcon width={14} height={14} />
                Delete
              </Button>
            )}
          </span>
        );
      },
    },
  ];

  return (
    <div className="page">
      <PageHeader
        title="Users"
        subtitle="Operator accounts, roles, and permissions for the GuruConnect console."
        actions={
          <>
            <Button
              variant="ghost"
              onClick={() => void usersQuery.refetch()}
              loading={usersQuery.isFetching}
            >
              <RefreshIcon width={15} height={15} />
              Refresh
            </Button>
            <Button variant="primary" onClick={() => setCreateOpen(true)}>
              <PlusIcon width={15} height={15} />
              Add user
            </Button>
          </>
        }
      />

      <Panel flush>
        <div className="userstoolbar">
          <div className="toolbar">
            <div className="searchbox">
              <span className="searchbox__icon">
                <SearchIcon width={15} height={15} />
              </span>
              <Input
                placeholder="Filter by username, email, or role"
                value={filter}
                onChange={(e) => setFilter(e.target.value)}
                aria-label="Filter users"
              />
            </div>
            <div className="toolbar__count">
              <span className="mono">{adminCount}</span> admin ·{" "}
              <span className="mono">{users.length}</span> total
            </div>
          </div>
        </div>

        {usersQuery.isLoading ? (
          <>
            <span className="visually-hidden" role="status">
              Loading users
            </span>
            <TableSkeleton
              headers={[
                "",
                "User",
                "Role",
                "Permissions",
                "Status",
                "Created",
                "Last login",
                "",
              ]}
            />
          </>
        ) : usersQuery.isError ? (
          <ErrorState
            title="Could not load users"
            message={
              usersQuery.error instanceof ApiError
                ? usersQuery.error.message
                : "The GuruConnect server did not respond. Check the relay status, then retry."
            }
            action={
              <Button
                variant="primary"
                onClick={() => void usersQuery.refetch()}
              >
                Retry
              </Button>
            }
          />
        ) : filtered.length === 0 ? (
          filter ? (
            <EmptyState
              title="No matching users"
              message={`Nothing matches "${filter}". Clear the filter to see every user.`}
              action={
                <Button variant="ghost" onClick={() => setFilter("")}>
                  Clear filter
                </Button>
              }
            />
          ) : (
            <EmptyState
              title="No users yet"
              message="Add an operator account to give a technician access to the console."
              action={
                <Button variant="primary" onClick={() => setCreateOpen(true)}>
                  Add user
                </Button>
              }
            />
          )
        ) : (
          <Table
            columns={columns}
            rows={filtered}
            rowKey={(u) => u.id}
            onRowClick={setEditFor}
            rowLabel={(u) => u.username}
          />
        )}
      </Panel>

      <CreateUserModal
        open={createOpen}
        onClose={() => setCreateOpen(false)}
      />
      <EditUserModal
        user={editFor}
        isSelf={editFor != null && currentUser?.id === editFor.id}
        onClose={() => setEditFor(null)}
      />
      <DeleteUserDialog user={deleteFor} onClose={() => setDeleteFor(null)} />
    </div>
  );
}
