import 'package:commons_core/commons_core.dart';
import 'package:flutter/material.dart';

import '../i18n/strings.g.dart';
import '../services/offer_thumbnail.dart';
import 'theme.dart';

/// Human words for an offer's reciprocity mode. Shared by the market list and
/// the offer detail page so both read the same way.
String offerTypeLabel(Translations t, OfferType type) => switch (type) {
      OfferType.gift => t.share.gift,
      OfferType.exchange => t.share.exchange,
      OfferType.sale => t.share.sell,
      OfferType.wanted => t.market.wanted,
      OfferType.lend => t.share.exchange,
    };

/// A small square thumbnail of an offer's photo for the market list card.
/// The image usually rides inline in the offer as a `data:` URI (decentralized,
/// no server), so it renders straight from memory; an `http(s)` URL is still
/// supported for interop and degrades gracefully (spinner, then placeholder).
class OfferThumbnail extends StatelessWidget {
  const OfferThumbnail({
    required this.url,
    required this.semanticLabel,
    this.size = 56,
    super.key,
  });

  final String url;
  final String semanticLabel;
  final double size;

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: _offerImage(
        url,
        semanticLabel: semanticLabel,
        width: size,
        height: size,
      ),
    );
  }
}

/// Full-width "hero" image atop the offer detail page. Same source handling as
/// [OfferThumbnail]; hidden entirely when the offer has no photo.
class OfferHeroImage extends StatelessWidget {
  const OfferHeroImage({
    required this.url,
    required this.semanticLabel,
    super.key,
  });

  final String url;
  final String semanticLabel;

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(14),
      child: AspectRatio(
        aspectRatio: 4 / 3,
        child: _offerImage(url, semanticLabel: semanticLabel),
      ),
    );
  }
}

/// Renders an offer image from either an inline `data:` URI (via memory) or a
/// remote URL (via network), always cropping to fill and falling back to a
/// neutral placeholder — a broken image must never block the card.
Widget _offerImage(
  String url, {
  required String semanticLabel,
  double? width,
  double? height,
}) {
  final inline = decodeDataUri(url);
  if (inline != null) {
    return Image.memory(
      inline,
      width: width,
      height: height,
      fit: BoxFit.cover,
      semanticLabel: semanticLabel,
      errorBuilder: (context, _, _) =>
          _OfferImagePlaceholder(width: width, height: height),
    );
  }
  return Image.network(
    url,
    width: width,
    height: height,
    fit: BoxFit.cover,
    semanticLabel: semanticLabel,
    loadingBuilder: (context, child, progress) => progress == null
        ? child
        : _OfferImagePlaceholder(width: width, height: height, loading: true),
    errorBuilder: (context, _, _) =>
        _OfferImagePlaceholder(width: width, height: height),
  );
}

/// Neutral fill shown while a remote offer image loads or when it can't be
/// decoded/fetched — a marketplace is useless if a broken image blocks the card.
class _OfferImagePlaceholder extends StatelessWidget {
  const _OfferImagePlaceholder({this.width, this.height, this.loading = false});

  final double? width;
  final double? height;
  final bool loading;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      color: seedPrimaryContainer.withValues(alpha: 0.4),
      alignment: Alignment.center,
      child: loading
          ? const SizedBox(
              width: 20,
              height: 20,
              child: CircularProgressIndicator(strokeWidth: 2),
            )
          : const Icon(Icons.image_not_supported_outlined, color: seedMuted),
    );
  }
}

/// The small pill showing an offer's reciprocity mode (give/swap/sell/wanted).
class OfferTypeChip extends StatelessWidget {
  const OfferTypeChip({required this.label, super.key});

  final String label;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
      decoration: BoxDecoration(
        color: seedPrimaryContainer,
        borderRadius: BorderRadius.circular(20),
      ),
      child: Text(
        label,
        style: const TextStyle(
          color: seedOnPrimaryContainer,
          fontSize: 12,
          fontWeight: FontWeight.w600,
        ),
      ),
    );
  }
}
