import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:unit2/model/location/country.dart';
import 'package:unit2/model/location/region.dart';
import 'package:unit2/screens/profile/components/other_information/org_membership/add_modal.dart';
import 'package:unit2/screens/unit2/login/components/update_required.dart';
import 'package:unit2/sevices/profile/learningDevelopment_service.dart';
import 'package:unit2/test_data.dart';
import 'package:unit2/utils/text_container.dart';

import '../../../model/location/barangay.dart';
import '../../../model/location/city.dart';
import '../../../model/location/provinces.dart';
import '../../../model/profile/learning_development.dart';
import '../../../model/utils/agency.dart';
import '../../../model/utils/category.dart';
import '../../../utils/location_utilities.dart';
import '../../../utils/profile_utilities.dart';

part 'learning_development_event.dart';
part 'learning_development_state.dart';

class LearningDevelopmentBloc
    extends Bloc<LearningDevelopmentEvent, LearningDevelopmentState> {
  LearningDevelopmentBloc() : super(LearningDevelopmentInitial()) {
    List<LearningDevelopement> learningsAndDevelopments = [];
    List<LearningDevelopmentType> types = [];
    List<LearningDevelopmentType> topics = [];
    List<Country> globalCountries = [];
    List<Region> globalRegions = [];
    List<Province> globalProvinces = [];
    List<CityMunicipality> globalCities = [];
    List<Barangay> globalBarangay = [];
    List<Agency> agencies = [];
    List<Category> agencyCategory = [];

    Region? currentRegion;
    Country? currentCountry;
    Province? currentProvince;
    CityMunicipality? currentCity;
    Barangay? currentBarangay;
    
    on<GetLearningDevelopments>((event, emit) async {
            emit(LearningDevelopmentLoadingState());
      try {

      List<LearningDevelopement> learnings = await LearningDevelopmentServices
          .instance
          .getLearningDevelopments(event.profileId, event.token);
      learningsAndDevelopments = learnings;
      emit(LearningDevelopmentLoadedState(
          learningsAndDevelopment: learningsAndDevelopments));
      } catch (e) {
        emit(LearningDevelopmentErrorState(message: e.toString()));
      }
    });
    ////load
    on<LoadLearniningDevelopment>((event, emit) {
      emit(LearningDevelopmentLoadedState(
          learningsAndDevelopment: learningsAndDevelopments));
    });
    //// show add form
    on<ShowAddLearningDevelopmentForm>((event, emit) async {
      try {
        emit(LearningDevelopmentLoadingState());
        if (types.isEmpty) {
          List<LearningDevelopmentType> newTypes =
              await LearningDevelopmentServices.instance
                  .getLearningDevelopmentType();
          types = newTypes;
        }
        if (topics.isEmpty) {
          List<LearningDevelopmentType> newTopics =
              await LearningDevelopmentServices.instance.getTrainingTopics();
          topics = newTopics;
        }
        if (globalRegions.isEmpty) {
          List<Region> regions = await LocationUtils.instance.getRegions();
          globalRegions = regions;
        }
        if (globalCountries.isEmpty) {
          List<Country> countries = await LocationUtils.instance.getCountries();
          globalCountries = countries;
        }
        if (agencies.isEmpty) {
          List<Agency> newAgencies =
              await ProfileUtilities.instance.getAgecies();
          agencies = newAgencies;
        }
        if (agencyCategory.isEmpty) {
          List<Category> categoryAgencies =
              await ProfileUtilities.instance.agencyCategory();
          agencyCategory = categoryAgencies;
        }

        emit(LearningDevelopmentAddingState(
            types: types,
            topics: topics,
            countries: globalCountries,
            regions: globalRegions,
            conductedBy: agencies,
            sponsorAgencies: agencies,
            agencyCategory: agencyCategory));
      } catch (e) {
        emit(LeaningDevelopmentErrorState(message: e.toString()));
      }
    });
    ////Show edit form
    on<ShowEditLearningDevelopmentForm>((event, emit) async {
      try{
      if (globalRegions.isEmpty) {
        List<Region> regions = await LocationUtils.instance.getRegions();
        globalRegions = regions;
      }
      if (globalCountries.isEmpty) {
        List<Country> countries = await LocationUtils.instance.getCountries();
        globalCountries = countries;
      }
      currentCountry = globalCountries.firstWhere((Country country) =>
          event.learningDevelopment.conductedTraining!.venue!.country!.code ==
          country.code);
      if (!event.isOverseas) {
        //// if not overseas
        currentRegion = globalRegions.firstWhere((Region region) =>
            event.learningDevelopment.conductedTraining!.venue!
                .cityMunicipality!.province!.region!.code ==
            region.code);

        globalProvinces = await LocationUtils.instance
            .getProvinces(regionCode: currentRegion!.code.toString());
        currentProvince = globalProvinces.firstWhere((Province province) =>
            event.learningDevelopment.conductedTraining!.venue!
                .cityMunicipality!.province!.code ==
            province.code);

        globalCities = await LocationUtils.instance
            .getCities(code: currentProvince!.code.toString());

        currentCity = globalCities.firstWhere(
            (CityMunicipality cityMunicipality) =>
                event.learningDevelopment.conductedTraining!.venue!
                    .cityMunicipality!.code ==
                cityMunicipality.code);
        globalBarangay = await LocationUtils.instance
            .getBarangay(code: currentCity!.code.toString());

        if (event.learningDevelopment.conductedTraining?.venue?.barangay?.cityMunicipality !=
            null) {
          currentBarangay = globalBarangay.firstWhere((Barangay barangay) =>
              event.learningDevelopment.conductedTraining!.venue!.barangay!
                  .code ==
              barangay.code);
        } else {
          currentBarangay = null;
        }
      }
      if (topics.isEmpty) {
        List<LearningDevelopmentType> newTopics =
            await LearningDevelopmentServices.instance.getTrainingTopics();
        topics = newTopics;
      }
      if (types.isEmpty) {
        List<LearningDevelopmentType> newTypes =
            await LearningDevelopmentServices.instance
                .getLearningDevelopmentType();
        types = newTypes;
      }
      if (agencies.isEmpty) {
        List<Agency> newAgencies = await ProfileUtilities.instance.getAgecies();
        agencies = newAgencies;
      }
      if (agencyCategory.isEmpty) {
        List<Category> categoryAgencies =
            await ProfileUtilities.instance.agencyCategory();
        agencyCategory = categoryAgencies;
      }
      emit(LearningDevelopmentUpdatingState(
        cities: globalCities,
          currentBarangay: currentBarangay,
          barangay: globalBarangay,

          provinces: globalProvinces,
          types: types,
          topics: topics,
          training: event.learningDevelopment.conductedTraining!.title!,
          learningDevelopement: event.learningDevelopment,
          currentConductedBy:
          event.learningDevelopment.conductedTraining!.conductedBy!,
          currentSponsor: event.learningDevelopment.sponsoredBy,
          conductedBy: agencies,
          sponsorAgencies: agencies,
          agencyCategory: agencyCategory,
          countries: globalCountries,
          regions: globalRegions,
          currentRegion: currentRegion,
          currentCountry: currentCountry!,
          currentProvince: currentProvince,
          currentCity: currentCity,
          overseas: event.isOverseas));
      }catch(e){
        emit(LearningDevelopmentErrorState(message: e.toString()));
      }
    });

    ////Add
    on<AddLearningAndDevelopment>((event, emit) async {
      try {
        Map<dynamic, dynamic> status =
            await LearningDevelopmentServices.instance.add(
                learningDevelopement: event.learningDevelopement,
                token: event.token,
                profileId: event.profileId);
        if (status['success']) {
          LearningDevelopement learningDevelopement =
              LearningDevelopement.fromJson(status['data']);
          learningsAndDevelopments.add(learningDevelopement);
          emit(LearningDevelopmentAddedState(response: status));
        } else {
          emit(LearningDevelopmentAddedState(response: status));
        }
      } catch (e) {
        emit(LearningDevelopmentErrorState(message: e.toString()));
      }
    });
    
    ////Update
    on<UpdateLearningDevelopment>((event, emit) async {
      try {
        Map<dynamic, dynamic> status =
            await LearningDevelopmentServices.instance.update(
                learningDevelopement: event.learningDevelopement,
                token: event.token,
                profileId: event.profileId);
        if (status['success']) {
           learningsAndDevelopments.removeWhere((LearningDevelopement element) =>
              element.conductedTraining!.id == event.learningDevelopement.conductedTraining!.id &&
              element.conductedTraining!.totalHours == event.learningDevelopement.conductedTraining!.totalHours);
          LearningDevelopement learningDevelopement =
              LearningDevelopement.fromJson(status['data']);
          learningsAndDevelopments.add(learningDevelopement);
          emit(LearningDevelopmentUpdatedState(response: status));
        } else {
          emit(LearningDevelopmentUpdatedState(response: status));
        }
      } catch (e) {
        emit(LearningDevelopmentErrorState(message: e.toString()));
      }
    });
    ////delete
    on<DeleteLearningDevelopment>((event, emit) async {
      try {
        final bool success = await LearningDevelopmentServices.instance.delete(
            profileId: event.profileId,
            token: event.token,
            sponsorId: event.sponsorId,
            totalHours: event.hours,
            trainingId: event.trainingId);
        if (success) {
          learningsAndDevelopments.removeWhere((LearningDevelopement element) =>
              element.conductedTraining!.id == event.trainingId &&
              element.conductedTraining!.totalHours == event.hours);
          emit(DeleteLearningDevelopmentState(success: success));
        } else {
          emit(DeleteLearningDevelopmentState(success: success));
        }
      } catch (e) {
        emit(LearningDevelopmentErrorState(message: e.toString()));
      }
    });
    //// call errror
    on<CallErrorState>((event, emit) {
      emit(LeaningDevelopmentErrorState(message: event.message));
    });
  }
}
