import 'dart:convert';

import 'package:equatable/equatable.dart';
import 'package:hamlemuhcrm/core/extensions/log_extension.dart';

import '../../../../../data/dropdown_models/personal_getdata_api.dart';
import '../../data/dropdown_models/project_stage_api.dart';
import '../../data/repo/calendar_repository.dart';
import '../../data/repo/project_repository.dart';
import '../../features/calendar/model/calendar_model.dart';
import '../base/base_cubit.dart';

part 'dropdown_state.dart';

final class DropdownCubit extends BaseCubit<DropdownState> {
  DropdownCubit() : super(DropdownState.initial());

  var projectRepo = ProjectRepository();
  var calendarRepo = CalendarRepository();

  List<AsamalarDD> asamalar = [];
  dynamic gelenAsamaDegerler;
  bool isStageChange = false;
  String selectedStage = '';

  ///////////////////////////////////////////////////////////////////////////////

  List<ProjeDDModel> projeler = [];
  dynamic gelenProjeler;

  ///////////////////////////////////////////////////////////////////////////////

  dynamic gelenYetkiliDegerler;
  bool isYetkiliChange = false;
  String selectedYetkili = '';
  List<YetkiliDDModel> cubitSecilenYetkililer = [];

  ///////////////////////////////////////////////////////////////////////////////

  dynamic gelenCalisanDegerler;
  bool isCalisanChange = false;
  String selectedCalisan = '';
  List<CalisanYetkiliDDModel> cubitSecilenCalisanlar = [];

  Future<void> fetchStageData(
      String asamaProjeId, String token, String loginuserid) async {
    var response =
        await projectRepo.fetchAllStage(asamaProjeId, token, loginuserid);
    gelenAsamaDegerler = json.decode(response.data.toString());
  }

  Future<void> parseStageData() async {
    asamalar =
        List<AsamalarDD>.from(gelenAsamaDegerler["gorev_asamalari"].map((i) {
      return AsamalarDD.fromJSON(i);
    }));
  }

  Future<List<AsamalarDD>> processStage(
      String asamaProjeId, String token, String loginuserid) async {
    await fetchStageData(asamaProjeId, token, loginuserid);
    await parseStageData();
    return asamalar;
  }

  ///////////////////////////////////////////////////////////////////////////////
  Future<void> fetchProjectsData(
      String userfirmId, String token, String loginuserid) async {
    var response =
        await projectRepo.fetchAllProjects(userfirmId, token, loginuserid);
    gelenProjeler = json.decode(response.data.toString());
    List<ProjeDDModel> projeler = List<ProjeDDModel>.from(
      gelenProjeler["projeler"].map(
        (i) {
          return ProjeDDModel.fromJSON(i);
        },
      ),
    );
    safeEmit(state.copyWith(projeler: projeler));
  }

  ///////////////////////////////////////////////////////////////////////////////

  Future<void> fetchYetkiliData(
      String yetkiliFirmaId, String token, String loginuserid) async {
    emit(state.copyWith(yetkililer: []));
    var response = await calendarRepo.fetchAllYetkiliDD(
        yetkiliFirmaId, token, loginuserid);
    gelenYetkiliDegerler = json.decode(response.data.toString());
    List<YetkiliDDModel> yetkililer = List<YetkiliDDModel>.from(
      gelenYetkiliDegerler?["firma_yetkililer"].map(
        (i) {
          return YetkiliDDModel.fromJSON(i);
        },
      ),
    );
    safeEmit(state.copyWith(yetkililer: yetkililer));
  }

  bool? isAvailableCheckYetkililer(String yetkiliId) {
    for (var model in state.secilenYetkililer) {
      if (model.yetkiliId == yetkiliId) {
        return true;
      }
    }
    return null;
  }

  void listeyeYetkiliEkle(YetkiliDDModel yetkili) async {
    safeEmit(state.copyWith(isLoading: true, isComplete: false));
    bool isAvailable = isAvailableCheckYetkililer(yetkili.yetkiliId) ?? false;
    if (isAvailable == false) {
      List<YetkiliDDModel> yeniSecilenYetkililer =
          List.from(state.secilenYetkililer);
      yeniSecilenYetkililer.add(yetkili);
      safeEmit(state.copyWith(
          isComplete: true,
          isLoading: false,
          secilenYetkililer: yeniSecilenYetkililer));
      'state.secilenYetkililer : ${state.secilenYetkililer.length}';
      //cubitSecilenYetkililer..add(yetkili)
    } else {
      safeEmit(state.copyWith(
        isComplete: true,
        isLoading: false,
      ));
    }
    'göya eklendikten sonra state.secilenYetkililer Length : ${state.secilenYetkililer.length}'
        .log();
  }

  void listedenYetkiliCikart(YetkiliDDModel yetkili) async {
    safeEmit(state.copyWith(isLoading: true, isComplete: false));
    bool isAvailable = isAvailableCheckYetkililer(yetkili.yetkiliId) ?? false;
    if (isAvailable == true) {
      List<YetkiliDDModel> yeniSecilenYetkililer =
          List.from(state.secilenYetkililer);
      yeniSecilenYetkililer
          .removeWhere((element) => element.yetkiliId == yetkili.yetkiliId);
      safeEmit(state.copyWith(
          isComplete: true,
          isLoading: false,
          secilenYetkililer: yeniSecilenYetkililer));
      //secilenYetkililer: cubitSecilenYetkililer..remove(yetkili)));
    } else {
      safeEmit(state.copyWith(
        isComplete: true,
        isLoading: false,
        //secilenYetkililer: state.secilenYetkililer,
      ));
    }

    'göya eklendikten sonra state.secilenYetkililer Length : ${state.secilenYetkililer.length}'
        .log();
  }

  void secilenYetkiliListeTemizle() async {
    emit(state.copyWith(isLoading: true, isComplete: false));
    await Future.delayed(const Duration(milliseconds: 200));
    List<YetkiliDDModel> seciliYetkililer = List.from(state.secilenYetkililer);
    seciliYetkililer.clear();
    emit(state.copyWith(
        isLoading: false,
        isComplete: true,
        secilenYetkililer: seciliYetkililer));
  }

  Future<void> fetchCalisanData(
      String userfirmId, String token, String loginuserid) async {
    safeEmit(state.copyWith(calisanlar: []));
    var response =
        await calendarRepo.fetchAllCalisanDD(userfirmId, token, loginuserid);
    gelenCalisanDegerler = json.decode(response.data.toString());
    List<CalisanYetkiliDDModel> calisanlar = List<CalisanYetkiliDDModel>.from(
      gelenCalisanDegerler?["users"].map(
        (i) {
          return CalisanYetkiliDDModel.fromJSON(i);
        },
      ),
    );
    safeEmit(state.copyWith(calisanlar: calisanlar));
  }

  Future<bool?> isAvailableCheckCalisanlar(String calisanId) async {
    for (var model in state.secilenCalisanlar) {
      if (model.id == calisanId) {
        return true;
      }
    }
    return null;
  }

  void calisanEkle(CalisanYetkiliDDModel calisan) async {
    'state.secilenCalisanlar : ${state.secilenCalisanlar.length}';
    emit(state.copyWith(isLoading: true, isComplete: false));
    bool isAvailable = await isAvailableCheckCalisanlar(calisan.id) ?? false;
    if (isAvailable == false) {
      List<CalisanYetkiliDDModel> seciliCalisanlar =
          List.from(state.secilenCalisanlar);
      seciliCalisanlar.add(calisan);
      emit(state.copyWith(
          isComplete: true,
          isLoading: false,
          secilenCalisanlar: seciliCalisanlar));
    } else {
      emit(state.copyWith(
          isComplete: true,
          isLoading: false,
          secilenCalisanlar: state.secilenCalisanlar));
    }
    'göya eklendikten sonra state.secilenCalisanlar Length : ${state.secilenCalisanlar.length}'
        .log();
  }

  void calisanCikart(CalisanYetkiliDDModel calisan) async {
    emit(state.copyWith(isLoading: true, isComplete: false));
    bool isAvailable = await isAvailableCheckCalisanlar(calisan.id) ?? false;
    if (isAvailable == true) {
      List<CalisanYetkiliDDModel> mevcutCalisanlar =
          List.from(state.secilenCalisanlar);
      mevcutCalisanlar.removeWhere((element) => element.id == calisan.id);
      emit(state.copyWith(
          isComplete: true,
          isLoading: false,
          secilenCalisanlar: state.secilenCalisanlar
            ..removeWhere((element) => element.id == calisan.id)));
    } else {
      emit(state.copyWith(
        isComplete: true,
        isLoading: false,
        //secilenCalisanlar: state.secilenCalisanlar,
      ));
    }

    'göya eklendikten sonra state.secilenCalisanlar Length : ${state.secilenCalisanlar.length}'
        .log();
  }

  void secilenCalisanListeTemizle() async {
    emit(state.copyWith(isLoading: true, isComplete: false));
    await Future.delayed(const Duration(milliseconds: 200));
    List<CalisanYetkiliDDModel> seciliCalisanlar =
        List.from(state.secilenCalisanlar);
    seciliCalisanlar.clear();
    emit(state.copyWith(
        isLoading: false,
        isComplete: true,
        secilenCalisanlar: seciliCalisanlar));
  }

  void updateMeetSetInitialSelectedEmployess(
      CalendarModel? calendarModel) async {
    if (calendarModel == null) return;
    emit(state.copyWith(isLoading: true, isComplete: false));
    List<CalisanYetkiliDDModel> eslesenCalisanListe = [];
    List<YetkiliDDModel> eslesenYetkiliListe = [];
    String gelenUserIdler = calendarModel.toplantiUserIdler ?? '';
    String gelenYetkiliIdler = calendarModel.toplantiYetkiliIdler ?? '';

    List<String> gelenPersonelIdler = gelenUserIdler
        .split(",")
        .where((element) => element.isNotEmpty)
        .toSet()
        .toList();
    List<String> gelenYetkililerIdler = gelenYetkiliIdler
        .split(",")
        .where((element) => element.isNotEmpty)
        .toSet()
        .toList();

    for (String personelId in gelenPersonelIdler) {
      for (var element in state.calisanlar) {
        if (element.id == personelId) {
          eslesenCalisanListe.add(element);
        }
      }
    }
    for (String yetkiliId in gelenYetkililerIdler) {
      for (var k in state.yetkililer) {
        if (k.yetkiliId == yetkiliId) {
          eslesenYetkiliListe.add(k);
        }
      }
    }
    'eslesenCalisan Liste uzunluk : ${eslesenCalisanListe.length}'.log();
    'eslesenYetkili Liste uzunluk : ${eslesenYetkiliListe.length}'.log();

    for (var k in eslesenCalisanListe) {
      '${k.id} - ${k.firstName} - ${k.lastName}'.log();
    }

    for (var k in eslesenYetkiliListe) {
      '${k.yetkiliId} - ${k.yetkiliAdSoyad} '.log();
    }
    emit(state.copyWith(
        isLoading: false,
        isComplete: true,
        secilenCalisanlar: eslesenCalisanListe,
        secilenYetkililer: eslesenYetkiliListe));
  }

  void resetDropdown() {
    emit(DropdownState.initial());
  }
}
