import 'package:flutter/material.dart';
import 'package:p_tits_pas/services/api/tokenService.dart';

/// [Image.network] avec en-tête `Authorization` uniquement si l’URL n’est pas un fichier statique public.
///
/// Les chemins `/uploads/...` sont servis sans auth (voir back + Traefik) : ne pas envoyer de Bearer,
/// sinon en **cross-origin** (ex. admin Flutter web en local, API en prod) le navigateur peut bloquer
/// la requête (CORS) et afficher l’icône « image cassée ».
class AuthNetworkImage extends StatefulWidget {
  const AuthNetworkImage({
    super.key,
    required this.url,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.loadingBuilder,
    this.errorBuilder,
  });

  final String url;
  final double? width;
  final double? height;
  final BoxFit fit;
  final AlignmentGeometry alignment;
  final ImageLoadingBuilder? loadingBuilder;
  final ImageErrorWidgetBuilder? errorBuilder;

  static bool isPublicUploadUrl(String url) {
    final u = url.toLowerCase();
    return u.contains('/uploads/');
  }

  @override
  State<AuthNetworkImage> createState() => _AuthNetworkImageState();
}

class _AuthNetworkImageState extends State<AuthNetworkImage> {
  late final Future<Map<String, String>?> _headersFuture;

  @override
  void initState() {
    super.initState();
    final isPublic = AuthNetworkImage.isPublicUploadUrl(widget.url);
    _headersFuture =
        isPublic ? Future<Map<String, String>?>.value(null) : _loadHeaders();
  }

  static Future<Map<String, String>?> _loadHeaders() async {
    final t = await TokenService.getToken();
    if (t == null || t.isEmpty) return null;
    return {'Authorization': 'Bearer $t'};
  }

  ImageErrorWidgetBuilder _wrapErrorBuilder() {
    return (BuildContext context, Object error, StackTrace? stackTrace) {
      final inner = widget.errorBuilder;
      if (inner != null) {
        return inner(context, error, stackTrace);
      }
      return ColoredBox(
        color: Colors.grey.shade200,
        child: Center(
          child: Icon(Icons.broken_image_outlined, color: Colors.grey.shade500),
        ),
      );
    };
  }

  @override
  Widget build(BuildContext context) {
    final err = _wrapErrorBuilder();

    if (AuthNetworkImage.isPublicUploadUrl(widget.url)) {
      return Image.network(
        widget.url,
        width: widget.width,
        height: widget.height,
        fit: widget.fit,
        alignment: widget.alignment,
        loadingBuilder: widget.loadingBuilder,
        errorBuilder: err,
      );
    }

    return FutureBuilder<Map<String, String>?>(
      future: _headersFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return SizedBox(
            width: widget.width,
            height: widget.height,
            child: ColoredBox(
              color: Colors.grey.shade200,
              child: const Center(
                child: SizedBox(
                  width: 24,
                  height: 24,
                  child: CircularProgressIndicator(strokeWidth: 2),
                ),
              ),
            ),
          );
        }
        final headers = snapshot.data;
        return Image.network(
          widget.url,
          width: widget.width,
          height: widget.height,
          fit: widget.fit,
          alignment: widget.alignment,
          headers: headers,
          loadingBuilder: widget.loadingBuilder,
          errorBuilder: err,
        );
      },
    );
  }
}
