// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:html' as html;
import 'dart:math';
import 'dart:ui';

import 'package:image_picker_for_web/src/image_resizer_utils.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';

/// Helper class that resizes images.
class ImageResizer {
  /// Resizes the image if needed.
  /// (Does not support gif images)
  Future<XFile> resizeImageIfNeeded(XFile file, double? maxWidth,
      double? maxHeight, int? imageQuality) async {
    if (!imageResizeNeeded(maxWidth, maxHeight, imageQuality) ||
        file.mimeType == 'image/gif') {
      // Implement maxWidth and maxHeight for image/gif
      return file;
    }
    try {
      final html.ImageElement imageElement = await loadImage(file.path);
      final html.CanvasElement canvas =
          resizeImageElement(imageElement, maxWidth, maxHeight);
      final XFile resizedImage =
          await writeCanvasToFile(file, canvas, imageQuality);
      html.Url.revokeObjectUrl(file.path);
      return resizedImage;
    } catch (e) {
      return file;
    }
  }

  /// function that loads the blobUrl into an imageElement
  Future<html.ImageElement> loadImage(String blobUrl) {
    final Completer<html.ImageElement> imageLoadCompleter =
        Completer<html.ImageElement>();
    final html.ImageElement imageElement = html.ImageElement();
    // ignore: unsafe_html
    imageElement.src = blobUrl;

    imageElement.onLoad.listen((html.Event event) {
      imageLoadCompleter.complete(imageElement);
    });
    imageElement.onError.listen((html.Event event) {
      const String exception = 'Error while loading image.';
      imageElement.remove();
      imageLoadCompleter.completeError(exception);
    });
    return imageLoadCompleter.future;
  }

  /// Draws image to a canvas while resizing the image to fit the [maxWidth],[maxHeight] constraints
  html.CanvasElement resizeImageElement(
      html.ImageElement source, double? maxWidth, double? maxHeight) {
    final Size newImageSize = calculateSizeOfDownScaledImage(
        Size(source.width!.toDouble(), source.height!.toDouble()),
        maxWidth,
        maxHeight);
    final html.CanvasElement canvas = html.CanvasElement();
    canvas.width = newImageSize.width.toInt();
    canvas.height = newImageSize.height.toInt();
    final html.CanvasRenderingContext2D context = canvas.context2D;
    if (maxHeight == null && maxWidth == null) {
      context.drawImage(source, 0, 0);
    } else {
      context.drawImageScaled(source, 0, 0, canvas.width!, canvas.height!);
    }
    return canvas;
  }

  /// function that converts a canvas element to Xfile
  /// [imageQuality] is only supported for jpeg and webp images.
  Future<XFile> writeCanvasToFile(
      XFile originalFile, html.CanvasElement canvas, int? imageQuality) async {
    final double calculatedImageQuality =
        (min(imageQuality ?? 100, 100)) / 100.0;
    final html.Blob blob =
        await canvas.toBlob(originalFile.mimeType, calculatedImageQuality);
    return XFile(html.Url.createObjectUrlFromBlob(blob),
        mimeType: originalFile.mimeType,
        name: 'scaled_${originalFile.name}',
        lastModified: DateTime.now(),
        length: blob.size);
  }
}
