// 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:typed_data';
import 'dart:ui';

import 'package:flutter_test/flutter_test.dart';
import 'package:image_picker_for_web/src/image_resizer.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
import 'package:integration_test/integration_test.dart';

//This is a sample 10x10 png image
const String pngFileBase64Contents =
    'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKAQMAAAC3/F3+AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEXqQzX+/v6lfubTAAAAAWJLR0QB/wIt3gAAAAlwSFlzAAAHEwAABxMBziAPCAAAAAd0SU1FB+UJHgsdDM0ErZoAAAALSURBVAjXY2DABwAAHgABboVHMgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wOS0zMFQxMToyOToxMi0wNDowMHCDC24AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDktMzBUMTE6Mjk6MTItMDQ6MDAB3rPSAAAAAElFTkSuQmCC';

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  // Under test...
  late ImageResizer imageResizer;
  late XFile pngFile;
  setUp(() {
    imageResizer = ImageResizer();
    final html.File pngHtmlFile =
        _base64ToFile(pngFileBase64Contents, 'pngImage.png');
    pngFile = XFile(html.Url.createObjectUrl(pngHtmlFile),
        name: pngHtmlFile.name, mimeType: pngHtmlFile.type);
  });

  testWidgets('image is loaded correctly ', (WidgetTester tester) async {
    final html.ImageElement imageElement =
        await imageResizer.loadImage(pngFile.path);
    expect(imageElement.width!, 10);
    expect(imageElement.height!, 10);
  });

  testWidgets(
      "canvas is loaded with image's width and height when max width and max height are null",
      (WidgetTester widgetTester) async {
    final html.ImageElement imageElement =
        await imageResizer.loadImage(pngFile.path);
    final html.CanvasElement canvas =
        imageResizer.resizeImageElement(imageElement, null, null);
    expect(canvas.width, imageElement.width);
    expect(canvas.height, imageElement.height);
  });

  testWidgets(
      'canvas size is scaled when max width and max height are not null',
      (WidgetTester widgetTester) async {
    final html.ImageElement imageElement =
        await imageResizer.loadImage(pngFile.path);
    final html.CanvasElement canvas =
        imageResizer.resizeImageElement(imageElement, 8, 8);
    expect(canvas.width, 8);
    expect(canvas.height, 8);
  });

  testWidgets('resized image is returned after converting canvas to file',
      (WidgetTester widgetTester) async {
    final html.ImageElement imageElement =
        await imageResizer.loadImage(pngFile.path);
    final html.CanvasElement canvas =
        imageResizer.resizeImageElement(imageElement, null, null);
    final XFile resizedImage =
        await imageResizer.writeCanvasToFile(pngFile, canvas, null);
    expect(resizedImage.name, 'scaled_${pngFile.name}');
  });

  testWidgets('image is scaled when maxWidth is set',
      (WidgetTester tester) async {
    final XFile scaledImage =
        await imageResizer.resizeImageIfNeeded(pngFile, 5, null, null);
    expect(scaledImage.name, 'scaled_${pngFile.name}');
    final Size scaledImageSize = await _getImageSize(scaledImage);
    expect(scaledImageSize, const Size(5, 5));
  });

  testWidgets('image is scaled when maxHeight is set',
      (WidgetTester tester) async {
    final XFile scaledImage =
        await imageResizer.resizeImageIfNeeded(pngFile, null, 6, null);
    expect(scaledImage.name, 'scaled_${pngFile.name}');
    final Size scaledImageSize = await _getImageSize(scaledImage);
    expect(scaledImageSize, const Size(6, 6));
  });

  testWidgets('image is scaled when imageQuality is set',
      (WidgetTester tester) async {
    final XFile scaledImage =
        await imageResizer.resizeImageIfNeeded(pngFile, null, null, 89);
    expect(scaledImage.name, 'scaled_${pngFile.name}');
  });

  testWidgets('image is scaled when maxWidth,maxHeight,imageQuality are set',
      (WidgetTester tester) async {
    final XFile scaledImage =
        await imageResizer.resizeImageIfNeeded(pngFile, 3, 4, 89);
    expect(scaledImage.name, 'scaled_${pngFile.name}');
  });

  testWidgets('image is not scaled when maxWidth,maxHeight, is set',
      (WidgetTester tester) async {
    final XFile scaledImage =
        await imageResizer.resizeImageIfNeeded(pngFile, null, null, null);
    expect(scaledImage.name, pngFile.name);
  });
}

Future<Size> _getImageSize(XFile file) async {
  final Completer<Size> completer = Completer<Size>();
  final html.ImageElement image = html.ImageElement(src: file.path);
  image.onLoad.listen((html.Event event) {
    completer.complete(Size(image.width!.toDouble(), image.height!.toDouble()));
  });
  image.onError.listen((html.Event event) {
    completer.complete(const Size(0, 0));
  });
  return completer.future;
}

html.File _base64ToFile(String data, String fileName) {
  final List<String> arr = data.split(',');
  final String bstr = html.window.atob(arr[1]);
  int n = bstr.length;
  final Uint8List u8arr = Uint8List(n);

  while (n >= 1) {
    u8arr[n - 1] = bstr.codeUnitAt(n - 1);
    n--;
  }

  return html.File(<Uint8List>[u8arr], fileName);
}
