import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:dsbridge_flutter/dsbridge_flutter.dart';
import 'package:electronic_assistant/resource/colors.gen.dart';
import 'package:flutter_svg/svg.dart';
import 'package:path_provider/path_provider.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import 'package:xml/xml.dart' as xml;

class MindUtil {
  MindUtil._();

  static const String functionToJsUpdateMind = "updateValue";
  static const String functionToJsExport = "export";

  static DWebViewController createMindWebViewController() {
    late final PlatformWebViewControllerCreationParams params;
    if (WebViewPlatform.instance is WebKitWebViewPlatform) {
      params = WebKitWebViewControllerCreationParams(
        allowsInlineMediaPlayback: true,
        mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
      );
    } else {
      params = const PlatformWebViewControllerCreationParams();
    }
    DWebViewController webViewController =
        DWebViewController.fromPlatformCreationParams(params);
    webViewController.setJavaScriptMode(JavaScriptMode.unrestricted);
    webViewController.setBackgroundColor(ColorName.white);
    webViewController.enableZoom(false);
    return webViewController;
  }

  static Future<File> convertToFile(Uint8List bytes, String fileName) async {
    final directory = await getTemporaryDirectory();
    final file = File('${directory.path}/mind/$fileName');
    if (!file.existsSync()) {
      file.createSync(recursive: true);
    }
    await file.writeAsBytes(bytes);
    return file;
  }

  static Future<void> convertMapDataToToFile(
      dynamic data, String fileName) async {
    Uint8List? bytes = convertToUint8List(data);
    if (bytes == null) {
      return;
    }
    final directory = await getTemporaryDirectory();
    final file = File('${directory.path}/$fileName');
    await file.writeAsBytes(bytes);
  }

  static Uint8List? convertToUint8List(dynamic value) {
    if (value is Map) {
      final data = value.values.toList().cast<int>();
      return Uint8List.fromList(data);
    }
    if (value is String) {
      return base64Decode(value.split(',').last);
    }
    return null;
  }

  static Future<Uint8List?> svgToPng(String svgString) async {
// first parse svgString to get width and height using xml plugin
    final document = xml.XmlDocument.parse(svgString);
    final svgElement = document.rootElement;
    final widthAttribute =
        svgElement.getAttribute('width')!.replaceAll("px", "");
    final heightAttribute =
        svgElement.getAttribute('height')!.replaceAll("px", "");

    final svgDrawableRoot =
        await vg.loadPicture(SvgStringLoader(svgString), null);
    // same thing

    // Convert to ui.Image. toImage() takes width and height as parameters
    // you need to find the best size to suit your needs and take into account the screen DPI
    final image = await svgDrawableRoot.picture.toImage(
        int.parse(widthAttribute.toString()),
        int.parse(heightAttribute.toString()));
    ByteData? bytes = await image.toByteData(format: ImageByteFormat.png);

    return bytes?.buffer.asUint8List();
  }

  static Future<File> saveToFile(dynamic value, String fileName) async {
    Uint8List? bytes = convertToUint8List(value);
    if (bytes == null) {
      throw Exception('bytes is null');
    }
    return convertToFile(bytes, fileName);
  }
}
