import 'package:cross_file/cross_file.dart';
import 'package:dio/dio.dart';
import 'package:hoshan/core/services/api/dio_service.dart';
import 'package:hoshan/core/utils/strings.dart';
import 'package:hoshan/data/model/auth/login_model.dart';
import 'package:hoshan/data/model/auth/user_info_model.dart';
import 'package:hoshan/data/model/report_model.dart';
import 'package:shamsi_date/shamsi_date.dart';

class AuthRepository {
  static final DioService _dioService = DioService();

  static Future<UserInfoModel> getUserInfo() async {
    try {
      Response response =
          await _dioService.sendRequest().get(DioService.getInfo);
      return UserInfoModel.fromJson(response.data);
    } catch (ex) {
      rethrow;
    }
  }

  // static Future<Response> registerUser(String number) async {
  //   try {
  //     Response response = await _dioService.sendRequest().post(
  //         DioService.register,
  //         data: {'mobile_number': number.convertToEnglishNumber()});
  //     return response;
  //   } catch (ex) {
  //     rethrow;
  //   }
  // }

  static Future<bool> sendOtp(String number) async {
    try {
      Response response = await _dioService.sendRequest().post(
          DioService.sendOTP,
          data: {'mobile_number': number.convertToEnglishNumber()});
      return response.data['is_new'];
    } catch (ex) {
      rethrow;
    }
  }

  static Future<LoginModel> loginWithPassword(
      String number, String password) async {
    try {
      Response response = await _dioService.sendRequest().post(
          DioService.loginWithPassword,
          data: {'username': number, 'password': password});
      return LoginModel.fromJson(response.data);
    } catch (ex) {
      rethrow;
    }
  }

  static Future<LoginModel> loginWithOTP(String number, String otp) async {
    try {
      Response response = await _dioService.sendRequest().post(
          DioService.loginWithOTP,
          data: {"mobile_number": number.convertToEnglishNumber(), "otp": otp});
      return LoginModel.fromJson(response.data);
    } catch (ex) {
      rethrow;
    }
  }

  static Future<bool> checkUsernameIsValid(String username) async {
    try {
      Response response = await _dioService
          .sendRequest()
          .post(DioService.checkUsername, data: {"username": username});
      return response.data['available'];
    } catch (ex) {
      rethrow;
    }
  }

  static Future<bool> editUsername(String username) async {
    try {
      Response response = await _dioService
          .sendRequest()
          .put(DioService.editUsername, data: {"username": username});
      return (response.statusCode!) >= 200 && (response.statusCode!) < 300;
    } catch (ex) {
      return false;
    }
  }

  static Future<bool> editImageProfile(XFile image) async {
    try {
      FormData formData = FormData();

      MultipartFile multipartFile = await DioService.getMultipartFile(image);

      formData.files.add(MapEntry('file', multipartFile));
      Response response = await _dioService
          .sendRequest()
          .put(DioService.editProfile, data: formData);
      return (response.statusCode!) >= 200 && (response.statusCode!) < 300;
    } catch (ex) {
      return false;
    }
  }

  static Future<bool> editPasswordProfile(String password) async {
    try {
      Response response = await _dioService
          .sendRequest()
          .put(DioService.editPassword, data: {"password": password});
      return (response.statusCode!) >= 200 && (response.statusCode!) < 300;
    } catch (ex) {
      return false;
    }
  }

  static Future<bool> editCardNumber(String? cardNumber) async {
    try {
      Response response = await _dioService
          .sendRequest()
          .put(DioService.cardNumber, data: {"card_number": cardNumber});
      return (response.statusCode!) >= 200 && (response.statusCode!) < 300;
    } catch (ex) {
      return false;
    }
  }

  static Future<String?> checkGiftCode(String code) async {
    try {
      Response response = await _dioService
          .sendRequest()
          .post(DioService.giftCode, data: {"code": code});
      return response.data['detail'];
    } catch (ex) {
      rethrow;
    }
  }

  static Future<ReportModel> getReport({required Jalali? startDate}) async {
    try {
      startDate ??= Jalali.now();

      final shamsiYear = startDate.year;
      final shamsiMounth = startDate.month;

      startDate = Jalali(shamsiYear, shamsiMounth, 1);
      Jalali endDate = Jalali(
              shamsiMounth == 12 ? shamsiYear + 1 : shamsiYear,
              shamsiMounth == 12 ? 1 : shamsiMounth + 1,
              1)
          .addDays(-1);
      Gregorian sMiladiDate = startDate.toGregorian();
      Gregorian eMiladiDate = endDate.toGregorian();

      String sDate =
          '${sMiladiDate.year}-${sMiladiDate.month.toString().padLeft(2, '0')}-${sMiladiDate.day.toString().padLeft(2, '0')}';
      String eDate =
          '${eMiladiDate.year}-${eMiladiDate.month.toString().padLeft(2, '0')}-${eMiladiDate.day.toString().padLeft(2, '0')}';
      Response response = await _dioService.sendRequest().get(
          DioService.reportPeriodic,
          queryParameters: {'start_date': sDate, 'end_date': eDate});
      return ReportModel.fromJson(response.data);
    } catch (ex) {
      rethrow;
    }
  }

  static Future<ReportModel> getReportCoin({required Jalali? startDate}) async {
    try {
      startDate ??= Jalali.now();

      final shamsiYear = startDate.year;
      final shamsiMounth = startDate.month;

      startDate = Jalali(shamsiYear, shamsiMounth, 1);
      Jalali endDate = Jalali(
              shamsiMounth == 12 ? shamsiYear + 1 : shamsiYear,
              shamsiMounth == 12 ? 1 : shamsiMounth + 1,
              1)
          .addDays(-1);

      Gregorian sMiladiDate = startDate.toGregorian();
      Gregorian eMiladiDate = endDate.toGregorian();

      String sDate =
          '${sMiladiDate.year}-${sMiladiDate.month.toString().padLeft(2, '0')}-${sMiladiDate.day.toString().padLeft(2, '0')}';
      String eDate =
          '${eMiladiDate.year}-${eMiladiDate.month.toString().padLeft(2, '0')}-${eMiladiDate.day.toString().padLeft(2, '0')}';
      Response response = await _dioService.sendRequest().get(
          DioService.reportPiCoin,
          queryParameters: {'start_date': sDate, 'end_date': eDate});
      return ReportModel.fromJson(response.data);
    } catch (ex) {
      rethrow;
    }
  }

  static Future<ReportModel> setFCMtoken(String token) async {
    try {
      Response response = await _dioService
          .sendRequest()
          .put(DioService.fCMtoken, data: {"token": token});
      return ReportModel.fromJson(response.data);
    } catch (ex) {
      rethrow;
    }
  }

  static Future<Response> getRemaining() async {
    try {
      Response response =
          await _dioService.sendRequest().get(DioService.remaining);
      return response;
    } catch (ex) {
      rethrow;
    }
  }

  static Future<bool> addSubUser(String mobileNumber, int level) async {
    try {
      final number = mobileNumber.convertToEnglishNumber(); 
      
      Response response = await _dioService.sendRequest().post(
        DioService.addSubUser,
        data: {
          "mobile_number": number,
          "level": level,
        },
      );
      return (response.statusCode!) >= 200 && (response.statusCode!) < 300;
    } catch (ex) {
      rethrow;
    }
  }

  static Future<bool> deleteSubUser(String id) async {
    try {
      final response =
          await _dioService.sendRequest().delete(DioService.deleteSubUser(id));
      return (response.statusCode ?? 500) >= 200 &&
          (response.statusCode ?? 0) < 300;
    } catch (ex) {
      rethrow;
    }
  }

  static Future<List<Map<String, dynamic>>> getSubUsers() async {
    try {
      Response response = await _dioService.sendRequest().get(DioService.getSubUsers);
      
      // استخراج لیست کاربران از پاسخ جیسون
      // ساختار: { "sub_users": [...], "total_count": 1 }
      List<dynamic> data = response.data['sub_users'];
      
      // تبدیل به لیستی از Mapها
      return List<Map<String, dynamic>>.from(data);
    } catch (ex) {
      rethrow;
    }
  }
}


