part of '../order.dart';

@freezed
class ListOrder with _$ListOrder {
  const factory ListOrder({
    required List<Order> orders,
    required int totalCount,
    required int page,
    required int limit,
    required int totalPages,
  }) = _ListOrder;

  factory ListOrder.empty() => const ListOrder(
    orders: [],
    totalCount: 0,
    page: 0,
    limit: 0,
    totalPages: 0,
  );
}

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

  const factory Order({
    required String id,
    required String orderNumber,
    required String outletId,
    required String userId,
    required String tableNumber,
    required String orderType,
    required String status,
    required int subtotal,
    required int taxAmount,
    required int discountAmount,
    required int totalAmount,
    required num totalCost,
    required int remainingAmount,
    required String paymentStatus,
    required int refundAmount,
    required String refundReason,
    required bool isVoid,
    required bool isRefund,
    required String notes,
    required Map<String, dynamic> metadata,
    required DateTime createdAt,
    required DateTime updatedAt,
    required List<OrderItem> orderItems,
    required List<Payment> payments,
    required int totalPaid,
    required int paymentCount,
    required String splitType,
  }) = _Order;

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

  factory Order.mockOrder() => Order(
    id: 'ORD-001',
    orderNumber: 'A-1001',
    outletId: 'OUTLET-001',
    userId: 'USER-001',
    tableNumber: 'T01',
    orderType: 'Dine In',
    status: 'Completed',
    subtotal: 150000,
    taxAmount: 15000,
    discountAmount: 5000,
    totalAmount: 160000,
    totalCost: 100000,
    remainingAmount: 0,
    paymentStatus: 'Paid',
    refundAmount: 0,
    refundReason: '',
    isVoid: false,
    isRefund: false,
    notes: 'Customer requested less sugar',
    metadata: {'source': 'POS', 'device': 'iPad', 'customer_name': "John Doe"},
    createdAt: DateTime.now().subtract(const Duration(hours: 1)),
    updatedAt: DateTime.now(),
    orderItems: [
      OrderItem(
        id: 'ITEM-001',
        orderId: 'ORD-001',
        productId: 'PROD-001',
        productName: 'Cappuccino',
        productVariantId: 'VAR-001',
        productVariantName: 'Hot',
        quantity: 2,
        unitPrice: 25000,
        totalPrice: 50000,
        modifiers: [
          {'name': 'Extra Shot', 'price': 5000},
        ],
        notes: 'No sugar',
        status: 'Served',
        createdAt: DateTime.now().subtract(const Duration(hours: 1)),
        updatedAt: DateTime.now(),
        printerType: 'Barista',
        printToChecker: false,
        paidQuantity: 2,
        categoryId: 'CAT-001',
        categoryName: 'Minuman',
      ),
      OrderItem(
        id: 'ITEM-002',
        orderId: 'ORD-001',
        productId: 'PROD-002',
        productName: 'Spaghetti Carbonara',
        productVariantId: 'VAR-002',
        productVariantName: '',
        quantity: 1,
        unitPrice: 55000,
        totalPrice: 55000,
        modifiers: [],
        notes: '',
        status: 'Served',
        createdAt: DateTime.now().subtract(const Duration(hours: 1)),
        updatedAt: DateTime.now(),
        printerType: 'Kitchen',
        printToChecker: false,
        paidQuantity: 1,
        categoryId: 'CAT-002',
        categoryName: 'Makanan',
      ),
       OrderItem(
        id: 'ITEM-003',
        orderId: 'ORD-001',
        productId: 'PROD-003',
        productName: 'Pasta',
        productVariantId: 'VAR-002',
        productVariantName: '',
        quantity: 1,
        unitPrice: 50000,
        totalPrice: 50000,
        modifiers: [],
        notes: '',
        status: 'Served',
        createdAt: DateTime.now().subtract(const Duration(hours: 1)),
        updatedAt: DateTime.now(),
        printerType: 'Kitchen',
        printToChecker: false,
        paidQuantity: 1,
        categoryId: 'CAT-002',
        categoryName: 'Makanan',
      ),
    ],
    payments: [
      Payment(
        id: 'PAY-001',
        orderId: 'ORD-001',
        paymentMethodId: 'PM-CASH',
        paymentMethodName: 'Cash',
        paymentMethodType: 'Cash',
        amount: 160000,
        status: 'Success',
        splitNumber: 1,
        splitTotal: 1,
        splitDescription: 'Full payment by cash',
        refundAmount: 0,
        metadata: {'cashier': 'Efril', 'device': 'POS iPad'},
        createdAt: DateTime.now().subtract(const Duration(minutes: 45)),
        updatedAt: DateTime.now(),
      ),
    ],
    totalPaid: 160000,
    paymentCount: 1,
    splitType: 'Single',
  );

  // For Add Item Order
  factory Order.fromLastOrder(Order order, List<ProductQuantity> products) =>
      order.copyWith(
        orderItems: products
            .map((e) => OrderItem.fromProductQuantity(e))
            .toList(),
        totalAmount: products
            .map((e) => e.product.price.toInt() * e.quantity)
            .reduce((value, element) => value + element),
            subtotal: products
            .map((e) => e.product.price.toInt() * e.quantity)
            .reduce((value, element) => value + element),
            metadata: order.metadata,
      );

  List<OrderItem> get orderItemNotCancelled =>
      orderItems.where((item) => item.status != 'cancelled').toList();
}

@freezed
class OrderItem with _$OrderItem {
  const factory OrderItem({
    required String id,
    required String orderId,
    required String productId,
    required String productName,
    required String productVariantId,
    required String productVariantName,
    required int quantity,
    required int unitPrice,
    required int totalPrice,
    required List<dynamic> modifiers,
    required String notes,
    required String status,
    required DateTime createdAt,
    required DateTime updatedAt,
    required String printerType,
    required bool printToChecker,
    required int paidQuantity,
    required String categoryId,
    required String categoryName,
  }) = _OrderItem;

  factory OrderItem.empty() => OrderItem(
    id: '',
    orderId: '',
    productId: '',
    productName: '',
    productVariantId: '',
    productVariantName: '',
    quantity: 0,
    unitPrice: 0,
    totalPrice: 0,
    modifiers: const [],
    notes: '',
    status: '',
    createdAt: DateTime(1970),
    updatedAt: DateTime(1970),
    printerType: '',
    printToChecker: false,
    paidQuantity: 0,
    categoryId: '',
    categoryName: '',
  );

  factory OrderItem.fromProductQuantity(ProductQuantity productQuantity) =>
      OrderItem(
        id: '',
        orderId: '',
        productId: productQuantity.product.id,
        productName: productQuantity.product.name,
        productVariantId: productQuantity.variant?.id ?? '',
        productVariantName: productQuantity.variant?.name ?? '',
        quantity: productQuantity.quantity,
        unitPrice: productQuantity.product.price.toInt(),
        totalPrice: (productQuantity.product.price * productQuantity.quantity)
            .toInt(),
        modifiers: [],
        notes: productQuantity.notes,
        status: 'pending',
        createdAt: DateTime.now(),
        updatedAt: DateTime.now(),
        printerType: productQuantity.product.printerType,
        printToChecker: productQuantity.product.printToChecker,
        paidQuantity: 0,
        categoryId: '',
        categoryName: '',
      );
}
