import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:easy_localization/easy_localization.dart';
import 'package:http/http.dart' as http;
import 'package:device_info_plus/device_info_plus.dart';
import 'package:mohem_flutter_app/api/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/date_uitl.dart';
import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
import 'package:mohem_flutter_app/models/dashboard/list_menu.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/itg/itg_main_response.dart';
import 'package:mohem_flutter_app/models/itg/itg_response_model.dart';
import 'package:mohem_flutter_app/models/sso_auth_model.dart';
import 'package:platform_device_id_plus/platform_device_id.dart';
// import 'package:platform_device_id/platform_device_id.dart';

// import 'package:platform_device_id/platform_device_id.dart';
import 'package:uuid/uuid.dart';

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

  DashboardApiClient._internal();

  factory DashboardApiClient() => _instance;

  Future<GetAttendanceTracking?> getAttendanceTracking() async {
    String url = "${ApiConsts.erpRest}GET_Attendance_Tracking";
    Map<String, dynamic> postParams = {};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData.getAttendanceTrackingList;
      },
      url,
      postParams,
    );
  }

  Future<GenericResponseModel?> getOpenNotifications() async {
    String url = "${ApiConsts.erpRest}GET_OPEN_NOTIFICATIONS";
    Map<String, dynamic> postParams = {};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<GenericResponseModel?> getCOCNotifications() async {
    String url = "${ApiConsts.cocRest}Mohemm_ITG_ReviewerAdmin_Pending_Tasks";
    Map<String, dynamic> postParams = {"Date": DateUtil.getISODateFormat(DateTime.now()), "EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<ItgFormsModel?> getItgFormsPendingTask() async {
    String url = "${ApiConsts.cocRest}ITGFormsPendingTasks";
    Map<String, dynamic> postParams = {};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        ItgFormsModel responseData = ItgFormsModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<List<GetAccrualBalancesList>> getAccrualBalances(String effectiveDate, {String? empID}) async {
    String url = "${ApiConsts.erpRest}GET_ACCRUAL_BALANCES";
    Map<String, dynamic> postParams = {"P_EFFECTIVE_DATE": effectiveDate};
    postParams.addAll(AppState().postParamsJson);
    if (empID != null) postParams["P_SELECTED_EMPLOYEE_NUMBER"] = empID;
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData.getAccrualBalancesList ?? [];
      },
      url,
      postParams,
    );
  }

  Future<GenericResponseModel?> getOpenMissingSwipes() async {
    String url = "${ApiConsts.erpRest}GET_OPEN_MISSING_SWIPES";
    Map<String, dynamic> postParams = {};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  //Menus List
  Future<List<ListMenu>> getListMenu() async {
    String url = "${ApiConsts.erpRest}GET_MENU";
    Map<String, dynamic> postParams = {};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData.listMenu ?? [];
      },
      url,
      postParams,
    );
  }

  //GET_MENU_ENTRIES
  Future<GenericResponseModel?> getGetMenuEntries() async {
    String url = "${ApiConsts.erpRest}GET_MENU_ENTRIES";
    Map<String, dynamic> postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E"};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<GenericResponseModel?> getEventActivity() async {
    String url = "${ApiConsts.erpRest}Get_EventActivity";
    Map<String, dynamic> postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E"};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<GenericResponseModel?> getTicketBookingRedirection() async {
    String url = "${ApiConsts.erpRest}GET_PORTAL_REDIRECTION";
    Map<String, dynamic> postParams = {"P_USER_NAME": AppState().memberInformationList?.eMPLOYEENUMBER};
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<SSOAuthModel?> getBookingSSOAuthRedirection({required String clientID}) async {
    String url = "${ApiConsts.ssoAuthRedirection}?grantType=mohemm";
    //https://sso-uat.hmg.com/api/auth/connect?grantType=mohemm'
    // Map<String, dynamic> postParams = {"P_USER_NAME": AppState().memberInformationList?.eMPLOYEENUMBER};
    Map<String, dynamic> postParams = {
      "ClientId": clientID,
      // "ClientId": "a9f4d1a0596d4aea8f830992ec4bdac1",
      "PersonId": AppState().memberInformationList?.eMPLOYEENUMBER,
      "Username": AppState().memberInformationList?.eMPLOYEENUMBER,
      "Language": "US",
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        SSOAuthModel responseData = SSOAuthModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<dynamic> getBookingSSOFinalRedirection({required String token}) async {
    token = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjhjZTE2OWM0YjIwYjQ2ZWM5YTQyOTU3Y2ZhODUzNzQ1IiwidHlwIjoiSldUIn0.eyJ0ZW5hbnRfaWQiOiJhOWY0ZDFhMDU5NmQ0YWVhOGY4MzA5OTJlYzRiZGFjMSIsImVpZCI6IjExNzkzMCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL3NpZCI6Ijk2MDI0OGM1NzA3YzQ3MmFhYTEzM2I1N2ZhODE1ZmVhIiwibGFuZ3VhZ2UiOiJVUyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6IjExNzkzMEBobWcuY29tIiwiZXhwIjoxNzgyNDc1NzY5LCJpc3MiOiJodHRwczovL3Nzby11YXQuaG1nLmNvbSIsImF1ZCI6ImE5ZjRkMWEwNTk2ZDRhZWE4ZjgzMDk5MmVjNGJkYWMxIn0.rJcLVsG8D0XECyLERCTD2uqGeWyvp-OBVGE9uL2qKrX4etFUHgdFt_5kYF6edFTtGy-0PIZadHDmv7e-IOhVWHm5HVMClaukiXoRXR8cDN8XA1wfme3Kd-U5PXN-IRh49AyRTzLO0rYNPvH81ScosWGlsFSkOvA-0hJNa2adHdtvgNvB8wJshSU5p7sAmF8mjdDY6aInG19etu2iEuUDwHHA4ZY_ts4hboHo8fE392hFaYGonExoD7bpW5RMx5xKWeRCmWpG_PK8Aw_z1jGzdB9PANus4pteRGuln1J-kmo2lQC9pVrSyZATAKp1HfgfyZ_vUhaHEfM69cMWaCslJQ";
    var request = http.MultipartRequest('POST', Uri.parse('https://ek.techmaster.in/SSO/HMG'));
    request.fields.addAll({'JWTToken': token});

    // request.headers.addAll(headers);

    http.StreamedResponse response = await request.send();
    if (response.statusCode == 302) {
      print("================== post ==========");
      var res = await response.stream.bytesToString();
      return response.headers["location"];
    } else {
      print(response.reasonPhrase);
    }
  }

  //Mark Attendance
  Future<GenericResponseModel?> markAttendance({
    String lat = "0",
    String? long = "0",
    required int pointType,
    String nfcValue = "",
    bool isGpsRequired = false,
    String QRValue = "",
    String payrollCode = "",
  }) async {
    String url = "${ApiConsts.swpRest}AuthenticateAndSwipeUserSupportNFC";
    var uuid = Uuid();
    String? deviceId = "";
    // Generate a v4 (random) id
    if (Platform.isAndroid) {
      AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
      deviceId = androidInfo.id;
    } else if (Platform.isIOS) {
      IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo;
      deviceId = iosInfo.identifierForVendor;
    }
    Map<String, dynamic> postParams = {
      "UID": deviceId, //uuid.v4(), //Mobile Id
      // "UID": uuid.v4(), //Mobile Id
      "Latitude": lat,
      "Longitude": long,
      "QRValue": QRValue,
      "PointType": pointType, // NFC=2, Wifi = 3, QR= 1,
      "NFCValue": nfcValue,
      "WifiValue": pointType == 3 ? "100" : "",
      "IsGpsRequired": isGpsRequired,
      "PayrollCodeStr": AppState().postParamsObject?.payrollCodeStr.toString() ?? "",
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  //Mark Fake Location
  Future<GenericResponseModel?> markFakeLocation({String lat = "0", String? long = "0", required String sourceName}) async {
    String url = "${ApiConsts.swpRest}CreateIssueInfo";
    var uuid = Uuid();
    // Generate a v4 (random) id

    Map<String, dynamic> postParams = {
      "UID": uuid.v4(), //Mobile Id
      "Latitude": lat,
      "Longitude": long,
      "QRValue": '',
      "NFCValue": sourceName == 'NFC' ? sourceName : '',
      "WifiValue": sourceName == 'WIFI' ? sourceName : '',
      "EmployeeID": AppState().memberInformationList!.eMPLOYEENUMBER,
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  //Check ITG Type
  Future<MohemmItgResponseItem?> getITGPageNotification() async {
    String url = "${ApiConsts.cocRest}Mohemm_ITG_GetPageNotification";

    Map<String, dynamic> postParams = {
      "EmployeeNumber": AppState().getUserName,
      "ItgEnableAt": "After Service Submission", //Mobile Id
      "ItgServiceName": "Login",
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        GenericResponseModel responseData = GenericResponseModel.fromJson(json);
        MohemmItgResponseItem res = MohemmItgResponseItem.fromJson(jsonDecode(responseData.mohemmITGResponseItem ?? ""));
        // var jsonDecodedData = jsonDecode(jsonDecode(responseData.mohemmITGResponseItem!)['result']['data']);
        return res;
      },
      url,
      postParams,
    );
  }

  //Submit ITG
  Future<ItgMainRes?> submitItgForm({required String comment, required String masterId, required List<Map<String, dynamic>> itgList, required int serviceId}) async {
    String url = "${ApiConsts.cocRest}Mohemm_ITG_Survey_Response";

    Map<String, dynamic> postParams = {
      "EmployeeNumber": AppState().getUserName,
      "ItgComments": comment,
      "ItgNotificationMasterId": masterId,
      "ItgQuestionResponses": itgList,
      "ItgSurveyId": serviceId,
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        ItgMainRes responseData = ItgMainRes.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future<ItgMainRes?> getAdvertisementDetail(String masterID) async {
    String url = "${ApiConsts.cocRest}Mohemm_ITG_GetPageNotificationDetails";

    Map<String, dynamic> postParams = {
      "EmployeeNumber": AppState().getUserName,
      "ItgNotificationMasterId": masterID, //Mobile Id
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        ItgMainRes responseData = ItgMainRes.fromJson(json);
        return responseData;
      },
      url,
      postParams,
    );
  }

  Future setAdvertisementViewed(String masterID, int advertisementId, String? ackValue) async {
    String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed";

    Map<String, dynamic> postParams = {
      "ItgNotificationMasterId": masterID,
      "EmployeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
      "ItgAdvertisementId": advertisementId,
      "ItgAcknowledgment": ackValue,
      // "ItgAdvertisement": {"ItgAdvertisementId": advertisementId, "ItgAcknowledgment": ackValue} //Mobile Id
    };
    postParams.addAll(AppState().postParamsJson);
    return await ApiClient().postJsonForObject(
      (json) {
        // ItgMainRes responseData = ItgMainRes.fromJson(json);
        return json;
      },
      url,
      postParams,
    );
  }

  // Future<dynamic?> getItgTimeCardDetails() async {
  //   String url = "${ApiConsts.cocRest}ITG_TimeCard_Get";
  //   Map<String, dynamic> postParams = {};
  //   postParams.addAll(AppState().postParamsJson);
  //   return await ApiClient().postJsonForObject(
  //     (json) {
  //       ItgTimeCardModel responseData = ItgTimeCardModel.fromJson(json);
  //       return responseData;
  //     },
  //     url,
  //     postParams,
  //   );
  // }
}
