import 'package:collection/collection.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/user.dart';
import 'package:didvan/models/view/alert_data.dart';
import 'package:didvan/providers/core_provider.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:didvan/utils/action_sheet.dart';

class UserProvider extends CoreProvier {
  late User user;
  bool isAuthenticated = false;

  static final List<MapEntry> _radarMarkQueue = [];
  static final List<MapEntry> _newsMarkQueue = [];
  static final List<MapEntry> _studioMarkQueue = [];

  Future<String?> setAndGetToken({String? newToken}) async {
    if (newToken == null) {
      final token = await StorageService.getValue(key: 'token');
      return token;
    }
    await StorageService.setValue(key: 'token', value: newToken);
    return null;
  }

  Future<bool> getUserInfo() async {
    isAuthenticated = true;
    final RequestService service = RequestService(RequestHelper.userInfo);
    await service.httpGet();
    if (service.statusCode == 401 ||
        (service.isSuccess && service.result['user'] == null)) {
      return false;
    }
    if (service.isSuccess) {
      user = User.fromJson(service.result['user']);
      return true;
    }
    throw 'Getting user from API failed!';
  }

  Future<bool> setProfilePhoto(dynamic file) async {
    appState = AppState.isolatedBusy;
    final RequestService service =
        RequestService(RequestHelper.updateProfilePhoto);
    await service.multipart(
      file: file,
      method: 'PUT',
      fileName: 'user-profile',
      fieldName: 'photo',
      mediaExtension: 'jpg',
      mediaFormat: 'image',
    );
    if (service.isSuccess) {
      user = user.copyWith(photo: service.result['photo']);
      appState = AppState.idle;
      return true;
    }
    appState = AppState.failed;
    return false;
  }

  Future<bool> deleteProfilePhoto() async {
    appState = AppState.isolatedBusy;
    final RequestService service =
        RequestService(RequestHelper.updateProfilePhoto);
    await service.delete();
    if (service.isSuccess) {
      user = user.copyWith(photo: null);
      appState = AppState.idle;
      return true;
    }
    appState = AppState.idle;
    return false;
  }

  Future<bool?> checkUsername(String username) async {
    if (user.username == username) return true;
    final RequestService service = RequestService(
      RequestHelper.checkUsername,
      body: {'username': username},
    );
    await service.post();
    if (service.isSuccess) {
      return service.result['available'];
    }
    return null;
  }

  Future<void> editProfile(
    String fullName,
    String? username,
    String? email,
  ) async {
    appState = AppState.isolatedBusy;
    final service = RequestService(
      RequestHelper.updateProfile,
      body: {
        'fullName': fullName,
        'email': email,
        'username': username,
      },
    );
    await service.put();
    if (service.isSuccess) {
      user = user.copyWith(
        fullName: fullName,
        email: email,
        username: username,
      );
      appState = AppState.idle;
      ActionSheetUtils.pop();
      ActionSheetUtils.showAlert(
        AlertData(
          message: 'پروفایل با موفقیت ویرایش شد',
          aLertType: ALertType.success,
        ),
      );
      return;
    }
    appState = AppState.idle;
    ActionSheetUtils.showAlert(
      AlertData(
        message: service.errorMessage,
      ),
    );
  }

  static Future<void> changeRadarMark(int id, bool value) async {
    _radarMarkQueue.add(MapEntry(id, value));
    Future.delayed(const Duration(milliseconds: 500), () async {
      final MapEntry? lastChange =
          _radarMarkQueue.lastWhereOrNull((item) => item.key == id);
      if (lastChange == null) return;
      final service = RequestService(RequestHelper.mark(id, 'radar'));
      if (lastChange.value) {
        await service.post();
      } else {
        await service.delete();
      }
      _radarMarkQueue.removeWhere((element) => element.key == id);
    });
  }

  static Future<void> changeStudioMark(int id, bool value) async {
    _studioMarkQueue.add(MapEntry(id, value));
    Future.delayed(const Duration(milliseconds: 500), () async {
      final MapEntry? lastChange =
          _studioMarkQueue.lastWhereOrNull((item) => item.key == id);
      if (lastChange == null) return;
      final service = RequestService(RequestHelper.mark(id, 'studio'));
      if (lastChange.value) {
        await service.post();
      } else {
        await service.delete();
      }
      _studioMarkQueue.removeWhere((element) => element.key == id);
    });
  }

  static Future<void> changeNewsMark(int id, bool value) async {
    _newsMarkQueue.add(MapEntry(id, value));
    Future.delayed(const Duration(milliseconds: 500), () async {
      final MapEntry? lastChange =
          _newsMarkQueue.lastWhereOrNull((item) => item.key == id);
      if (lastChange == null) return;
      final service = RequestService(RequestHelper.mark(id, 'news'));
      if (lastChange.value) {
        await service.post();
      } else {
        await service.delete();
      }
      _newsMarkQueue.removeWhere((element) => element.key == id);
    });
  }
}
