import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { adminFetch } from './admin-api';

// ── Types ──────────────────────────────────────────────────────────────

export interface RoleSummary {
  id: string;
  name: string;
  scope: string;
}

export interface GroupSummary {
  id: string;
  name: string;
  parentGroupId: string | null;
}

export interface UserSummary {
  userId: string;
  displayName: string;
}

export interface UserDetail {
  userId: string;
  provider: string;
  email: string;
  displayName: string;
  createdAt: string;
  directRoles: RoleSummary[];
  directGroups: GroupSummary[];
  effectiveRoles: RoleSummary[];
  effectiveGroups: GroupSummary[];
}

export interface RoleDetail {
  id: string;
  name: string;
  description: string;
  scope: string;
  system: boolean;
  createdAt: string;
  assignedGroups: GroupSummary[];
  directUsers: UserSummary[];
  effectivePrincipals: UserSummary[];
}

export interface GroupDetail {
  id: string;
  name: string;
  parentGroupId: string | null;
  createdAt: string;
  directRoles: RoleSummary[];
  effectiveRoles: RoleSummary[];
  members: UserSummary[];
  childGroups: GroupSummary[];
}

export interface CreateUserRequest {
  username: string;
  displayName?: string;
  email?: string;
  password?: string;
}

export interface UpdateUserRequest {
  displayName?: string;
  email?: string;
}

export interface CreateRoleRequest {
  name: string;
  description?: string;
  scope?: string;
}

export interface UpdateRoleRequest {
  name: string;
  description?: string;
  scope?: string;
}

export interface CreateGroupRequest {
  name: string;
  parentGroupId?: string | null;
}

export interface UpdateGroupRequest {
  name: string;
  parentGroupId?: string | null;
}

// ── Stats Hook ───────────────────────────────────────────────────────

export interface RbacStats {
  userCount: number;
  activeUserCount: number;
  groupCount: number;
  maxGroupDepth: number;
  roleCount: number;
}

export function useRbacStats() {
  return useQuery({
    queryKey: ['admin', 'rbac', 'stats'],
    queryFn: () => adminFetch<RbacStats>('/rbac/stats'),
  });
}

// ── User Query Hooks ───────────────────────────────────────────────────

export function useUsers(enabled = true) {
  return useQuery({
    queryKey: ['admin', 'users'],
    queryFn: () => adminFetch<UserDetail[]>('/users'),
    enabled,
  });
}

export function useUser(userId: string | null) {
  return useQuery({
    queryKey: ['admin', 'users', userId],
    queryFn: () => adminFetch<UserDetail>(`/users/${userId}`),
    enabled: !!userId,
  });
}

// ── Role Query Hooks ───────────────────────────────────────────────────

export function useRoles(enabled = true) {
  return useQuery({
    queryKey: ['admin', 'roles'],
    queryFn: () => adminFetch<RoleDetail[]>('/roles'),
    enabled,
  });
}

export function useRole(roleId: string | null) {
  return useQuery({
    queryKey: ['admin', 'roles', roleId],
    queryFn: () => adminFetch<RoleDetail>(`/roles/${roleId}`),
    enabled: !!roleId,
  });
}

// ── Group Query Hooks ──────────────────────────────────────────────────

export function useGroups(enabled = true) {
  return useQuery({
    queryKey: ['admin', 'groups'],
    queryFn: () => adminFetch<GroupDetail[]>('/groups'),
    enabled,
  });
}

export function useGroup(groupId: string | null) {
  return useQuery({
    queryKey: ['admin', 'groups', groupId],
    queryFn: () => adminFetch<GroupDetail>(`/groups/${groupId}`),
    enabled: !!groupId,
  });
}

// ── User Mutation Hooks ────────────────────────────────────────────────

export function useCreateUser() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (req: CreateUserRequest) =>
      adminFetch<UserDetail>('/users', {
        method: 'POST',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
    },
  });
}

export function useUpdateUser() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ userId, ...req }: UpdateUserRequest & { userId: string }) =>
      adminFetch<void>(`/users/${userId}`, {
        method: 'PUT',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
    },
  });
}

export function useDeleteUser() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (userId: string) =>
      adminFetch<void>(`/users/${userId}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
    },
  });
}

export function useSetPassword() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async ({ userId, password }: { userId: string; password: string }) => {
      await adminFetch(`/users/${userId}/password`, {
        method: 'POST',
        body: JSON.stringify({ password }),
      });
    },
    onSuccess: () => qc.invalidateQueries({ queryKey: ['admin', 'users'] }),
  });
}

export function useAssignRoleToUser() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ userId, roleId }: { userId: string; roleId: string }) =>
      adminFetch<void>(`/users/${userId}/roles/${roleId}`, { method: 'POST' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}

export function useRemoveRoleFromUser() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ userId, roleId }: { userId: string; roleId: string }) =>
      adminFetch<void>(`/users/${userId}/roles/${roleId}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}

export function useAddUserToGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ userId, groupId }: { userId: string; groupId: string }) =>
      adminFetch<void>(`/users/${userId}/groups/${groupId}`, { method: 'POST' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
    },
  });
}

export function useRemoveUserFromGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ userId, groupId }: { userId: string; groupId: string }) =>
      adminFetch<void>(`/users/${userId}/groups/${groupId}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'users'] });
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
    },
  });
}

// ── Role Mutation Hooks ────────────────────────────────────────────────

export function useCreateRole() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (req: CreateRoleRequest) =>
      adminFetch<{ id: string }>('/roles', {
        method: 'POST',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}

export function useUpdateRole() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, ...req }: UpdateRoleRequest & { id: string }) =>
      adminFetch<void>(`/roles/${id}`, {
        method: 'PUT',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}

export function useDeleteRole() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) =>
      adminFetch<void>(`/roles/${id}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}

// ── Group Mutation Hooks ───────────────────────────────────────────────

export function useCreateGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (req: CreateGroupRequest) =>
      adminFetch<{ id: string }>('/groups', {
        method: 'POST',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
    },
  });
}

export function useUpdateGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ id, ...req }: UpdateGroupRequest & { id: string }) =>
      adminFetch<void>(`/groups/${id}`, {
        method: 'PUT',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
    },
  });
}

export function useDeleteGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) =>
      adminFetch<void>(`/groups/${id}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
    },
  });
}

export function useAssignRoleToGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ groupId, roleId }: { groupId: string; roleId: string }) =>
      adminFetch<void>(`/groups/${groupId}/roles/${roleId}`, { method: 'POST' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}

export function useRemoveRoleFromGroup() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ groupId, roleId }: { groupId: string; roleId: string }) =>
      adminFetch<void>(`/groups/${groupId}/roles/${roleId}`, { method: 'DELETE' }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'groups'] });
      qc.invalidateQueries({ queryKey: ['admin', 'roles'] });
    },
  });
}
