import 'dart:io';
import 'package:mypoint_flutter_app/configs/api_paths.dart';
import 'package:mypoint_flutter_app/base/base_response_model.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/networking/restful_api.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import '../configs/device_info.dart';
import '../model/auth/biometric_register_response_model.dart';
import '../model/auth/login_token_response_model.dart';
import '../model/auth/profile_response_model.dart';
import '../model/update_response_model.dart';
import '../preference/point/header_home_model.dart';
import '../screen/faqs/faqs_model.dart';
import '../screen/onboarding/model/check_phone_response_model.dart';
import '../screen/onboarding/model/onboarding_info_model.dart';
import '../screen/otp/model/create_otp_response_model.dart';
import '../screen/otp/model/otp_verify_response_model.dart';
import '../screen/pageDetail/model/campaign_detail_model.dart';
import '../screen/pageDetail/model/detail_page_rule_type.dart';
import '../screen/splash/splash_screen_viewmodel.dart';
import 'model_maker.dart';

extension RestfullAPIClientAllApi on RestfulAPIClient {
  Future<BaseResponseModel<UpdateResponseModel>> checkUpdateApp() async {
    String version = Platform.version;
    final body = {"operating_system": "iOS", "software_model": "MyPoint", "version": "1.21.7", "build_number": "1"};
    return requestNormal(
      APIPaths.checkUpdate,
      Method.POST,
      body,
      (data) => UpdateResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<OnboardingInfoModel>> getOnboardingInfo() async {
    return requestNormal(
      APIPaths.getOnboardingInfo,
      Method.GET,
      {},
      (data) => OnboardingInfoModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<CheckPhoneResponseModel>> checkPhoneNumber(String phone) async {
    var deviceKey = await DeviceInfo.getDeviceId();
    var key = "$phone+_=$deviceKey/*8854";
    final body = {"device_key": deviceKey, "phone_number": phone, "key": key.toSha256()};
    return requestNormal(
      APIPaths.checkPhoneNumber,
      Method.POST,
      body,
      (data) => CheckPhoneResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<OTPVerifyResponseModel>> verifyOTP(String otp, String mfaToken) async {
    final body = {"otp": otp, "mfaToken": mfaToken};
    return requestNormal(
      APIPaths.verifyOtpWithAction,
      Method.POST,
      body,
      (data) => OTPVerifyResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<OTPResendResponseModel>> resendOTP(String mfaToken) async {
    final body = {"mfaToken": mfaToken};
    return requestNormal(
      APIPaths.retryOtpWithAction,
      Method.POST,
      body,
      (data) => OTPResendResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<CreateOTPResponseModel>> requestOtpDeleteAccount() async {
    return requestNormal(
      APIPaths.otpDeleteAccountRequest,
      Method.POST,
      {},
          (data) => CreateOTPResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<CreateOTPResponseModel>> verifyDeleteAccount(String otp) async {
    return requestNormal(
      APIPaths.verifyDeleteAccount,
      Method.POST,
      {"otp": otp},
          (data) => CreateOTPResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<EmptyCodable>> signup(String phone, String password) async {
    var deviceKey = await DeviceInfo.getDeviceId();
    final body = {"username": phone, "password": password.toSha256(), "device_key": deviceKey};
    return requestNormal(APIPaths.signup, Method.POST, body, (data) => EmptyCodable.fromJson(data as Json));
  }

  Future<BaseResponseModel<LoginTokenResponseModel>> login(String phone, String password) async {
    var deviceKey = await DeviceInfo.getDeviceId();
    final body = {
      "username": phone,
      "password": password.toSha256(),
      "device_key": deviceKey,
      "workspace_code": "8854"};
    return requestNormal(APIPaths.login, Method.POST, body, (data) => LoginTokenResponseModel.fromJson(data as Json));
  }

  Future<BaseResponseModel<LoginTokenResponseModel>> loginWithBiometric(String phone) async {
    var deviceKey = await DeviceInfo.getDeviceId();
    var bioToken = await DataPreference.instance.getBioToken(phone) ?? "";
    final body = {
      "username": phone,
      "bioToken": bioToken,
      "deviceKey": deviceKey,
      "workspaceCode": "8854"};
    return requestNormal(APIPaths.loginWithBiometric, Method.POST, body, (data) => LoginTokenResponseModel.fromJson(data as Json));
  }

  Future<BaseResponseModel<ProfileResponseModel>> getUserProfile() async {
    var deviceKey = await DeviceInfo.getDeviceId();
    return requestNormal(APIPaths.getUserInfo, Method.GET, {}, (data) => ProfileResponseModel.fromJson(data as Json));
  }

  Future<BaseResponseModel<CreateOTPResponseModel>> otpCreateNew(String ownerId) async {
    var deviceKey = await DeviceInfo.getDeviceId();
    final body = {"owner_id": ownerId, "ttl": Constants.otpTtl, "resend_after_second": Constants.otpTtl};
    return requestNormal(
      APIPaths.otpCreateNew,
      Method.POST,
      body,
      (data) => CreateOTPResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<CreateOTPResponseModel>> otpVerifyForDoingNextEvent(
    String ownerId,
    String otp,
    String nextEventName,
  ) async {
    final body = {
      "owner_id": ownerId,
      "otp": otp,
      "next_event_name": nextEventName,
      "ttdne": 180, //  TODO
      "ttl": Constants.otpTtl, "resend_after_second": Constants.otpTtl,
    };
    return requestNormal(
      APIPaths.otpVerifyForDoingNextEvent,
      Method.POST,
      body,
      (data) => CreateOTPResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<CampaignDetailResponseModel>> websitePageGetDetail(String id) async {
    final body = {"website_page_id": id};
    return requestNormal(
      APIPaths.websitePageGetDetail,
      Method.POST,
      body,
      (data) => CampaignDetailResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<CampaignDetailResponseModel>> websitePage(DetailPageRuleType rule) async {
    final body = {"code": rule.key};
    return requestNormal(
      APIPaths.websitePage,
      Method.GET,
      body,
      (data) => CampaignDetailResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<FAQItemModelResponse>> websiteFolderGetPageList() async {
    final body = {"folder_uri": "FAQ"};
    return requestNormal(
      APIPaths.websiteFolderGetPageList,
      Method.POST,
      body,
      (data) => FAQItemModelResponse.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<EmptyCodable>> accountPasswordReset(String phone, String password) async {
    final body = {"login_name": phone, "password": password.toSha256()};
    return requestNormal(
      APIPaths.accountPasswordReset,
      Method.POST,
      body,
          (data) => EmptyCodable.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<EmptyCodable>> accountPasswordChange(String phone, String password) async {
    String? token = await DataPreference.instance.token ?? "";
    final body = {"login_name": phone, "password": password.toSha256(), "access_token": token};
    return requestNormal(
      APIPaths.accountPasswordChange,
      Method.POST,
      body,
          (data) => EmptyCodable.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<EmptyCodable>> accountLoginForPasswordChange(String phone, String password) async {
    String? token = await DataPreference.instance.token ?? "";
    final body = {"login_name": phone, "password": password.toSha256(), "access_token": token};
    return requestNormal(
      APIPaths.accountLoginForPasswordChange,
      Method.POST,
      body,
          (data) => EmptyCodable.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<BiometricRegisterResponseModel>> accountBioCredential() async {
    var deviceKey = await DeviceInfo.getDeviceId();
    final body = {"deviceKey": deviceKey};
    return requestNormal(
      APIPaths.bioCredential,
      Method.POST,
      body,
          (data) => BiometricRegisterResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<BiometricRegisterResponseModel>> registerBiometric() async {
    var deviceKey = await DeviceInfo.getDeviceId();
    final body = {"deviceKey": deviceKey};
    return requestNormal(
      APIPaths.registerBiometric,
      Method.POST,
      body,
          (data) => BiometricRegisterResponseModel.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<EmptyCodable>> unRegisterBiometric() async {
    var deviceKey = await DeviceInfo.getDeviceId();
    final path = "${APIPaths.unRegisterBiometric}/$deviceKey";
    final body = {"deviceKey": deviceKey};
    return requestNormal(
      path,
      Method.POST,
      body,
          (data) => EmptyCodable.fromJson(data as Json),
    );
  }

  Future<BaseResponseModel<HeaderHomeModel>> getHomeHeaderData() async {
    return requestNormal(
      APIPaths.headerHome,
      Method.GET,
      {},
          (data) => HeaderHomeModel.fromJson(data as Json),
    );
  }
}
