import { useState, useEffect, useCallback } from 'react';
import { PositionDTO } from '@/types/org';
import { PageResponse, PageRequest } from '@/types/backend';
import { orgService } from '@/services/orgService';

interface UsePositionsOptions extends PageRequest {
    autoFetch?: boolean;
    orgUnitId?: string;
}

interface UsePositionsReturn {
    positions: PositionDTO[];
    loading: boolean;
    error: string | null;
    page: number;
    totalPages: number;
    totalElements: number;
    refetch: () => Promise<void>;
    setPage: (page: number) => void;
    createPosition: (position: Omit<PositionDTO, 'id'>) => Promise<PositionDTO>;
    updatePosition: (id: string, position: PositionDTO) => Promise<PositionDTO>;
    getPositionById: (id: string) => Promise<PositionDTO>;
}

export function usePositions(options: UsePositionsOptions = {}): UsePositionsReturn {
    const {
        page: initialPage = 0,
        size = 20,
        sortBy,
        sortDirection = 'ASC',
        autoFetch = true,
        orgUnitId,
    } = options;

    const [positions, setPositions] = useState<PositionDTO[]>([]);
    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 fetchPositions = useCallback(async () => {
        try {
            setLoading(true);
            setError(null);
            const response = await orgService.getPositions({
                page,
                size,
                sortBy,
                sortDirection,
                orgUnitId,
            });

            // Lidar com retorno de PageResponse ou Array
            if ('content' in response) {
                setPositions(response.content);
                setTotalPages(response.totalPages);
                setTotalElements(response.totalElements);
            } else {
                // Se for array (quando filtrado por orgUnitId em alguns casos), simular paginação
                setPositions(response as PositionDTO[]);
                setTotalPages(1);
                setTotalElements((response as PositionDTO[]).length);
            }
        } catch (err: any) {
            const errorMessage =
                err.response?.data?.message ||
                err.message ||
                'Erro ao carregar posições';
            setError(errorMessage);
            console.error('Erro ao buscar posições:', err);
        } finally {
            setLoading(false);
        }
    }, [page, size, sortBy, sortDirection, orgUnitId]);

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

    const createPosition = async (
        position: Omit<PositionDTO, 'id'>
    ): Promise<PositionDTO> => {
        try {
            setError(null);
            const newPosition = await orgService.createPosition(position as PositionDTO);
            await fetchPositions();
            return newPosition;
        } catch (err: any) {
            const errorMessage =
                err.response?.data?.message ||
                err.message ||
                'Erro ao criar posição';
            setError(errorMessage);
            throw new Error(errorMessage);
        }
    };

    const updatePosition = async (
        id: string,
        position: PositionDTO
    ): Promise<PositionDTO> => {
        try {
            setError(null);
            const updated = await orgService.updatePosition(id, position);
            await fetchPositions();
            return updated;
        } catch (err: any) {
            const errorMessage =
                err.response?.data?.message ||
                err.message ||
                'Erro ao atualizar posição';
            setError(errorMessage);
            throw new Error(errorMessage);
        }
    };

    const getPositionById = async (id: string): Promise<PositionDTO> => {
        try {
            setError(null);
            const position = await orgService.getPositionById(id);
            return position;
        } catch (err: any) {
            const errorMessage =
                err.response?.data?.message ||
                err.message ||
                'Erro ao buscar posição';
            setError(errorMessage);
            throw new Error(errorMessage);
        }
    };

    return {
        positions,
        loading,
        error,
        page,
        totalPages,
        totalElements,
        refetch: fetchPositions,
        setPage,
        createPosition,
        updatePosition,
        getPositionById,
    };
}
