import { useState, useEffect, useCallback } from 'react';
import { UserAccountDTO, PageResponse, PageRequest, AssignRolesDTO } from '@/types/backend';
import { api } from '@/services/api';

interface UseUsersOptions extends PageRequest {
  autoFetch?: boolean;
}

interface UseUsersReturn {
  users: UserAccountDTO[];
  loading: boolean;
  error: string | null;
  page: number;
  totalPages: number;
  totalElements: number;
  refetch: () => Promise<void>;
  setPage: (page: number) => void;
  createUser: (user: Omit<UserAccountDTO, 'id' | 'createdAt' | 'updatedAt' | 'roleIds'>) => Promise<UserAccountDTO>;
  updateUser: (id: string, user: Partial<UserAccountDTO>) => Promise<UserAccountDTO>;
  getUserById: (id: string) => Promise<UserAccountDTO>;
  deleteUser: (id: string) => Promise<void>;
  assignRoles: (userId: string, roleIds: string[]) => Promise<void>;
}

export function useUsers(options: UseUsersOptions = {}): UseUsersReturn {
  const {
    page: initialPage = 0,
    size = 20,
    sortBy,
    sortDirection = 'ASC',
    autoFetch = true,
  } = options;

  const [users, setUsers] = useState<UserAccountDTO[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(initialPage);
  const [totalPages, setTotalPages] = useState(0);
  const [totalElements, setTotalElements] = useState(0);

  const fetchUsers = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const response: PageResponse<UserAccountDTO> = await api.getPage<UserAccountDTO>(
        '/admin/users',
        {
          page,
          size,
          sortBy,
          sortDirection,
        }
      );
      setUsers(response.content);
      setTotalPages(response.totalPages);
      setTotalElements(response.totalElements);
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.message ||
        err.message ||
        'Erro ao carregar utilizadores';
      setError(errorMessage);
      console.error('Erro ao buscar utilizadores:', err);
    } finally {
      setLoading(false);
    }
  }, [page, size, sortBy, sortDirection]);

  useEffect(() => {
    if (autoFetch) {
      fetchUsers();
    }
  }, [fetchUsers, autoFetch]);

  const createUser = async (
    user: Omit<UserAccountDTO, 'id' | 'createdAt' | 'updatedAt' | 'roleIds'>
  ): Promise<UserAccountDTO> => {
    try {
      setError(null);
      const newUser = await api.post<UserAccountDTO>('/admin/users', user);
      await fetchUsers();
      return newUser;
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.message ||
        err.message ||
        'Erro ao criar utilizador';
      setError(errorMessage);
      throw new Error(errorMessage);
    }
  };

  const updateUser = async (
    id: string,
    user: Partial<UserAccountDTO>
  ): Promise<UserAccountDTO> => {
    try {
      setError(null);
      const updated = await api.put<UserAccountDTO>(`/admin/users/${id}`, user);
      await fetchUsers();
      return updated;
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.message ||
        err.message ||
        'Erro ao atualizar utilizador';
      setError(errorMessage);
      throw new Error(errorMessage);
    }
  };

  const getUserById = async (id: string): Promise<UserAccountDTO> => {
    try {
      setError(null);
      const user = await api.get<UserAccountDTO>(`/admin/users/${id}`);
      return user;
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.message ||
        err.message ||
        'Erro ao buscar utilizador';
      setError(errorMessage);
      throw new Error(errorMessage);
    }
  };

  const deleteUser = async (id: string): Promise<void> => {
    try {
      setError(null);
      await api.delete(`/admin/users/${id}`);
      await fetchUsers();
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.message ||
        err.message ||
        'Erro ao excluir utilizador';
      setError(errorMessage);
      throw new Error(errorMessage);
    }
  };

  const assignRoles = async (userId: string, roleIds: string[]): Promise<void> => {
    try {
      setError(null);
      const payload: AssignRolesDTO = { roleIds };
      await api.post(`/admin/users/${userId}/roles`, payload);
      await fetchUsers();
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.message ||
        err.message ||
        'Erro ao atribuir perfis';
      setError(errorMessage);
      throw new Error(errorMessage);
    }
  };

  return {
    users,
    loading,
    error,
    page,
    totalPages,
    totalElements,
    refetch: fetchUsers,
    setPage,
    createUser,
    updateUser,
    getUserById,
    deleteUser,
    assignRoles,
  };
}

export function useUser(id: string) {
  const [user, setUser] = useState<UserAccountDTO | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchUser = async () => {
      if (!id) return;
      
      setLoading(true);
      setError(null);
      
      try {
        const data = await api.get<UserAccountDTO>(`/admin/users/${id}`);
        setUser(data);
      } catch (err: any) {
        const errorMessage =
          err.response?.data?.message ||
          err.message ||
          'Erro ao buscar utilizador';
        setError(errorMessage);
      } finally {
        setLoading(false);
      }
    };

    fetchUser();
  }, [id]);

  return { user, loading, error };
}

