import 'package:commons_core/commons_core.dart';

import '../db/enums.dart';

/// Turns a locally-shared lot into a publishable [Offer]. Pure — no I/O — so it
/// is easy to test and keeps the privacy seam explicit: only the fields passed
/// here ever reach the network (never the whole lot/inventory, never an exact
/// address; the area is a coarse geohash chosen by the user).
class OfferMapper {
  const OfferMapper._();

  /// Maps the app's local sharing intent ([OfferStatus]) to the network offer
  /// type. `private` lots are never published.
  static OfferType offerTypeFor(OfferStatus sharing) => switch (sharing) {
        OfferStatus.shared => OfferType.gift,
        OfferStatus.exchange => OfferType.exchange,
        OfferStatus.sell => OfferType.sale,
        OfferStatus.private =>
          throw ArgumentError('private lots are not published to the network'),
      };

  /// Builds the [Offer] for a shared lot. [lotId] gives the offer a stable,
  /// addressable id (re-publishing updates in place). [areaGeohash] is the
  /// user's coarse area — the transport coarsens it further on the wire.
  static Offer fromSharedLot({
    required String lotId,
    required String authorPubkeyHex,
    required String summary,
    required OfferStatus sharing,
    required String areaGeohash,
    String? category,
    bool isOrganic = false,
    num? priceAmount,
    String? priceCurrency,
    String? exchangeTerms,
    String? imageUrl,
    DateTime? expiresAt,
  }) {
    final type = offerTypeFor(sharing);
    return Offer(
      id: lotId,
      authorPubkeyHex: authorPubkeyHex,
      summary: summary,
      type: type,
      approxGeohash: areaGeohash,
      category: category,
      isOrganic: isOrganic,
      priceAmount: type == OfferType.sale ? priceAmount : null,
      priceCurrency: type == OfferType.sale ? priceCurrency : null,
      exchangeTerms: type == OfferType.exchange ? exchangeTerms : null,
      imageUrl: imageUrl,
      expiresAt: expiresAt,
    );
  }
}
