import 'dart:async';
import 'dart:io';

import 'package:extended_image/extended_image.dart';
import 'package:flutter/painting.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';

bool _requiresAuthenticatedImageHeaders(String url) {
  return url.contains("/external/oss/local/");
}

Map<String, String>? buildNetworkImageHeaders(String url) {
  if (!_requiresAuthenticatedImageHeaders(url)) {
    return null;
  }
  final uri = Uri.tryParse(url);
  final headers = <String, String>{
    "req-lang": SCGlobalConfig.lang,
    "X-Forwarded-Proto": "http",
    "User-Agent": "Dart/3.7.2(dart:io)",
    "req-imei": SCGlobalConfig.imei,
    "req-app-intel":
        "version=${SCGlobalConfig.version};build=${SCGlobalConfig.build};model=${SCGlobalConfig.model};sysVersion=${SCGlobalConfig.sysVersion};channel=${SCGlobalConfig.channel}",
    "req-client": Platform.isAndroid ? "Android" : "iOS",
    "req-sys-origin":
        "origin=${SCGlobalConfig.origin};originChild=${SCGlobalConfig.originChild}",
  };
  if ((uri?.host ?? "").isNotEmpty) {
    headers["Host"] = uri!.host;
  }
  final token = AccountStorage().getToken();
  if (token.isNotEmpty) {
    headers["Authorization"] = "Bearer $token";
  }
  headers.removeWhere((key, value) => value.trim().isEmpty);
  return headers;
}

ImageProvider<Object> buildCachedImageProvider(String url) {
  if (url.startsWith("http")) {
    return ExtendedNetworkImageProvider(
      url,
      headers: buildNetworkImageHeaders(url),
      cache: true,
      cacheMaxAge: const Duration(days: 7),
    );
  }
  return FileImage(File(url));
}

Future<bool> warmNetworkImage(
  String url, {
  Duration timeout = const Duration(seconds: 6),
}) async {
  if (url.isEmpty) {
    return false;
  }
  final provider = buildCachedImageProvider(url);
  final stream = provider.resolve(ImageConfiguration.empty);
  final completer = Completer<bool>();
  late final ImageStreamListener listener;
  listener = ImageStreamListener(
    (image, synchronousCall) {
      if (!completer.isCompleted) {
        completer.complete(true);
      }
      stream.removeListener(listener);
    },
    onError: (Object error, StackTrace? stackTrace) {
      if (!completer.isCompleted) {
        completer.complete(false);
      }
      stream.removeListener(listener);
    },
  );
  stream.addListener(listener);
  return completer.future.timeout(
    timeout,
    onTimeout: () {
      stream.removeListener(listener);
      return false;
    },
  );
}
