import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../../../core/constants/url_services_constant.dart';
import '../../../../core/extensions/log_extension.dart';
import '../../../../core/utility/toast_manager.dart';
import '../../../../data/dropdown_models/personal_getdata_api.dart';
import '../../../auth/login/cubit/login_cubit.dart';
import '../../../home/view/home_custom.dart';
import '../../cubit/message_cubit.dart';
import '../../model/query/req_update_group.dart';
import '../../widget/group_multi_select_leader.dart';
import '../../widget/group_multi_select_user.dart';
import '../group_detail_view.dart';

mixin GroupDetailViewMixin on State<GroupDetailView> {
  final TextEditingController _groupNameController = TextEditingController();

  TextEditingController get groupNameController => _groupNameController;

  String gonderilecekGrupYoneticiIdler = '';
  List<String> secilenGrupYoneticiList = [];

  List<PersonelDDModel> calisanListesi = [];

  String gonderilecekGrupKullaniciIdler = '';
  List<String> secilenGrupKullaniciList = [];

  @override
  void initState() {
    super.initState();
    setInitialGroupName(widget.group.grupAdi);
    setInitialGroupUser(widget.group.grupKullanicilari);
    setInitialGroupLeader(widget.group.grupYoneticileri);
  }

  @override
  void dispose() {
    _groupNameController.dispose();
    super.dispose();
  }

  @override
  void deactivate() {
    super.deactivate();
    'deactive calisti'.log();
    context.read<MessageCubit>().secilenGrupYoneticileriIdler.clear();
    context.read<MessageCubit>().secilenGrupYoneticileriAdlar.clear();
    context.read<MessageCubit>().secilenGrupKullanicilariAdlar.clear();
    context.read<MessageCubit>().secilenGrupKullanicilariIdler.clear();
  }

  Future<List<PersonelDDModel>> userfirmCalisanData(
      String userfirmid, String token, String loginuserid) async {
    Map<String, dynamic>? dataPersonel;

    var calisanURL =
        "${URLAPIService.baseURL}/mobil/api/dd/firmaya_gore_personel_dd_pdo.php";
    var veri = {
      "user_userfirm_id": userfirmid,
      "token": token,
      "loginuserid": loginuserid
    };
    var response = await Dio().post(calisanURL, data: FormData.fromMap(veri));

    if (response.statusCode == 200) {
      setState(() {
        dataPersonel = json.decode(response.data.toString());
      });
      return calisanListesi = List<PersonelDDModel>.from(
        dataPersonel?["users"].map(
          (i) {
            return PersonelDDModel.fromJSON(i);
          },
        ),
      );
    }
    return [];
  }

  void setInitialGroupName(String? grupAd) {
    // Grup Adı null değilse atama yap
    if (grupAd == null) return;
    _groupNameController.text = grupAd;
  }

  void setInitialGroupUser(String? grupKullanicilari) {
    if (grupKullanicilari == null) return;
    List<String> result = [];

    final list = grupKullanicilari.split('h')
      ..toSet()
      ..toList();
    for (var k in list) {
      if (k.isNotEmpty) {
        result.add(k);
      }
    }
    for (var k in result) {
      'list : ${k.toString()}'.log();
    }
    context.read<MessageCubit>().secilenGrupKullanicilariIdler = result;
    if (!mounted) return;
    setIdFromGroupUserToName(result);
  }

  void setInitialGroupLeader(String? grupYoneticileri) {
    if (grupYoneticileri == null) return;
    List<String> result = [];

    final list = grupYoneticileri.split('h')
      ..toSet()
      ..toList();
    for (var k in list) {
      if (k.isNotEmpty) {
        result.add(k);
      }
    }
    if (!mounted) return;
    context.read<MessageCubit>().secilenGrupYoneticileriIdler = result;
    setIdFromGroupLeaderToName(result);
    // gelen grup yönetici adlari boş değil ise cubit tarafında ki listeye çevirip eşitle boş ise boş listeye yeniden eşitle
    // context.read<MessageCubit>().secilenGrupYoneticileriAdlar = widget.group.grupYoneticileriAdlar != null? widget.group.grupYoneticileriAdlar!.split(","): [];
  }

  Future<void> setIdFromGroupLeaderToName(List<String> leaderIds) async {
    List<PersonelDDModel> personeller = await userfirmCalisanData(
        context.read<LoginCubit>().userfirmId,
        context.read<LoginCubit>().token,
        context.read<LoginCubit>().id);
    setForCase(true, leaderIds, personeller);
  }

  Future<void> setIdFromGroupUserToName(List<String> userIds) async {
    List<PersonelDDModel> personeller = await userfirmCalisanData(
        context.read<LoginCubit>().userfirmId,
        context.read<LoginCubit>().token,
        context.read<LoginCubit>().id);
    setForCase(false, userIds, personeller);
  }

  void setForCase(bool isLeader, List<String> leaderIds,
      List<PersonelDDModel> personeller) {
    for (var item in personeller) {
      for (int i = 0; i < leaderIds.length; i++) {
        if (item.id == leaderIds[i]) {
          isLeader
              ? context
                  .read<MessageCubit>()
                  .secilenGrupYoneticileriAdlar
                  .add('${item.firstName} ${item.lastName}')
              : context
                  .read<MessageCubit>()
                  .secilenGrupKullanicilariAdlar
                  .add('${item.firstName} ${item.lastName}');
        }
      }
    }
  }

  void showMultiSelectLeaderEmployee() async {
    final List<String> items = [];
    final List<String>? results = await showDialog(
      context: context,
      builder: (BuildContext context) {
        return GroupLeaderMultiSelect(
          items: items,
        );
      },
    );

    if (results != null) {
      setState(() {
        secilenGrupYoneticiList = results;
        List<int> personelYoneticiIdler = secilenGrupYoneticiList
            .where((eleman) => int.tryParse(eleman) != null)
            .map((eleman) => int.parse(eleman))
            .toSet()
            .toList();
        gonderilecekGrupYoneticiIdler = personelYoneticiIdler.join(',');
      });
    }
  }

  void showMultiSelectUserEmployee() async {
    final List<String> items = [];

    final List<String>? results = await showDialog(
      context: context,
      builder: (BuildContext context) {
        return GroupUserMultiSelect(items: items);
      },
    );

    if (results != null) {
      setState(() {
        secilenGrupKullaniciList = results;
        List<int> personelIdler = secilenGrupKullaniciList
            .where((eleman) => int.tryParse(eleman) != null)
            .map((eleman) => int.parse(eleman))
            .toSet()
            .toList();
        gonderilecekGrupKullaniciIdler = personelIdler.join(',');
      });
    }
  }

  /// - Update Group Method
  void updateNewGroup() async {
    /// - Herhangi bir boş değer yok ise bu adımı atlayacak var ise aşağıdaki işlemlere geçmeyecek ve kullanıcıya boş alanlar doldurulmalı mesajı gösterilecek
    final String sendNewGroupLeadersId =
        context.read<MessageCubit>().secilenGrupYoneticileriIdler.join(',');
    final String sendNewGroupUsersId =
        context.read<MessageCubit>().secilenGrupKullanicilariIdler.join(',');
    if (groupNameController.text.isEmpty ||
        sendNewGroupLeadersId.isEmpty ||
        sendNewGroupUsersId.isEmpty) {
      return ToastManager.instance
          .toastMessageService("Boş Alanlar Doldurulmalı !");
    }

    /// - Model'in içi dolduruluyor

    final ReqUpdateGroup updateGroupModel = ReqUpdateGroup(
      grupId: widget.group.grupId ?? "0",
      grupAd: _groupNameController.text,
      yeniGrupKullanicilari: sendNewGroupUsersId,
      yeniGrupYoneticileri: sendNewGroupLeadersId,
      loginuserid: context.read<LoginCubit>().id,
      token: context.read<LoginCubit>().token,
      userfirmid: context.read<LoginCubit>().userfirmId,
    );

    /// - Model dolduruldu mu diye log atıldı

    'grupAd : ${updateGroupModel.grupAd}'.log();
    'grupKullanicilari : $sendNewGroupUsersId'.log();
    'grupYoneticileri : $sendNewGroupLeadersId'.log();

    // Düzenleme yaparken fazladan aynı kişilerin id'si gönderiliyor burasını tekrar test et
    // UI tarafında toSet ile idler'i kontrol ederek tekrardan deneme yap
    // Sorunun temel nedenini araştır
    // API tarafında dışarıdan parametre olarak aynı idler gönderilmiş ise de kontrol edilerek tek id'ye düşürülmeli.

    /// - Burada grup güncelleme servisine model gönderilecek ve grup güncellenecek aksi durumlar kontrol edilip ekrana ona göre toast mesaj gösterilecek
    /// - value yani dönen değer true ise işlem başarılı - değil ise toast göster hatalı diye

    try {
      bool isSuccess = await widget.cubit.updateMultiGroup(updateGroupModel);
      if (!mounted) return;
      navigateToMainMessageView(isSuccess, context);
    } catch (error) {
      ToastManager.instance.toastMessageService('Grup Güncellenemedi !');
    }
  }

  void navigateToMainMessageView(bool isComplete, BuildContext context) async {
    /// - Burada servisten gelen model gönderilerek ana sayfaya gönderilecek ve güncellendiğine dair mesaj gösterelim.

    if (isComplete == false) {
      return ToastManager.instance.toastMessageService('Grup Güncellenemedi !');
    }

    ToastManager.instance
        .toastMessageService("Grup Güncellendi !")
        .then((value) => Future.delayed(
              const Duration(milliseconds: 1600),
              () {
                Navigator.of(context).pushAndRemoveUntil(
                    MaterialPageRoute(builder: (context) => HomeCustom()),
                    (route) => false);
              },
            ));
  }
}
