import '../api/types.dart';
import 'delivery_address.dart';
import 'delivery_order.dart';
import 'user_info.dart';

class Delivery implements Serializable {
  final int id;
  final int routeFragmentId;
  final int deliveryIndex;
  final List<DeliveryOrder> orders;
  final UserInfo? deliveredBy;
  final DeliveryAddress? deliveryAddress;
  final String? deliveredAt;
  final String? skippedAt;
  final String createdAt;
  final String? updatedAt;
  final bool delivered;
  final bool hasBeenSkipped;
  final bool isSkipped;
  final String name;

  const Delivery({
    required this.id,
    required this.routeFragmentId,
    required this.deliveryIndex,
    required this.orders,
    this.deliveredBy,
    this.deliveryAddress,
    this.deliveredAt,
    this.skippedAt,
    required this.createdAt,
    this.updatedAt,
    required this.delivered,
    required this.hasBeenSkipped,
    required this.isSkipped,
    required this.name,
  });

  // Special warehouse ID constant
  static const int warehouseDeliveryId = -1;

  // Check if this is the warehouse delivery
  bool get isWarehouseDelivery => id == warehouseDeliveryId;

  // Create a static warehouse delivery item
  static Delivery createWarehouseDelivery() {
    return Delivery(
      id: warehouseDeliveryId,
      routeFragmentId: -1,
      deliveryIndex: 999,
      orders: const [],
      deliveryAddress: const DeliveryAddress(
        id: -1,
        line1: '3550 Rue de Cherbourg Suite 108',
        line2: '',
        postalCode: 'G8Y 6S6',
        city: 'Trois-Rivières',
        subdivision: 'QC',
        countryCode: 'CA',
        latitude: 46.3384605,
        longitude: -72.6080797,
        formattedAddress: '3550 Rue de Cherbourg Suite 108, Trois-Rivières, QC G8Y 6S6',
      ),
      createdAt: DateTime.now().toIso8601String(),
      delivered: false,
      hasBeenSkipped: false,
      isSkipped: false,
      name: 'Return to Warehouse',
    );
  }

  factory Delivery.fromJson(Map<String, dynamic> json) {
    return Delivery(
      id: json['id'] as int,
      routeFragmentId: json['routeFragmentId'] as int,
      deliveryIndex: json['deliveryIndex'] as int,
      orders: (json['orders'] as List?)
          ?.map((e) => DeliveryOrder.fromJson(e as Map<String, dynamic>))
          .toList() ?? [],
      deliveredBy: json['deliveredBy'] != null
          ? UserInfo.fromJson(json['deliveredBy'] as Map<String, dynamic>)
          : null,
      deliveryAddress: json['deliveryAddress'] != null
          ? DeliveryAddress.fromJson(json['deliveryAddress'] as Map<String, dynamic>)
          : null,
      deliveredAt: json['deliveredAt'] as String?,
      skippedAt: json['skippedAt'] as String?,
      createdAt: json['createdAt'] as String,
      updatedAt: json['updatedAt'] as String?,
      delivered: json['delivered'] as bool,
      hasBeenSkipped: json['hasBeenSkipped'] as bool,
      isSkipped: json['isSkipped'] as bool,
      name: json['name'] as String,
    );
  }

  @override
  Map<String, Object?> toJson() => {
    'id': id,
    'routeFragmentId': routeFragmentId,
    'deliveryIndex': deliveryIndex,
    'orders': orders.map((o) => o.toJson()).toList(),
    'deliveredBy': deliveredBy?.toJson(),
    'deliveryAddress': deliveryAddress?.toJson(),
    'deliveredAt': deliveredAt,
    'skippedAt': skippedAt,
    'createdAt': createdAt,
    'updatedAt': updatedAt,
    'delivered': delivered,
    'hasBeenSkipped': hasBeenSkipped,
    'isSkipped': isSkipped,
    'name': name,
  };
}
