import 'dart:convert';

import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart';
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'dart:io' show Platform;

import '../UpdatePage.dart';

DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
Helpers helpers = new Helpers();

class BaseAppClient {
  //TODO change the post fun to nun static when you change all service
  post(String endPoint,
      {Map<String, dynamic> body,
      Function(dynamic response, int statusCode) onSuccess,
      Function(String error, int statusCode) onFailure,
      bool isAllowAny = false}) async {
    String url = BASE_URL + endPoint;
    try {
      Map profile = await sharedPref.getObj(DOCTOR_PROFILE);
      String token = await sharedPref.getString(TOKEN);
      if (profile != null) {
        DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile);
        if (body['DoctorID'] == null)
          body['DoctorID'] = doctorProfile?.doctorID;
        if (body['DoctorID'] == "") body['DoctorID'] = null;
        if (body['EditedBy'] == null)
          body['EditedBy'] = doctorProfile?.doctorID;
        if (body['ProjectID'] == null) {
          body['ProjectID'] = doctorProfile?.projectID;
        }
        if (body['ClinicID'] == null)
          body['ClinicID'] = doctorProfile?.clinicID;
      }
      if (body['DoctorID'] == '') {
        body['DoctorID'] = null;
      }
      if (body['EditedBy'] == '') {
        body.remove("EditedBy");
      }
      body['TokenID'] = token ?? '';
      String lang = await sharedPref.getString(APP_Language);
      if (lang != null && lang == 'ar')
        body['LanguageID'] = 1;
      else
        body['LanguageID'] = 2;

      body['stamp'] = STAMP;
      // if(!body.containsKey("IPAdress"))
      body['IPAdress'] = IP_ADDRESS;
      body['VersionID'] = VERSION_ID;
      body['Channel'] = CHANNEL;
      body['SessionID'] = SESSION_ID;
      body['IsLoginForDoctorApp'] = IS_LOGIN_FOR_DOCTOR_APP;
      body['PatientOutSA'] = body['PatientOutSA'] ?? 0; // PATIENT_OUT_SA;
      if (body['VidaAuthTokenID'] == null) {
        body['VidaAuthTokenID'] =
            await sharedPref.getString(VIDA_AUTH_TOKEN_ID);
      }
      if (body['VidaRefreshTokenID'] == null) {
        body['VidaRefreshTokenID'] =
            await sharedPref.getString(VIDA_REFRESH_TOKEN_ID);
      }

      print("URL : $url");
      print("Body : ${json.encode(body)}");
      var asd = json.encode(body);
      var asd2;
      if (await Helpers.checkConnection()) {
        final response = await http.post(url,
            body: json.encode(body),
            headers: {
              'Content-Type': 'application/json',
              'Accept': 'application/json'
            });
        final int statusCode = response.statusCode;
        if (statusCode < 200 || statusCode >= 400) {
          onFailure(Helpers.generateContactAdminMsg(), statusCode);
        } else {
          var parsed = json.decode(response.body.toString());

          if (parsed['ErrorType'] == 4) {
            helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'],
                parsed['AndroidLink'], parsed['IOSLink']);
          }

          if (!parsed['IsAuthenticated']) {
            if (body['OTP_SendType'] != null) {
              onFailure(getError(parsed), statusCode);
            } else if (!isAllowAny) {
              await Helpers.logout();
              Helpers.showErrorToast('Your session expired Please login agian');
            }
            if (isAllowAny) {
              onFailure(getError(parsed), statusCode);
            }
          } else if (parsed['MessageStatus'] == 1) {
            if (!parsed['IsAuthenticated'])
              onFailure(getError(parsed), statusCode);
            else
              onSuccess(parsed, statusCode);
          } else {
            onFailure(getError(parsed), statusCode);
          }
        }
      } else {
        onFailure('Please Check The Internet Connection', -1);
      }
    } catch (e) {
      print(e);
      onFailure(e.toString(), -1);
    }
  }

  postPatient(String endPoint,
      {Map<String, dynamic> body,
      Function(dynamic response, int statusCode) onSuccess,
      Function(String error, int statusCode) onFailure,
      @required PatiantInformtion patient,
      bool isExternal = false}) async {
    String url = BASE_URL + endPoint;

    try {
      Map<String, String> headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      };

      String token = await sharedPref.getString(TOKEN);
      var languageID =
          await sharedPref.getStringWithDefaultValue(APP_Language, 'en');
      if (body.containsKey('SetupID')) {
        body['SetupID'] = body.containsKey('SetupID')
            ? body['SetupID'] != null
                ? body['SetupID']
                : SETUP_ID
            : SETUP_ID;
      }

      body['VersionID'] = 6.3;
      body['Channel'] = CHANNEL;
      body['LanguageID'] = languageID == 'ar' ? 1 : 2;

      body['IPAdress'] = IP_ADDRESS;
      body['generalid'] = GENERAL_ID;
      body['PatientOutSA'] = body.containsKey('PatientOutSA')
          ? body['PatientOutSA'] != null
              ? body['PatientOutSA']
              : PATIENT_OUT_SA_PATIENT_REQ
          : PATIENT_OUT_SA_PATIENT_REQ;

      if (body.containsKey('isDentalAllowedBackend')) {
        body['isDentalAllowedBackend'] =
            body.containsKey('isDentalAllowedBackend')
                ? body['isDentalAllowedBackend'] != null
                    ? body['isDentalAllowedBackend']
                    : IS_DENTAL_ALLOWED_BACKEND
                : IS_DENTAL_ALLOWED_BACKEND;
      }

      body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2;

      body['PatientType'] = body.containsKey('PatientType')
          ? body['PatientType'] != null
              ? body['PatientType']
              : patient.patientType != null
                  ? patient.patientType
                  : PATIENT_TYPE
          : PATIENT_TYPE;

      body['PatientTypeID'] = body.containsKey('PatientTypeID')
          ? body['PatientTypeID'] != null
              ? body['PatientTypeID']
              : patient.patientType != null
                  ? patient.patientType
                  : PATIENT_TYPE_ID
          : PATIENT_TYPE_ID;

      body['TokenID'] = token;
      body['PatientID'] = body['PatientID'] != null
          ? body['PatientID']
          : patient.patientId ?? patient.patientMRN;

      body['PatientOutSA'] = 0; //user['OutSA']; //TODO change it
      body['SessionID'] = SESSION_ID; //getSe

      print("URL : $url");
      print("Body : ${json.encode(body)}");

      if (await Helpers.checkConnection()) {
        final response = await http.post(url.trim(),
            body: json.encode(body), headers: headers);
        final int statusCode = response.statusCode;
        print("statusCode :$statusCode");
        if (statusCode < 200 || statusCode >= 400 || json == null) {
          onFailure('Error While Fetching data', statusCode);
        } else {
          // var parsed = json.decode(response.body.toString());
          var parsed = json.decode(utf8.decode(response.bodyBytes));
          if (parsed['Response_Message'] != null) {
            onSuccess(parsed, statusCode);
          } else {
            if (parsed['ErrorType'] == 4) {
              helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'],
                  parsed['AndroidLink'], parsed['IOSLink']);
            }
            if (parsed['IsAuthenticated'] == null) {
              if (parsed['isSMSSent'] == true) {
                onSuccess(parsed, statusCode);
              } else if (parsed['MessageStatus'] == 1) {
                onSuccess(parsed, statusCode);
              } else if (parsed['Result'] == 'OK') {
                onSuccess(parsed, statusCode);
              } else {
                if (parsed != null) {
                  onSuccess(parsed, statusCode);
                } else {
                  onFailure(getError(parsed), statusCode);
                }
              }
            } else if (parsed['MessageStatus'] == 1 ||
                parsed['SMSLoginRequired'] == true) {
              onSuccess(parsed, statusCode);
            } else if (parsed['MessageStatus'] == 2 &&
                parsed['IsAuthenticated']) {
              if (parsed['SameClinicApptList'] != null) {
                onSuccess(parsed, statusCode);
              } else {
                if (parsed['message'] == null &&
                    parsed['ErrorEndUserMessage'] == null) {
                  if (parsed['ErrorSearchMsg'] == null) {
                    onFailure("Server Error found with no available message",
                        statusCode);
                  } else {
                    onFailure(parsed['ErrorSearchMsg'], statusCode);
                  }
                } else {
                  onFailure(
                      parsed['message'] ??
                          parsed['ErrorEndUserMessage'] ??
                          parsed['ErrorMessage'],
                      statusCode);
                }
              }
            } else {
              if (parsed['SameClinicApptList'] != null) {
                onSuccess(parsed, statusCode);
              } else {
                if (parsed['message'] != null) {
                  onFailure(parsed['message'] ?? parsed['message'], statusCode);
                } else {
                  onFailure(
                      parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
                      statusCode);
                }
              }
            }
          }
        }
      } else {
        onFailure('Please Check The Internet Connection', -1);
      }
    } catch (e) {
      print(e);
      onFailure(e.toString(), -1);
    }
  }

  String getError(parsed) {
    //TODO change this fun
    String error = parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'];
    if (parsed["ValidationErrors"] != null) {
      error = parsed["ValidationErrors"]["StatusMessage"].toString() + "\n";

      if (parsed["ValidationErrors"]["ValidationErrors"] != null &&
          parsed["ValidationErrors"]["ValidationErrors"].length != 0) {
        for (var i = 0;
            i < parsed["ValidationErrors"]["ValidationErrors"].length;
            i++) {
          error = error +
              parsed["ValidationErrors"]["ValidationErrors"][i]["Messages"][0] +
              "\n";
        }
      }
    }
    if (error == null || error == "null" || error == "null\n") {
      return Helpers.generateContactAdminMsg();
    }
    return error;
  }
}
