/// Order Detail Model
///
/// Data model for order detail API response.
library;

import 'package:worker/features/account/data/models/address_model.dart';
import 'package:worker/features/orders/domain/entities/order_detail.dart';

/// Order Detail Model
class OrderDetailModel {
  const OrderDetailModel({
    required this.order,
    required this.billingAddress,
    required this.shippingAddress,
    required this.items,
    required this.paymentTerms,
    required this.timeline,
    required this.payments,
    required this.invoices,
  });

  final OrderDetailInfoModel order;
  final AddressModel billingAddress;
  final AddressModel shippingAddress;
  final List<OrderItemDetailModel> items;
  final PaymentTermsInfoModel paymentTerms;
  final List<TimelineItemModel> timeline;
  final List<PaymentInfoModel> payments;
  final List<InvoiceInfoModel> invoices;

  /// Create from JSON
  factory OrderDetailModel.fromJson(Map<String, dynamic> json) {
    return OrderDetailModel(
      order: OrderDetailInfoModel.fromJson(
        json['order'] as Map<String, dynamic>,
      ),
      billingAddress: AddressModel.fromJson(
        json['billing_address'] as Map<String, dynamic>,
      ),
      shippingAddress: AddressModel.fromJson(
        json['shipping_address'] as Map<String, dynamic>,
      ),
      items: (json['items'] as List<dynamic>)
          .map((item) =>
              OrderItemDetailModel.fromJson(item as Map<String, dynamic>))
          .toList(),
      paymentTerms: PaymentTermsInfoModel.fromJson(
        json['payment_terms'] as Map<String, dynamic>,
      ),
      timeline: (json['timeline'] as List<dynamic>)
          .map((item) =>
              TimelineItemModel.fromJson(item as Map<String, dynamic>))
          .toList(),
      payments: (json['payments'] as List<dynamic>? ?? [])
          .map((item) =>
              PaymentInfoModel.fromJson(item as Map<String, dynamic>))
          .toList(),
      invoices: (json['invoices'] as List<dynamic>? ?? [])
          .map((item) =>
              InvoiceInfoModel.fromJson(item as Map<String, dynamic>))
          .toList(),
    );
  }

  /// Convert to JSON
  Map<String, dynamic> toJson() {
    return {
      'order': order.toJson(),
      'billing_address': billingAddress.toJson(),
      'shipping_address': shippingAddress.toJson(),
      'items': items.map((item) => item.toJson()).toList(),
      'payment_terms': paymentTerms.toJson(),
      'timeline': timeline.map((item) => item.toJson()).toList(),
      'payments': payments.map((item) => item.toJson()).toList(),
      'invoices': invoices.map((item) => item.toJson()).toList(),
    };
  }

  /// Convert to domain entity
  OrderDetail toEntity() {
    return OrderDetail(
      order: order.toEntity(),
      billingAddress: billingAddress.toEntity(),
      shippingAddress: shippingAddress.toEntity(),
      items: items.map((item) => item.toEntity()).toList(),
      paymentTerms: paymentTerms.toEntity(),
      timeline: timeline.map((item) => item.toEntity()).toList(),
      payments: payments.map((item) => item.toEntity()).toList(),
      invoices: invoices.map((item) => item.toEntity()).toList(),
    );
  }

  /// Create from domain entity
  factory OrderDetailModel.fromEntity(OrderDetail entity) {
    return OrderDetailModel(
      order: OrderDetailInfoModel.fromEntity(entity.order),
      billingAddress: AddressModel.fromEntity(entity.billingAddress),
      shippingAddress: AddressModel.fromEntity(entity.shippingAddress),
      items: entity.items
          .map((item) => OrderItemDetailModel.fromEntity(item))
          .toList(),
      paymentTerms: PaymentTermsInfoModel.fromEntity(entity.paymentTerms),
      timeline: entity.timeline
          .map((item) => TimelineItemModel.fromEntity(item))
          .toList(),
      payments: entity.payments
          .map((item) => PaymentInfoModel.fromEntity(item))
          .toList(),
      invoices: entity.invoices
          .map((item) => InvoiceInfoModel.fromEntity(item))
          .toList(),
    );
  }
}

/// Order Detail Info Model
class OrderDetailInfoModel {
  const OrderDetailInfoModel({
    required this.name,
    required this.customer,
    required this.transactionDate,
    required this.deliveryDate,
    required this.status,
    required this.statusColor,
    required this.totalQty,
    required this.total,
    required this.grandTotal,
    required this.totalRemaining,
    required this.description,
    required this.contractRequest,
    required this.ignorePricingRule,
    this.rejectionReason,
    required this.isAllowCancel,
  });

  final String name;
  final String customer;
  final String transactionDate;
  final String deliveryDate;
  final String status;
  final String statusColor;
  final double totalQty;
  final double total;
  final double grandTotal;
  final double totalRemaining;
  final String description;
  final bool contractRequest;
  final bool ignorePricingRule;
  final String? rejectionReason;
  final bool isAllowCancel;

  factory OrderDetailInfoModel.fromJson(Map<String, dynamic> json) {
    return OrderDetailInfoModel(
      name: json['name'] as String,
      customer: json['customer'] as String,
      transactionDate: json['transaction_date'] as String,
      deliveryDate: json['delivery_date'] as String,
      status: json['status'] as String,
      statusColor: json['status_color'] as String,
      totalQty: (json['total_qty'] as num).toDouble(),
      total: (json['total'] as num).toDouble(),
      grandTotal: (json['grand_total'] as num).toDouble(),
      totalRemaining: (json['total_remaining'] as num).toDouble(),
      description: json['description'] as String,
      contractRequest: json['contract_request'] as bool,
      ignorePricingRule: json['ignore_pricing_rule'] as bool,
      rejectionReason: json['rejection_reason'] as String?,
      isAllowCancel: json['is_allow_cancel'] as bool,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'customer': customer,
      'transaction_date': transactionDate,
      'delivery_date': deliveryDate,
      'status': status,
      'status_color': statusColor,
      'total_qty': totalQty,
      'total': total,
      'grand_total': grandTotal,
      'total_remaining': totalRemaining,
      'description': description,
      'contract_request': contractRequest,
      'ignore_pricing_rule': ignorePricingRule,
      'rejection_reason': rejectionReason,
      'is_allow_cancel': isAllowCancel,
    };
  }

  OrderDetailInfo toEntity() {
    return OrderDetailInfo(
      name: name,
      customer: customer,
      transactionDate: transactionDate,
      deliveryDate: deliveryDate,
      status: status,
      statusColor: statusColor,
      totalQty: totalQty,
      total: total,
      grandTotal: grandTotal,
      totalRemaining: totalRemaining,
      description: description,
      contractRequest: contractRequest,
      ignorePricingRule: ignorePricingRule,
      rejectionReason: rejectionReason,
      isAllowCancel: isAllowCancel,
    );
  }

  factory OrderDetailInfoModel.fromEntity(OrderDetailInfo entity) {
    return OrderDetailInfoModel(
      name: entity.name,
      customer: entity.customer,
      transactionDate: entity.transactionDate,
      deliveryDate: entity.deliveryDate,
      status: entity.status,
      statusColor: entity.statusColor,
      totalQty: entity.totalQty,
      total: entity.total,
      grandTotal: entity.grandTotal,
      totalRemaining: entity.totalRemaining,
      description: entity.description,
      contractRequest: entity.contractRequest,
      ignorePricingRule: entity.ignorePricingRule,
      rejectionReason: entity.rejectionReason,
      isAllowCancel: entity.isAllowCancel,
    );
  }
}

/// Order Item Detail Model
class OrderItemDetailModel {
  const OrderItemDetailModel({
    required this.name,
    required this.itemCode,
    required this.itemName,
    required this.description,
    required this.qtyEntered,
    required this.qtyOfSm,
    required this.qtyOfNos,
    required this.conversionFactor,
    required this.price,
    required this.totalAmount,
    required this.deliveryDate,
    this.thumbnail,
  });

  final String name;
  final String itemCode;
  final String itemName;
  final String description;
  final double qtyEntered;
  final double qtyOfSm;
  final double qtyOfNos;
  final double conversionFactor;
  final double price;
  final double totalAmount;
  final String deliveryDate;
  final String? thumbnail;

  factory OrderItemDetailModel.fromJson(Map<String, dynamic> json) {
    return OrderItemDetailModel(
      name: json['name'] as String,
      itemCode: json['item_code'] as String,
      itemName: json['item_name'] as String,
      description: json['description'] as String,
      qtyEntered: (json['qty_entered'] as num).toDouble(),
      qtyOfSm: (json['qty_of_sm'] as num).toDouble(),
      qtyOfNos: (json['qty_of_nos'] as num).toDouble(),
      conversionFactor: (json['conversion_factor'] as num).toDouble(),
      price: (json['price'] as num).toDouble(),
      totalAmount: (json['total_amount'] as num).toDouble(),
      deliveryDate: json['delivery_date'] as String,
      thumbnail: json['thumbnail'] as String?,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'item_code': itemCode,
      'item_name': itemName,
      'description': description,
      'qty_entered': qtyEntered,
      'qty_of_sm': qtyOfSm,
      'qty_of_nos': qtyOfNos,
      'conversion_factor': conversionFactor,
      'price': price,
      'total_amount': totalAmount,
      'delivery_date': deliveryDate,
      'thumbnail': thumbnail,
    };
  }

  OrderItemDetail toEntity() {
    return OrderItemDetail(
      name: name,
      itemCode: itemCode,
      itemName: itemName,
      description: description,
      qtyEntered: qtyEntered,
      qtyOfSm: qtyOfSm,
      qtyOfNos: qtyOfNos,
      conversionFactor: conversionFactor,
      price: price,
      totalAmount: totalAmount,
      deliveryDate: deliveryDate,
      thumbnail: thumbnail,
    );
  }

  factory OrderItemDetailModel.fromEntity(OrderItemDetail entity) {
    return OrderItemDetailModel(
      name: entity.name,
      itemCode: entity.itemCode,
      itemName: entity.itemName,
      description: entity.description,
      qtyEntered: entity.qtyEntered,
      qtyOfSm: entity.qtyOfSm,
      qtyOfNos: entity.qtyOfNos,
      conversionFactor: entity.conversionFactor,
      price: entity.price,
      totalAmount: entity.totalAmount,
      deliveryDate: entity.deliveryDate,
      thumbnail: entity.thumbnail,
    );
  }
}

/// Payment Terms Info Model
class PaymentTermsInfoModel {
  const PaymentTermsInfoModel({
    required this.name,
    required this.description,
  });

  final String name;
  final String description;

  factory PaymentTermsInfoModel.fromJson(Map<String, dynamic> json) {
    return PaymentTermsInfoModel(
      name: json['name'] as String,
      description: json['description'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'description': description,
    };
  }

  PaymentTermsInfo toEntity() {
    return PaymentTermsInfo(
      name: name,
      description: description,
    );
  }

  factory PaymentTermsInfoModel.fromEntity(PaymentTermsInfo entity) {
    return PaymentTermsInfoModel(
      name: entity.name,
      description: entity.description,
    );
  }
}

/// Timeline Item Model
class TimelineItemModel {
  const TimelineItemModel({
    required this.label,
    this.value,
    required this.status,
  });

  final String label;
  final String? value;
  final String status;

  factory TimelineItemModel.fromJson(Map<String, dynamic> json) {
    return TimelineItemModel(
      label: json['label'] as String,
      value: json['value'] as String?,
      status: json['status'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'label': label,
      'value': value,
      'status': status,
    };
  }

  TimelineItem toEntity() {
    return TimelineItem(
      label: label,
      value: value,
      status: status,
    );
  }

  factory TimelineItemModel.fromEntity(TimelineItem entity) {
    return TimelineItemModel(
      label: entity.label,
      value: entity.value,
      status: entity.status,
    );
  }
}

/// Payment Info Model
class PaymentInfoModel {
  const PaymentInfoModel({
    required this.name,
    required this.creationDate,
    required this.amount,
  });

  final String name;
  final String creationDate;
  final double amount;

  factory PaymentInfoModel.fromJson(Map<String, dynamic> json) {
    return PaymentInfoModel(
      name: json['name'] as String,
      creationDate: json['creation_date'] as String,
      amount: (json['amount'] as num).toDouble(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'creation_date': creationDate,
      'amount': amount,
    };
  }

  PaymentInfo toEntity() {
    return PaymentInfo(
      name: name,
      creationDate: creationDate,
      amount: amount,
    );
  }

  factory PaymentInfoModel.fromEntity(PaymentInfo entity) {
    return PaymentInfoModel(
      name: entity.name,
      creationDate: entity.creationDate,
      amount: entity.amount,
    );
  }
}

/// Invoice Info Model
class InvoiceInfoModel {
  const InvoiceInfoModel({
    required this.name,
    required this.postingDate,
    required this.grandTotal,
  });

  final String name;
  final String postingDate;
  final double grandTotal;

  factory InvoiceInfoModel.fromJson(Map<String, dynamic> json) {
    return InvoiceInfoModel(
      name: json['name'] as String,
      postingDate: json['posting_date'] as String,
      grandTotal: (json['grand_total'] as num).toDouble(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'posting_date': postingDate,
      'grand_total': grandTotal,
    };
  }

  InvoiceInfo toEntity() {
    return InvoiceInfo(
      name: name,
      postingDate: postingDate,
      grandTotal: grandTotal,
    );
  }

  factory InvoiceInfoModel.fromEntity(InvoiceInfo entity) {
    return InvoiceInfoModel(
      name: entity.name,
      postingDate: entity.postingDate,
      grandTotal: entity.grandTotal,
    );
  }
}
