part of '../order_dtos.dart';

@freezed
class ListOrderDto with _$ListOrderDto {
  const ListOrderDto._();

  const factory ListOrderDto({
    @JsonKey(name: "orders") List<OrderDto>? orders,
    @JsonKey(name: 'total_count') int? totalCount,
    @JsonKey(name: 'page') int? page,
    @JsonKey(name: 'limit') int? limit,
    @JsonKey(name: 'total_pages') int? totalPages,
  }) = _ListOrderDto;

  factory ListOrderDto.fromJson(Map<String, dynamic> json) =>
      _$ListOrderDtoFromJson(json);

  ListOrder toDomain() => ListOrder(
    orders: orders?.map((e) => e.toDomain()).toList() ?? [],
    totalCount: totalCount ?? 0,
    page: page ?? 0,
    limit: limit ?? 0,
    totalPages: totalPages ?? 0,
  );
}

@freezed
class OrderDto with _$OrderDto {
  const OrderDto._();

  const factory OrderDto({
    @JsonKey(name: "id") String? id,
    @JsonKey(name: "order_number") String? orderNumber,
    @JsonKey(name: "outlet_id") String? outletId,
    @JsonKey(name: "user_id") String? userId,
    @JsonKey(name: "table_number") String? tableNumber,
    @JsonKey(name: "order_type") String? orderType,
    @JsonKey(name: "status") String? status,
    @JsonKey(name: "subtotal") int? subtotal,
    @JsonKey(name: "tax_amount") int? taxAmount,
    @JsonKey(name: "discount_amount") int? discountAmount,
    @JsonKey(name: "total_amount") int? totalAmount,
    @JsonKey(name: "total_cost") num? totalCost,
    @JsonKey(name: "remaining_amount") int? remainingAmount,
    @JsonKey(name: "payment_status") String? paymentStatus,
    @JsonKey(name: "refund_amount") int? refundAmount,
    @JsonKey(name: "refund_reason") String? refundReason,
    @JsonKey(name: "is_void") bool? isVoid,
    @JsonKey(name: "is_refund") bool? isRefund,
    @JsonKey(name: "notes") String? notes,
    @JsonKey(name: "metadata") Map<String, dynamic>? metadata,
    @JsonKey(name: "created_at") String? createdAt,
    @JsonKey(name: "updated_at") String? updatedAt,
    @JsonKey(name: "order_items") List<OrderItemDto>? orderItems,
    @JsonKey(name: "payments") List<PaymentDto>? payments,
    @JsonKey(name: "total_paid") int? totalPaid,
    @JsonKey(name: "payment_count") int? paymentCount,
    @JsonKey(name: "split_type") String? splitType,
  }) = _OrderDto;

  factory OrderDto.fromJson(Map<String, dynamic> json) =>
      _$OrderDtoFromJson(json);

  // Optional: mapper ke domain entity

  Order toDomain() => Order(
    id: id ?? '',
    orderNumber: orderNumber ?? '',
    outletId: outletId ?? '',
    userId: userId ?? '',
    tableNumber: tableNumber ?? '',
    orderType: orderType ?? '',
    status: status ?? '',
    subtotal: subtotal ?? 0,
    taxAmount: taxAmount ?? 0,
    discountAmount: discountAmount ?? 0,
    totalAmount: totalAmount ?? 0,
    totalCost: totalCost ?? 0,
    remainingAmount: remainingAmount ?? 0,
    paymentStatus: paymentStatus ?? '',
    refundAmount: refundAmount ?? 0,
    isVoid: isVoid ?? false,
    isRefund: isRefund ?? false,
    notes: notes ?? '',
    metadata: metadata ?? const {},
    createdAt: createdAt != null ? DateTime.parse(createdAt!) : DateTime(1970),
    updatedAt: updatedAt != null ? DateTime.parse(updatedAt!) : DateTime(1970),
    orderItems: orderItems?.map((e) => e.toDomain()).toList() ?? const [],
    payments: payments?.map((e) => e.toDomain()).toList() ?? const [],
    totalPaid: totalPaid ?? 0,
    paymentCount: paymentCount ?? 0,
    splitType: splitType ?? '',
    refundReason: refundReason ?? '',
  );
}

@freezed
class OrderItemDto with _$OrderItemDto {
  const OrderItemDto._();

  const factory OrderItemDto({
    @JsonKey(name: "id") String? id,
    @JsonKey(name: "order_id") String? orderId,
    @JsonKey(name: "product_id") String? productId,
    @JsonKey(name: "product_name") String? productName,
    @JsonKey(name: "product_variant_id") String? productVariantId,
    @JsonKey(name: "product_variant_name") String? productVariantName,
    @JsonKey(name: "quantity") int? quantity,
    @JsonKey(name: "unit_price") int? unitPrice,
    @JsonKey(name: "total_price") int? totalPrice,
    @JsonKey(name: "modifiers") List<dynamic>? modifiers,
    @JsonKey(name: "notes") String? notes,
    @JsonKey(name: "status") String? status,
    @JsonKey(name: "created_at") String? createdAt,
    @JsonKey(name: "updated_at") String? updatedAt,
    @JsonKey(name: "printer_type") String? printerType,
    @JsonKey(name: "print_to_checker") bool? printToChecker,
    @JsonKey(name: "paid_quantity") int? paidQuantity,
    @JsonKey(name: "category_id") String? categoryId,
    @JsonKey(name: "category_name") String? categoryName,
  }) = _OrderItemDto;

  factory OrderItemDto.fromJson(Map<String, dynamic> json) =>
      _$OrderItemDtoFromJson(json);

  // Optional mapper to domain entity
  OrderItem toDomain() => OrderItem(
    id: id ?? '',
    orderId: orderId ?? '',
    productId: productId ?? '',
    productName: productName ?? '',
    productVariantId: productVariantId ?? '',
    productVariantName: productVariantName ?? '',
    quantity: quantity ?? 0,
    unitPrice: unitPrice ?? 0,
    totalPrice: totalPrice ?? 0,
    modifiers: modifiers ?? [],
    notes: notes ?? '',
    status: status ?? '',
    createdAt: createdAt != null ? DateTime.parse(createdAt!) : DateTime(1970),
    updatedAt: updatedAt != null ? DateTime.parse(updatedAt!) : DateTime(1970),
    printerType: printerType ?? '',
    printToChecker: printToChecker ?? false,
    paidQuantity: paidQuantity ?? 0,
    categoryId: categoryId ?? '',
    categoryName: categoryName ?? '',
  );

  factory OrderItemDto.fromDomain(OrderItem orderItem) => OrderItemDto(
    id: orderItem.id,
    orderId: orderItem.orderId,
    productId: orderItem.productId,
    productName: orderItem.productName,
    productVariantId: orderItem.productVariantId,
    productVariantName: orderItem.productVariantName,
    quantity: orderItem.quantity,
    unitPrice: orderItem.unitPrice,
    totalPrice: orderItem.totalPrice,
    modifiers: orderItem.modifiers,
    notes: orderItem.notes,
    status: orderItem.status,
    createdAt: orderItem.createdAt.toIso8601String(),
    updatedAt: orderItem.updatedAt.toIso8601String(),
    printerType: orderItem.printerType,
    printToChecker: orderItem.printToChecker,
    paidQuantity: orderItem.paidQuantity,
    categoryId: orderItem.categoryId,
    categoryName: orderItem.categoryName,
  );
}
