import 'scan_progress.dart';

/// Eine Belegzeile innerhalb einer Lieferung.
///
/// Verweist über `articleId` auf den Artikel-Stamm (lookup via
/// `TourDetails.articleById`) und über `warehouseId` auf das Lager. Die
/// Soll-/Ist-Quantitäten leben hier: `requiredQuantity` ist statisch (ERP),
/// `scanProgress.scannedQuantity` wandert mit jedem Scan nach oben.
///
/// `komponentenArtikelNr` markiert Stücklisten-Komponenten. Im neuen
/// Backend gibt es **keine** Parent-/Child-Hierarchie mehr — jedes Item ist
/// gleichrangig; das Feld dient nur noch der Anzeige ("Teil von X") und
/// hat keinerlei Scan-Semantik.
class DeliveryItem {
  const DeliveryItem({
    required this.id,
    required this.deliveryId,
    required this.articleId,
    required this.warehouseId,
    required this.belegzeilenNr,
    required this.requiredQuantity,
    required this.scanProgress,
    this.unitPrice = 0,
    this.komponentenArtikelNr,
    this.parentArtikelNr,
  });

  final String id;
  final String deliveryId;
  final String articleId;
  final String warehouseId;

  /// ERP-Belegzeilen-Nummer. Bestimmt die Reihenfolge der Items in der
  /// Detail-Ansicht (aufsteigend).
  final int belegzeilenNr;
  final int requiredQuantity;
  final ScanProgress scanProgress;

  /// Stückpreis (brutto, EUR) aus dem ERP-Sync.
  final double unitPrice;

  final String? komponentenArtikelNr;

  /// Artikelnummer des Oberartikels, zu dem diese Komponente gehört (aus dem
  /// Sync). `null` bei Oberartikeln/regulären Zeilen. Die Liste rückt
  /// Komponenten unter ihrem Oberartikel ein.
  final String? parentArtikelNr;

  /// `true`, wenn dieses Item eine Stücklisten-Komponente ist (gehört unter
  /// einen Oberartikel).
  bool get isComponent => parentArtikelNr != null;

  // ─── Abgeleitete Sicht-Eigenschaften ──────────────────────────────────

  /// Tatsächlich auszuliefernde Menge = Soll − Gutschrift. Nie negativ.
  int get deliveredQuantity {
    final d = requiredQuantity - scanProgress.creditedQuantity;
    return d < 0 ? 0 : d;
  }

  /// Wert der ausgelieferten Menge dieser Position (brutto, EUR).
  double get lineTotal => unitPrice * deliveredQuantity;

  /// Vollständig gescannt (Status `done` oder Ist ≥ Soll).
  bool get isDone =>
      scanProgress.status == ScanStatus.done ||
      scanProgress.scannedQuantity >= requiredQuantity;

  /// Aktuell pausiert.
  bool get isHeld => scanProgress.status == ScanStatus.held;

  /// Nach dem Laden wieder entfernt.
  bool get isRemoved => scanProgress.status == ScanStatus.removed;

  /// Noch offene Restmenge (für Loading-UI). Nicht negativ.
  int get remainingQuantity {
    final remaining = requiredQuantity - scanProgress.scannedQuantity;
    return remaining < 0 ? 0 : remaining;
  }

  DeliveryItem copyWith({
    String? id,
    String? deliveryId,
    String? articleId,
    String? warehouseId,
    int? belegzeilenNr,
    int? requiredQuantity,
    ScanProgress? scanProgress,
    double? unitPrice,
    String? komponentenArtikelNr,
    String? parentArtikelNr,
  }) {
    return DeliveryItem(
      id: id ?? this.id,
      deliveryId: deliveryId ?? this.deliveryId,
      articleId: articleId ?? this.articleId,
      warehouseId: warehouseId ?? this.warehouseId,
      belegzeilenNr: belegzeilenNr ?? this.belegzeilenNr,
      requiredQuantity: requiredQuantity ?? this.requiredQuantity,
      scanProgress: scanProgress ?? this.scanProgress,
      unitPrice: unitPrice ?? this.unitPrice,
      komponentenArtikelNr: komponentenArtikelNr ?? this.komponentenArtikelNr,
      parentArtikelNr: parentArtikelNr ?? this.parentArtikelNr,
    );
  }
}
