import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:qadirneyriz/config/config.dart';
import 'package:qadirneyriz/models/meetings/meetings_model.dart';
import 'package:qadirneyriz/models/meetings/one_meeting_model.dart';
import 'package:qadirneyriz/setting/setting.dart';
import 'package:qadirneyriz/utils/result/result.dart';

class MeetingsApi {
  Future<MeetingsModel> getMeetings({
    required int count,
    required int page,
    String? fromDate,
    String? toDate,
    int? location,
    int? subject,
    int? meetingManager,
    int? status,
  }) async {
    Map<String, String> headers = {
      'Accept': 'application/json',
    };
    String dataToken = setting.userLocalDb.getUser().token!;
    if (dataToken != '') {
      headers['Authorization'] = "Bearer $dataToken";
    }

    final String link =
        "${config.network.baseUrl}meetings?lang=${setting.userLocalDb.getUser().language}";
    // print(
    //     'Parameters: count: $count, page: $page, fromDate: $fromDate, toDate: $toDate, location: $location, subject: $subject, meetingManager: $meetingManager, status: $status');

    final response = await Dio().get(link,
        options: Options(
          headers: headers,
        ),
        queryParameters: {
          'count': count,
          'page': page,
          'date_meeting_az': fromDate,
          'date_meeting_ta': toDate,
          'location': location,
          'subject': subject,
          'meeting_manager': meetingManager,
          'status': status,
        });
    // print('${response.data} response.data');
    final MeetingsModel meetingsList = MeetingsModel.fromJson(response.data);

    return meetingsList;
  }

// one meeting
  Future<OneMeetingModel> getOneMeeting({required final int id}) async {
    Map<String, String> headers = {
      'Accept': 'application/json',
    };
    String dataToken = setting.userLocalDb.getUser().token!;
    if (dataToken != '') {
      headers['Authorization'] = "Bearer $dataToken";
    }

    final String link =
        "${config.network.baseUrl}meeting/$id?lang=${setting.userLocalDb.getUser().language}";

    final response = await Dio().get(
      link,
      options: Options(
        headers: headers,
      ),
    );
    final OneMeetingModel oneMeet = OneMeetingModel.fromJson(response.data);

    return oneMeet;
  }

// add meeting
  Future<Result> addMeetingApi(
      {int? locationId,
      int? subjectId,
      int? managerId,
      required String fromHour,
      required String toHour,
      required String dateMeeting,
      required List<int> members}) async {
    try {
      Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken != '') {
        headers['Authorization'] = "Bearer $dataToken";
      }
      FormData? formData;

      if (managerId != null) {
        formData = FormData.fromMap({
          'locations_id': locationId,
          'subject_id': subjectId,
          'az_hour': fromHour,
          'ta_hour': toHour,
          'members[]': members,
          'date_meeting': dateMeeting,
        });
      } else {
        formData = FormData.fromMap({
          'locations_id': locationId,
          'subject_id': subjectId,
          'manager_id': managerId,
          'az_hour': fromHour,
          'ta_hour': toHour,
          'members[]': members,
          'date_meeting': dateMeeting,
        });
      }
      print('${formData.fields} saggggggggg');
      final res = await Dio().post("${config.network.baseUrl}admin/add-meeting",
          data: formData, options: Options(headers: headers));

      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: res.data['message']);
      }
    } on DioException catch (e) {
      print('${e.message}');
      return Result(
          isOk: false,
          errors: e.response!.data['errors'],
          message: e.response!.data['message']);
    }
    return const Result(isOk: false);
  }

// edit meeting
  Future<Result> editMeetingApi(
      {required int id,
      required int locationId,
      required int subjectId,
      required int managerId,
      required String fromHour,
      required String toHour,
      required String dateMeeting,
      required List<int> members}) async {
    try {
      Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken != '') {
        headers['Authorization'] = "Bearer $dataToken";
      }
      FormData? formData;

      formData = FormData.fromMap({
        'id': id,
        'locations_id': locationId,
        'subject_id': subjectId,
        'manager_id': managerId,
        'az_hour': fromHour,
        'ta_hour': toHour,
        'members[]': members,
        'date_meeting': dateMeeting,
      });
      // print('${formData.fields} things to send');
      final res = await Dio().post(
          "${config.network.baseUrl}admin/edit-meeting",
          data: formData,
          options: Options(headers: headers));

      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: res.data['message']);
      }
    } on DioException catch (e) {
      // print(e);
      return Result(
          isOk: false,
          errors: e.response!.data['errors'],
          message: e.response!.data['message']);
    }
    return const Result(isOk: false);
  }

// cancel meeting
  Future<Result> cancelMeetingApi({
    required int id,
  }) async {
    try {
      Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken != '') {
        headers['Authorization'] = "Bearer $dataToken";
      }
      FormData? formData;

      formData = FormData.fromMap({
        'meeting_id': id,
      });
      final res = await Dio().post(
          "${config.network.baseUrl}admin/cancel-meeting",
          data: formData,
          options: Options(headers: headers));

      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: res.data['message']);
      }
    } on DioException catch (e) {
      return Result(
          isOk: false,
          errors: e.response!.data['errors'],
          message: e.response!.data['message']);
    }
    return const Result(isOk: false);
  }

// accept meeting
  Future<Result> acceptMeetingApi({
    required int id,
  }) async {
    try {
      Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken != '') {
        headers['Authorization'] = "Bearer $dataToken";
      }
      FormData? formData;

      formData = FormData.fromMap({
        'meeting_id': id,
      });
      final res = await Dio().post(
          "${config.network.baseUrl}admin/accept-meeting",
          data: formData,
          options: Options(headers: headers));

      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: res.data['message']);
      }
    } on DioException catch (e) {
      return Result(
          isOk: false,
          errors: e.response!.data['errors'],
          message: e.response!.data['message']);
    }
    return const Result(isOk: false);
  }

// add meeting minutes
  Future<Result> addMeetingMinuteApi({
    required int id,
    required String description,
    required List<PlatformFile> meetingFiles, // List of PlatformFile
  }) async {
    try {
      Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken.isNotEmpty) {
        headers['Authorization'] = "Bearer $dataToken";
      }

      // Create FormData
      FormData formData = FormData();

      // Add id and description fields
      formData.fields.add(MapEntry('id', id.toString()));
      formData.fields.add(MapEntry('description', description));

      // Check if meetingFiles is not empty and add files to FormData
      if (meetingFiles.isNotEmpty) {
        for (var file in meetingFiles) {
          if (file.path != null) {
            // Ensure that the file path is not null
            formData.files.add(
              MapEntry(
                  'meeting_files[]', await MultipartFile.fromFile(file.path!)),
            );
          }
        }
      }

      // Send request
      final res = await Dio().post(
        "${config.network.baseUrl}admin/add-meeting-minutes",
        data: formData,
        options: Options(headers: headers),
      );

      // Check response status
      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: res.data['message']);
      }
    } on DioException catch (e) {
      return Result(
        isOk: false,
        errors: e.response?.data['errors'],
        message: e.response?.data['message'],
      );
    }
    return const Result(isOk: false);
  }

// download meeting summary
  Future<Result?> downloadSummary(
      {required int id, String? format = 'zip'}) async {
    try {
      final Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken != '') {
        headers['Authorization'] = "Bearer $dataToken";
      }
      final Directory tempDir = await getApplicationDocumentsDirectory();

      final String tempPath = tempDir.path;
      final String savePath = '$tempPath/sammary_$id.$format';

      final res = await Dio().download(
        '${config.network.baseUrl}download-minutes/$id',
        savePath,
        options: Options(headers: headers),
      );

      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: savePath);
      } else {
        return Result(
            isOk: false, message: 'Failed with status code: ${res.statusCode}');
      }
    } on DioException catch (e) {
      return Result(
        isOk: false,
        errors: e.response?.data['errors'],
        message:
            e.response?.data['message'] ?? 'An error occurred during download.',
      );
    }
  }

// get String file of summary
  Future<List<String>> getListStringFils({required int id}) async {
    Map<String, String> headers = {
      'Accept': 'application/json',
    };

    String dataToken = setting.userLocalDb.getUser().token!;
    if (dataToken.isNotEmpty) {
      headers['Authorization'] = "Bearer $dataToken";
    }

    // ساخت لینک API
    final String link =
        "${config.network.baseUrl}admin/all-meeting-minutes/$id";

    // فراخوانی API
    final response = await Dio().get(
      link,
      options: Options(
        headers: headers,
      ),
    );

    print('${response.data} response.data');

    // بررسی ساختار پاسخ و تبدیل داده‌ها
    if (response.data is List) {
      return List<String>.from(response.data);
    } else {
      return [];
    }
  }

// delete file of summary
  Future<Result> deleteFileSummary({
    required int id,
    required String text,
  }) async {
    try {
      Map<String, String> headers = {"Accept": "application/json"};
      String dataToken = setting.userLocalDb.getUser().token!;
      if (dataToken.isNotEmpty) {
        headers['Authorization'] = "Bearer $dataToken";
      }

      // Create FormData
      FormData formData = FormData();

      // Send request
      final link =
          "${config.network.baseUrl}admin/delete-meeting-minutes/$id/$text";
      print('${link}');
      final res = await Dio().get(
        link,
        data: formData,
        options: Options(headers: headers),
      );

      // Check response status
      if (res.statusCode == 200 || res.statusCode == 201) {
        return Result(isOk: true, message: res.data['message']);
      }
    } on DioException catch (e) {
      print(e);
      return Result(
        isOk: false,
        errors: e.response?.data['errors'],
        message: e.response?.data['message'],
      );
    }
    return const Result(isOk: false);
  }
}
