import { createContext, PropsWithChildren, useContext } from "react";
import { StateRepository } from "../domain/repositories/state_repository";
import { StateRepositoryImpl } from "../infrastructure/repositories/state_repository";
import { StateDataSourceDev } from "../infrastructure/datasource/dev/state_datasource";
import { AuthRepository } from "../domain/repositories/auth_repository";
import { AuthDataSourceDev } from "../infrastructure/datasource/dev/auth_datasource";
import { AuthRepositoryImpl } from "../infrastructure/repositories/auth_repository";
import { AuthDatasourceProd } from "../infrastructure/datasource/prod/auth_datasource";
import { ActivityRepository } from "../domain/repositories/activity_repository";
import { ActivityDatasourceDev } from "../infrastructure/datasource/dev/activity_datasource";
import { ActivityRepositoryDev } from '../infrastructure/repositories/activity_repository';

type DataContextType = {
    statesRepository: StateRepository | null;
    authRepository: AuthRepository | null;
    activityRepository: ActivityRepository | null;
};

type DataContextProviderProps = PropsWithChildren<{}>;

const DataContext = createContext<DataContextType>({
    statesRepository: null,
    authRepository: null,
    activityRepository: null
});

export const DataContextProvider = ({ children }: DataContextProviderProps) => {
    const statesDataSource = new StateDataSourceDev();
    const statesRepository = new StateRepositoryImpl(statesDataSource);
    const authDataSource = new AuthDataSourceDev();
    const authRepository = new AuthRepositoryImpl(authDataSource);
    const activityDataSource = new ActivityDatasourceDev();
    const activityRepository = new ActivityRepositoryDev(activityDataSource);
    
    const value = {
        statesRepository,
        authRepository,
        activityRepository
    };

    return (
        <DataContext.Provider value={value}>
            {children}
        </DataContext.Provider>
    );
};

export const useDataContext = () => {
    const context = useContext(DataContext);
    if (!context) {
        throw new Error("useDataContext must be used within a DataContextProvider");
    }
    return context;
}