import { useMemo, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Link } from "wouter";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Checkbox } from "@/components/ui/checkbox";
import { getQueryFn } from "@/lib/queryClient";
import RoleBadge from "./components/RoleBadge";
import RoleActions from "./components/RoleActions";
import type { DeleteUserResponse, HardResetResponse, UserSummary, UsersResponse } from "./types";
import { fetchAdminJson, getAdminErrorMessage } from "./api";

export default function AdminUsers() {
  const [page, setPage] = useState(1);
  const [query, setQuery] = useState("");
  const [deleteTarget, setDeleteTarget] = useState<UserSummary | null>(null);
  const [confirmChecked, setConfirmChecked] = useState(false);
  const [deleteError, setDeleteError] = useState<string | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const [resetTarget, setResetTarget] = useState<UserSummary | null>(null);
  const [resetChecked, setResetChecked] = useState(false);
  const [resetError, setResetError] = useState<string | null>(null);
  const [isResetting, setIsResetting] = useState(false);
  const queryClient = useQueryClient();
  const pageSize = 20;

  const queryString = useMemo(() => {
    const params = new URLSearchParams();
    params.set("page", String(page));
    params.set("page_size", String(pageSize));
    if (query.trim()) {
      params.set("query", query.trim());
    }
    return params.toString();
  }, [page, pageSize, query]);

  const usersQuery = useQuery<UsersResponse>({
    queryKey: ["admin/users", page, query],
    queryFn: async () => {
      const data = await fetchAdminJson<UsersResponse>(`admin/users?${queryString}`);
      if (!data) {
        throw new Error("No admin users response returned.");
      }
      return data;
    },
  });

  const meQuery = useQuery<{ id: string; username: string; role?: string } | null>({
    queryKey: ["me"],
    queryFn: getQueryFn({ on401: "returnNull" }),
  });

  const canDelete = !!deleteTarget && confirmChecked && !isDeleting;
  const canReset = !!resetTarget && resetChecked && !isResetting;

  const handleDelete = async () => {
    if (!deleteTarget) {
      return;
    }
    setIsDeleting(true);
    setDeleteError(null);
    try {
      const result = await fetchAdminJson<DeleteUserResponse>(
        `admin/users/${deleteTarget.user_id}?hard=true`,
        { method: "DELETE" },
      );
      void result;
      setDeleteTarget(null);
      setConfirmChecked(false);
      await queryClient.invalidateQueries({ queryKey: ["admin/users"] });
      await queryClient.invalidateQueries({ queryKey: ["admin/overview"] });
    } catch (err) {
      const message = getAdminErrorMessage(err, "Delete failed.");
      setDeleteError(message);
    } finally {
      setIsDeleting(false);
    }
  };

  const handleReset = async () => {
    if (!resetTarget) {
      return;
    }
    setIsResetting(true);
    setResetError(null);
    try {
      const result = await fetchAdminJson<HardResetResponse>(
        `admin/users/${resetTarget.user_id}/hard-reset`,
        { method: "POST" },
      );
      void result;
      setResetTarget(null);
      setResetChecked(false);
      await queryClient.invalidateQueries({ queryKey: ["admin/users"] });
      await queryClient.invalidateQueries({ queryKey: ["admin/overview"] });
    } catch (err) {
      const message = getAdminErrorMessage(err, "Reset failed.");
      setResetError(message);
    } finally {
      setIsResetting(false);
    }
  };

  if (usersQuery.isLoading) {
    return <div className="text-sm text-muted-foreground">Loading users...</div>;
  }

  if (usersQuery.isError) {
    return (
      <div className="rounded-2xl border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive">
        {getAdminErrorMessage(usersQuery.error, "Failed to load users.")}
      </div>
    );
  }

  const data = usersQuery.data;
  if (!data) {
    return <div className="text-sm text-muted-foreground">No users.</div>;
  }

  const totalPages = Math.max(1, Math.ceil(data.total / data.page_size));
  const currentUserId = meQuery.data?.id;
  const currentUserRole = meQuery.data?.role ?? "USER";
  const isSuperAdmin = currentUserRole === "SUPER_ADMIN";

  return (
    <div className="space-y-6">
      <div className="rounded-2xl border border-border/60 bg-card/70 p-6 shadow-sm">
        <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
          <div>
            <p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">Users</p>
            <h2 className="text-2xl font-semibold">User directory</h2>
          </div>
          <Input
            className="md:w-72"
            placeholder="Search by email or ID"
            value={query}
            onChange={(e) => {
              setQuery(e.target.value);
              setPage(1);
            }}
          />
        </div>
      </div>

      <div className="rounded-2xl border border-border/60 bg-card/70 p-6 shadow-sm overflow-x-auto">
        <table className="min-w-full text-sm">
          <thead className="text-muted-foreground">
            <tr>
              <th className="px-4 py-2 text-left">User</th>
              <th className="px-4 py-2 text-left">Role</th>
              <th className="px-4 py-2 text-left">Last login</th>
              <th className="px-4 py-2 text-left">Runs</th>
              <th className="px-4 py-2 text-left">Active run</th>
              <th className="px-4 py-2 text-left">Broker</th>
              {isSuperAdmin && <th className="px-4 py-2 text-left">Actions</th>}
            </tr>
          </thead>
          <tbody className="divide-y divide-border/60">
            {data.users.map((user) => (
              <tr key={user.user_id}>
                <td className="px-4 py-2">
                  <Link href={`/admin/users/${user.user_id}`}>
                    <a className="text-primary hover:underline">{user.username}</a>
                  </Link>
                </td>
                <td className="px-4 py-2">
                  <RoleBadge role={user.role} isSelf={user.user_id === currentUserId} />
                </td>
                <td className="px-4 py-2 text-xs text-muted-foreground">
                  {user.last_login_at ?? "-"}
                </td>
                <td className="px-4 py-2">{user.runs_count}</td>
                <td className="px-4 py-2 text-xs">
                  {user.active_run_status ? `${user.active_run_status}` : "-"}
                </td>
                <td className="px-4 py-2 text-xs">
                  {user.broker_connected ? "Connected" : "Not connected"}
                </td>
                {isSuperAdmin && (
                  <td className="px-4 py-2 space-y-2">
                    <RoleActions
                      target={user}
                      isSelf={user.user_id === currentUserId}
                      isSuperAdmin={isSuperAdmin}
                      onUpdated={() => {
                        queryClient.invalidateQueries({ queryKey: ["admin/users"] });
                        queryClient.invalidateQueries({ queryKey: ["admin/overview"] });
                      }}
                    />
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => {
                        setResetTarget(user);
                        setResetChecked(false);
                        setResetError(null);
                      }}
                    >
                      Hard reset data
                    </Button>
                    <Button
                      variant="destructive"
                      size="sm"
                      disabled={user.user_id === currentUserId && user.role === "SUPER_ADMIN"}
                      onClick={() => {
                        setDeleteTarget(user);
                        setConfirmChecked(false);
                        setDeleteError(null);
                      }}
                    >
                      Delete user
                    </Button>
                  </td>
                )}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div className="flex items-center justify-between">
        <Button
          variant="outline"
          disabled={page <= 1}
          onClick={() => setPage((p) => Math.max(1, p - 1))}
        >
          Prev
        </Button>
        <span className="text-xs text-muted-foreground">
          Page {page} of {totalPages}
        </span>
        <Button
          variant="outline"
          disabled={page >= totalPages}
          onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
        >
          Next
        </Button>
      </div>

      <Dialog
        open={!!deleteTarget}
        onOpenChange={(open) => {
          if (!open) {
            setDeleteTarget(null);
          }
        }}
      >
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>Delete user</DialogTitle>
            <DialogDescription>
              This will permanently delete all trading history, orders, logs, sessions, and broker
              links for this user. This action cannot be undone.
            </DialogDescription>
          </DialogHeader>

          {deleteTarget && (
            <div className="space-y-4">
              <label className="flex items-start gap-3 text-sm">
                <Checkbox
                  checked={confirmChecked}
                  onCheckedChange={(checked) => setConfirmChecked(Boolean(checked))}
                />
                <span className="text-muted-foreground">
                  I understand this action is permanent and cannot be undone.
                </span>
              </label>
              {deleteError && <p className="text-xs text-destructive">{deleteError}</p>}
            </div>
          )}

          <DialogFooter className="flex flex-col gap-2 sm:flex-row sm:justify-end">
            <Button
              variant="outline"
              onClick={() => setDeleteTarget(null)}
              disabled={isDeleting}
            >
              Cancel
            </Button>
            <Button variant="destructive" onClick={handleDelete} disabled={!canDelete}>
              {isDeleting ? "Deleting..." : "Delete permanently"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={!!resetTarget}
        onOpenChange={(open) => {
          if (!open) {
            setResetTarget(null);
          }
        }}
      >
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>Hard reset user data</DialogTitle>
            <DialogDescription>
              This clears all runs, orders, trades, positions, MTM, logs, and events for this user.
              The account stays, but trading history is wiped. This cannot be undone.
            </DialogDescription>
          </DialogHeader>

          {resetTarget && (
            <div className="space-y-4">
              <label className="flex items-start gap-3 text-sm">
                <Checkbox
                  checked={resetChecked}
                  onCheckedChange={(checked) => setResetChecked(Boolean(checked))}
                />
                <span className="text-muted-foreground">
                  I understand this will permanently wipe all trading history for this user.
                </span>
              </label>
              {resetError && <p className="text-xs text-destructive">{resetError}</p>}
            </div>
          )}

          <DialogFooter className="flex flex-col gap-2 sm:flex-row sm:justify-end">
            <Button
              variant="outline"
              onClick={() => setResetTarget(null)}
              disabled={isResetting}
            >
              Cancel
            </Button>
            <Button variant="destructive" onClick={handleReset} disabled={!canReset}>
              {isResetting ? "Resetting..." : "Reset data"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
