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

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:telnow_mobile_new/src/injector/injector.dart';
import 'package:telnow_mobile_new/src/layouts/components/template.dart';
import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:path_provider/path_provider.dart';
import 'package:telnow_mobile_new/src/utils/U.dart';
import 'package:telnow_mobile_new/src/utils/cache_manager.dart';
import 'api_auth_provider.dart';

class JwtToken{
  final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
  final ApiAuthProvider _apiAuthProvider = ApiAuthProvider();

  Map<String, dynamic> parseJwtPayLoad(String token) {
    final parts = token.split('.');
    if (parts.length != 3) {
      throw Exception('invalid token');
    }

    final payload = _decodeBase64(parts[1]);
    final payloadMap = json.decode(payload);
    if (payloadMap is! Map<String, dynamic>) {
      throw Exception('invalid payload');
    }

    return payloadMap;
  }

  Map<String, dynamic> parseJwtHeader(String token) {
    final parts = token.split('.');
    if (parts.length != 3) {
      throw Exception('invalid token');
    }

    final payload = _decodeBase64(parts[0]);
    final payloadMap = json.decode(payload);
    if (payloadMap is! Map<String, dynamic>) {
      throw Exception('invalid payload');
    }

    return payloadMap;
  }

  String _decodeBase64(String str) {
    String output = str.replaceAll('-', '+').replaceAll('_', '/');

    switch (output.length % 4) {
      case 0:
        break;
      case 2:
        output += '==';
        break;
      case 3:
        output += '=';
        break;
      default:
        throw Exception('Illegal base64url string!"');
    }

    return utf8.decode(base64Url.decode(output));
  }

  Future<dynamic> getUserData(BuildContext context) async{
    bool isTokenExist = _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyAccessToken)!;
    String token = _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken)!;
    String username = _sharedPreferencesManager.getString(SharedPreferencesManager.keyUsername)!;

    if(isTokenExist && token != ''){
      var jwt = parseJwtPayLoad(token);
      var url = '/api/informants/'+jwt['userId'].toString();
      Map<String, dynamic>? user;

      if(U.getInternetStatus()){
        user = await _apiAuthProvider.getData(url, null, context);
      }
      else{
        var val = await CacheMan.readData(url);
        if (val != null) {
          user = val['data'][0];
        }
      }

      if((user != null && user['userId'].toLowerCase() != username.toLowerCase())){
        U.getChangedPassword() ? handlingError(context, 3) : (){}; //invalid user
        return null;
      } else if(user != null && user['dateExpired'] != null){
        final dateToCheck = DateTime.parse(user['dateExpired']);
        final now = DateTime.now();
        if(now.isAfter(dateToCheck)){
          handlingError(context, 4); //expired
          return null;
        }
      }

      if(user != null){
        context.setLocale(Locale(user['language'].toLowerCase()));
      }

      if(U.getInternetStatus()){
        CacheMan.writeData(url, [user]);
      }
      return user;
    } else {
      U.getChangedPassword() ? handlingError(context, 3) : (){}; //invalid user
      return Future.error("not found");
    }
  }

  logout() async{
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessToken);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyRefreshToken);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyUsername);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyIsLogin);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyScoope);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.debugString);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyHistoryMark);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyMenuDisplay);
    await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAutoTranslate);
    CacheMan.clearData();
  }

//  getPath() async{
//    var externalDirectoryPath = await ExtStorage.getExternalStorageDirectory();
//    return externalDirectoryPath;
//  }

  getPath() async {
    if(!kIsWeb) {
      Directory appDocDir = await getApplicationDocumentsDirectory();
      return appDocDir.path;
    }else{
      return null;
    }
  }
}