import 'dart:math' as math;

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

@immutable
class DetailPaletteRequest {
  DetailPaletteRequest({required this.url, Map<String, String>? headers})
    : headers = headers == null
          ? null
          : Map<String, String>.unmodifiable(headers);

  final String url;
  final Map<String, String>? headers;

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        other is DetailPaletteRequest &&
            other.url == url &&
            mapEquals(other.headers, headers);
  }

  @override
  int get hashCode {
    final sortedHeaderEntries = headers?.entries.toList(growable: false)
      ?..sort((left, right) => left.key.compareTo(right.key));
    final headersHash = sortedHeaderEntries == null
        ? null
        : Object.hashAll(
            sortedHeaderEntries.map(
              (entry) => Object.hash(entry.key, entry.value),
            ),
          );
    return Object.hash(url, headersHash);
  }
}


final detailPaletteProvider =
    FutureProvider.family<Color?, DetailPaletteRequest>((ref, request) async {
      try {
        final sourceProvider = CachedNetworkImageProvider(
          request.url,
          headers: request.headers,
        );
        final resizedProvider = ResizeImage.resizeIfNeeded(
          100,
          null,
          sourceProvider,
        );
        final colorScheme = await ColorScheme.fromImageProvider(
          provider: resizedProvider,
          brightness: Brightness.dark,
        ).timeout(const Duration(seconds: 6));

        final sourceColor = HSLColor.fromColor(colorScheme.primary);
        return sourceColor
            .withSaturation(math.min(sourceColor.saturation, 0.3))
            .withLightness(0.11)
            .toColor();
      } catch (_) {
        return null;
      }
    });

Color createDetailNavigationColor(Color backgroundColor) {
  final backgroundHsl = HSLColor.fromColor(backgroundColor);
  return backgroundHsl
      .withSaturation(math.min(backgroundHsl.saturation, 0.26))
      .withLightness(0.07)
      .toColor();
}
