import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/utils/app_permission_handler.dart';
import 'package:mc_common_app/utils/utils.dart';

abstract class CommonAppServices {
  Future<List<File>> pickMultipleImages();

  Future<File?> pickImageFromPhone(int sourceFlag);

  Future<List<File>?> pickMultipleFiles(BuildContext context, {bool allowMultiple = true});

  Future<File?> pickFile(BuildContext context, {required FileType fileType, List<String>? allowedExtensions});

  double getDistanceBetween({
    required double curLatitude,
    required double curLongitude,
    required double destLatitude,
    required double destLongitude,
  });
}

class CommonServicesImp implements CommonAppServices {
  @override
  Future<File?> pickImageFromPhone(int sourceFlag) async {
    final picker = ImagePicker();
    final pickedImage = await picker.pickImage(
      source: sourceFlag == 0 ? ImageSource.camera : ImageSource.gallery,
    );
    final pickedImageFile = File(pickedImage!.path);
    return pickedImageFile;
  }

  @override
  Future<List<File>?> pickMultipleFiles(BuildContext context, {bool allowMultiple = true}) async {
    FilePickerResult? result;

    final status = await AppPermissions.checkStoragePermissions(context);
    if (status) {
      result = await FilePicker.platform.pickFiles(allowMultiple: allowMultiple, type: FileType.custom, allowedExtensions: ['pdf']);
    }

    List<File> pickedFiles = [];
    if (result != null) {
      for (var element in result.files) {
        if (element.path != null) {
          pickedFiles.add(File(element.path!));
        }
      }
    }
    return pickedFiles;
  }



  Future<List<File>> pickMultipleImages() async {
    final picker = ImagePicker();
    List<File> imageModels = [];
    List<File> pickedImages = [];
    var images = await picker.pickMultiImage(imageQuality: 70);

    for (var element in images) {
      final extension = element.path.split('.').last.toLowerCase();

      if (extension != 'jpg' && extension != 'jpeg' && extension != 'png') {
        Utils.showToast(LocaleKeys.onlyJPGandPNG);
        return [];
      }

      if (await element.length() > GlobalConsts().maxFileSizeInBytes) {
        Utils.showToast(LocaleKeys.maxFileSize);
        return [];
      }
      imageModels.add(File(element.path));
    }

    if (imageModels.length > GlobalConsts().maxFileCount) {
      Utils.showToast(LocaleKeys.maxFileSelection);
      imageModels = imageModels.sublist(0, GlobalConsts().maxFileCount); // Keep only the first 7 images
    }

    pickedImages.addAll(imageModels);
    return pickedImages;
  }

  @override
  Future<File?> pickFile(BuildContext context, {required FileType fileType, List<String>? allowedExtensions}) async {
    FilePickerResult? result;

    final status = await AppPermissions.checkStoragePermissions(context);
    if (status) {
      result = await FilePicker.platform.pickFiles(allowMultiple: false, type: fileType, allowedExtensions: allowedExtensions);
    }

    List<File> pickedFiles = [];
    if (result != null) {
      for (var element in result.files) {
        if (element.path != null) {
          pickedFiles.add(File(element.path!));
        }
      }
    }
    return pickedFiles.isNotEmpty ? pickedFiles.first : null;
  }

  @override
  double getDistanceBetween({required double curLatitude, required double curLongitude, required double destLatitude, required double destLongitude}) {
    try {
      double distance = Geolocator.distanceBetween(
        curLatitude,
        curLongitude,
        destLatitude,
        destLongitude,
      );

      return (distance / 1000) ?? 0.0;
    } catch (e) {
      logger.e(e.toString());
      return 0.0;
    }
  }
}
