import 'dart:developer';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:hmg_qline/constants/app_constants.dart';
import 'package:hmg_qline/models/global_config_model.dart';
import 'package:hmg_qline/models/ticket_model.dart';
import 'package:hmg_qline/utilities/enums.dart';
import 'package:hmg_qline/utilities/extensions.dart';

abstract class TextToSpeechService {
  Future<void> speechText({
    required TicketDetailsModel ticket,
    required GlobalConfigurationsModel globalConfigurationsModel,
    bool isMute = false,
  });

  Future<void> speechTextTest(String test);

  void listenToTextToSpeechEvents({required Function() onVoiceCompleted});
}

class TextToSpeechServiceImp implements TextToSpeechService {
  FlutterTts textToSpeechInstance;

  TextToSpeechServiceImp({required this.textToSpeechInstance});

  double volume = 1.0;
  double pitch = 0.6;
  double rate = 0.2;

  @override
  Future<void> speechTextTest(String test) async {
    log("lang: ${await textToSpeechInstance.areLanguagesInstalled(["en", "ar"])}");
    log("getDefaultEngine: ${await textToSpeechInstance.getDefaultEngine}");
    log("getEngines: ${await textToSpeechInstance.getEngines}");

    // await textToSpeechInstance.setLanguage(LanguageEnum.arabic.enumToString());
    // textToSpeechInstance.setSpeechRate(0.45);
    // textToSpeechInstance.setPitch(0.9);

    await textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString());
    textToSpeechInstance.setSpeechRate(0.37);
    textToSpeechInstance.setPitch(0.85);

    await textToSpeechInstance.speak(test);
  }

  @override
  Future<void> speechText({
    required TicketDetailsModel ticket,
    required GlobalConfigurationsModel globalConfigurationsModel,
    bool isMute = false,
  }) async {
    const ttsGoogleEngine = 'com.google.android.tts';
    LanguageEnum langEnum = ticket.ticketModel!.voiceLanguageEnum;
    List engines = await textToSpeechInstance.getEngines;
    if (engines.contains(ttsGoogleEngine)) {
      await textToSpeechInstance.setEngine(ttsGoogleEngine);
    }

    if (isMute) {
      textToSpeechInstance.setVolume(0.0);
    } else {
      textToSpeechInstance.setVolume(1.0);
    }
    if (langEnum == LanguageEnum.arabic) {
      await textToSpeechInstance.setLanguage(LanguageEnum.arabic.enumToString());
      textToSpeechInstance.setSpeechRate(0.45);
      textToSpeechInstance.setPitch(0.9);
    } else if (langEnum == LanguageEnum.english) {
      await textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString());
      textToSpeechInstance.setSpeechRate(0.37);
      textToSpeechInstance.setPitch(0.85);
    }
    String preVoice = ticket.ticketModel!.ticketNoText;
    String postVoice = '';
    if (globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment) {
      postVoice = ticket.ticketModel!.callTypeEnum.getCallTextFromCallType(ticket.ticketModel!);
    } else {
      postVoice = ticket.ticketModel!.postVoiceText;
    }
    String roomNo = '';
    if (globalConfigurationsModel.qTypeEnum != QTypeEnum.appointment && ticket.ticketModel!.roomNo != null && ticket.ticketModel!.roomNo!.isNotEmpty) {
      roomNo = ".. ${ticket.ticketModel!.roomNo.toString()}";
    }

    if (preVoice.isNotEmpty) {
      preVoice = '$preVoice..';
    }

    String ticketNo = ticket.ticketModel!.queueNo!.trim().toString();

    // log("lang: ${await textToSpeechInstance.areLanguagesInstalled(["en", "ar"])}");
    // log("getDefaultEngine: ${await textToSpeechInstance.getDefaultEngine}");
    // log("getEngines: ${await textToSpeechInstance.getEngines}");
    log("lang: $langEnum");
    log("preVoice: $preVoice");
    log("postVoice: $postVoice");
    log("ticketNo: $ticketNo");

    String patientAlpha = "";
    String patientNumeric = "";
    String clinicName = "";

    bool isClinicNameAdded = (ticket.ticketModel?.queueNo != ticket.ticketModel?.callNoStr);

    if (isClinicNameAdded) {
      var queueNo = "";
      var clinic = ticketNo.split(" ");
      if (clinic.length > 1) {
        clinicName = clinic[0];
        queueNo = clinic[1];
      } else {
        queueNo = ticketNo;
      }

      var queueNoArray = queueNo.split("-");
      if (queueNoArray.length > 2) {
        patientAlpha = "${queueNoArray[0]} .. ${queueNoArray[1]}";
        patientNumeric = queueNoArray[2];
      } else {
        patientAlpha = queueNoArray[0];
        patientNumeric = queueNoArray[1];
      }
    } else {
      var queueNoArray = ticketNo.split("-");
      if (queueNoArray.length > 2) {
        patientAlpha = "${queueNoArray[0]} .. ${queueNoArray[1]}";
        patientNumeric = queueNoArray[2];
      } else {
        patientAlpha = queueNoArray[0];
        patientNumeric = queueNoArray[1];
      }
    }

    patientAlpha = patientAlpha.split('').join(' .. ');

    if (langEnum == LanguageEnum.english) {
      await textToSpeechInstance.speak("$preVoice .. $clinicName .. $patientAlpha .. $patientNumeric .. $postVoice $roomNo");
      return;
    }

    if (isNeedToBreakVoiceForArabic) {
      await textToSpeechInstance.awaitSpeakCompletion(true);

      isSpeechCompleted = false;
      if (preVoice.isNotEmpty) {
        await textToSpeechInstance.speak("$preVoice ");
      }
      textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString());
      await textToSpeechInstance.speak("$patientAlpha .. $patientNumeric");
      textToSpeechInstance.setLanguage(langEnum.enumToString());
      // await textToSpeechInstance.speak(postVoice);
      // textToSpeechInstance.setLanguage(LanguageEnum.english.enumToString());
      await textToSpeechInstance.speak("$postVoice $roomNo").whenComplete(() {
        isSpeechCompleted = true;
      });
    } else {
      await textToSpeechInstance.speak("$preVoice .. $clinicName .. $patientAlpha .. $patientNumeric .. $postVoice $roomNo");
    }
  }

  @override
  void listenToTextToSpeechEvents({required Function() onVoiceCompleted}) {
    textToSpeechInstance.setCompletionHandler(onVoiceCompleted);
  }
}
