import { createContext, PropsWithChildren, useContext } from "react";
import { StateRepositoryImpl } from "../../place/infrastructure/repositories/state_repository";
import { StateDataSourceDev } from "../../place/infrastructure/datasources/dev/state_datasource";
import { AuthRepository } from "../../auth/domain/repositories/auth_repository";
import { AuthDataSourceDev } from "../../auth/infrastructure/dev/datasources/auth_datasource";
import { AuthRepositoryImpl } from "../../auth/infrastructure/prod/repositories/auth_repository";
import { RouteRepository } from "../../route/domain/repositories/route_repository";
import { RouteDataSourceDev } from "../../route/infrastructure/datasources/dev/route_datasource";
import { RouteRepositoryImpl } from "../../route/infrastructure/repositories/route_repository";
import { StateDataSourceProd } from "../../place/infrastructure/datasources/prod/state_datasource";
import { ProfileRepository } from "../../profile/domain/repositories/profile_repository";
import { ProfileDataSourceDev } from "../../profile/infrastructure/datasources/dev/profile_datasource";
import { ProfileRepositoryImpl } from "../../profile/infrastructure/repositories/profile_repository";
import { useTranslation } from "react-i18next";
import { ProfileDataSourceProd } from "../../profile/infrastructure/datasources/prod/profile_datasource";
import { ActivityRepository } from "../../activity/domain/repositories/activity_repository";
import { RouteDatasourceProd } from "../../route/infrastructure/datasources/prod/route_datasource";
import { ActivityRepositoryDev } from "../../activity/infrastructure/repositories/activity_repository";
import { ActivityDatasourceProd } from "../../activity/infrastructure/datasources/prod/activity_datasource";
import { ActivityDatasourceDev } from "../../activity/infrastructure/datasources/dev/activity_datasource";
import { StateRepository } from "../../place/domain/repositories/state_repository";
import { TravelRepository } from "../../travel/domain/repositories/travel_repository";
import { TravelRepositoryImpl } from "../../travel/infrastructure/repositories/travel_repository";
import { AuthDatasourceProd } from "../../auth/infrastructure/prod/datasources/auth_datasource";
import { TravelDatasourceDev } from "../../travel/infrastructure/datasources/dev/travel_datasource";
import { TravelDatasourceProd } from "../../travel/infrastructure/datasources/prod/travel_datasource_prod";

type DataContextType = {
  statesRepository: StateRepository | null;
  authRepository: AuthRepository | null;
  activityRepository: ActivityRepository | null;
  travelRepository: TravelRepository | null;
  routeRepository: RouteRepository | null;
  profileRepository: ProfileRepository | null;
};

type DataContextProviderProps = PropsWithChildren<{}>;

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

const getProductionContext = (language: string): DataContextType => {
  return {
    statesRepository: new StateRepositoryImpl(
      new StateDataSourceProd(language)
    ),
    authRepository: new AuthRepositoryImpl(new AuthDatasourceProd()),
    activityRepository: new ActivityRepositoryDev(new ActivityDatasourceProd()),
    travelRepository: new TravelRepositoryImpl(new TravelDatasourceProd()),
    routeRepository: new RouteRepositoryImpl(new RouteDatasourceProd(language)),
    profileRepository: new ProfileRepositoryImpl(
      new ProfileDataSourceProd(language)
    ),
  };
};

const getDevelopmentContext = (): DataContextType => {
  return {
    statesRepository: new StateRepositoryImpl(new StateDataSourceDev()),
    authRepository: new AuthRepositoryImpl(new AuthDataSourceDev()),
    activityRepository: new ActivityRepositoryDev(new ActivityDatasourceDev()),
    travelRepository: new TravelRepositoryImpl(new TravelDatasourceDev()),
    routeRepository: new RouteRepositoryImpl(new RouteDataSourceDev()),
    profileRepository: new ProfileRepositoryImpl(new ProfileDataSourceDev()),
  };
};

export const DataContextProvider = ({ children }: DataContextProviderProps) => {
  const {
    i18n: { language },
  } = useTranslation();

  const value = getProductionContext(language);
  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;
};
