import 'dart:convert';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_callkit_incoming/entities/entities.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:logger/logger.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as ALM;
import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart';
import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:path_provider/path_provider.dart';
import 'package:signalr_netcore/hub_connection.dart';
import 'package:signalr_netcore/signalr_client.dart';

class ChatVoipCall {
  static final ChatVoipCall _instance = ChatVoipCall._internal();

  ChatVoipCall._internal();

  factory ChatVoipCall() => _instance;

  late ChatProviderModel prov;
  late ChatCallProvider cProv;
  dynamic inCallData;
  bool isUserOnline = false;
  dynamic callData;
  static const platform = MethodChannel('com.example.httpchannel/http');

  Future<void> showCallkitIncoming({required String uuid, RemoteMessage? data, CallDataModel? incomingCallData, bool background = false}) async {
    await FlutterCallkitIncoming.endAllCalls();
    ALM.Response autoLoginData;
    SingleUserChatModel callerData;
    if (data!.data["user_token_response"] == null || data.data["user_token_response"].isEmpty) {
      // Online & App Logged In
      ALM.Response sharedDetails = ALM.Response.fromJson(jsonDecode(await Utils.getStringFromPrefs("userLoginChatDetails")));
      autoLoginData = ALM.Response.fromJson(AppState().getchatUserDetails == null ? sharedDetails.toJson() : AppState().getchatUserDetails!.response!.toJson());
      dynamic items = jsonDecode(data.data["user_chat_history_response"]);
      callerData = SingleUserChatModel(
          targetUserId: items["CurrentUserId"],
          targetUserEmail: items["CurrentUserEmail"],
          targetUserName: items["CurrentUserName"].split("@").first,
          currentUserId: autoLoginData.id,
          currentUserEmail: autoLoginData.email,
          currentUserName: autoLoginData.userName,
          chatEventId: 3);
      isUserOnline = true;
    } else {
      // Offline or App in Background or App is At Verify Screen
      autoLoginData = ALM.Response.fromJson(jsonDecode(data.data["user_token_response"]));
      callerData = SingleUserChatModel.fromJson(json.decode(data.data["user_chat_history_response"]));
    }
    CallKitParams params = CallKitParams(
      id: uuid,
      nameCaller: callerData.targetUserName,
      appName: 'Mohemm',
      handle: '',
      type: 0,
      duration: 20000,
      textAccept: 'Accept',
      textDecline: 'Decline',
      extra: {
        "loginDetails": autoLoginData.toJson(),
        "callerDetails": callerData.toJson(),
        'isIncomingCall': true,
        'isUserOnline': isUserOnline,
        'callType': data.data["callType"],
      },
      android: const AndroidParams(
        isCustomNotification: true,
        isShowLogo: false,
        ringtonePath: 'system_ringtone_default',
        backgroundColor: '#0955fa',
        backgroundUrl: 'assets/test.png',
        actionColor: '#4CAF50',
      ),
      ios: IOSParams(
        iconName: 'Mohemm',
        handleType: '',
        supportsVideo: true,
        maximumCallGroups: 2,
        maximumCallsPerCallGroup: 1,
        audioSessionMode: 'default',
        audioSessionActive: true,
        audioSessionPreferredSampleRate: 38000.0,
        audioSessionPreferredIOBufferDuration: 0.005,
        supportsDTMF: true,
        supportsHolding: true,
        supportsGrouping: false,
        supportsUngrouping: false,
        ringtonePath: 'system_ringtone_default',
      ),
    );
    if (callerData.chatEventId == 3) {
      await Utils.saveStringFromPrefs("isIncomingCall", "true");
      await FlutterCallkitIncoming.showCallkitIncoming(params);
    }
  }

  Future<void> declineCall({  payload}) async {
    IncomingCallModel data = IncomingCallModel.fromJson(jsonDecode(payload));

    if (isUserOnline) {
      HubConnection _hc = await makeHub(sessionData: data);
      await _hc.start();
      if (_hc.state == HubConnectionState.Connected) {
        if (data.extra != null) {
          await _hc.invoke("HangUpAsync", args: [data.extra!.callerDetails!.currentUserId!, data.extra!.callerDetails!.targetUserId!]);
          await _hc.invoke("UpdateUserStatusAsync", args: [int.parse(data.extra!.callerDetails!.currentUserId.toString()), 1]);
          FlutterCallkitIncoming.endAllCalls();
          chatHubConnection = _hc;
        }
      }
    } 
      //else {
      // Future.delayed(const Duration(seconds: 3), () {
      //   ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!);
      // });
      // HubConnection _hc = await makeHub(sessionData: data);
      // await _hc.start();
      // if (_hc.state == HubConnectionState.Connected) {
      //   logger.log(Level.info, "HUB-EVENT");
      //   await _hc.invoke("HangUpAsync", args: [
      //     data.extra!.callerDetails!.currentUserId!,
      //     data.extra!.callerDetails!.targetUserId!,
      //   ]);
      //   FlutterCallkitIncoming.endAllCalls();
      //   await _hc.stop();
      // }
      // }

      //
      // try {
      //   var response = await platform.invokeMethod(
      //       'executeHttpPostRequest', {"currentUserID": data.extra!.callerDetails!.targetUserId, "targetUserID": data.extra!.callerDetails!.currentUserId, "token": data.extra!.loginDetails!.token});
      //   print('HTTP POST response: $response');
      //   Future.delayed(Duration(seconds: 3), () {
      //     ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!);
      //   });
      // } on PlatformException catch (e) {
      //   print('Error invoking method: ${e.message}');
      // }

      //await ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!);
      // logger.log(Level.error, "API-EVENT-END");
  }
  
  Future<void> voipDeclineCall(IosCallPayload? _iosCallPayload ) async {
    try {
      ALM.UserAutoLoginModel model = await ChatApiClient().getUserCallToken(userid: _iosCallPayload!.incomingCallReciverId.toString());
      dynamic Res = await ChatApiClient().callDecline(cUserID: int.parse(_iosCallPayload!.incomingCallerId!), tUserID: int.parse(_iosCallPayload!.incomingCallReciverId.toString()), targetUsertoken: model.response!.token!);
    } catch (err) {
      print(err);
    }
  }

  Future<HubConnection> makeHub({required IncomingCallModel sessionData}) async {
    late HubConnection hc;
    try {
      HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
      hc = HubConnectionBuilder()
          .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${sessionData.extra!.loginDetails!.id}&source=Desktop&access_token=${sessionData.extra?.loginDetails!.token}", options: httpOp)
          .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
      return hc;
    } catch (e) {
      print(e);
      return hc;
    }
  }
}

