part of '../order_dtos.dart';

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

  const factory PaymentRequestDto({
    @JsonKey(name: "order_id") String? orderId,
    @JsonKey(name: "payment_method_id") String? paymentMethodId,
    @JsonKey(name: "amount") int? amount,
    @JsonKey(name: "transaction_id") String? transactionId,
    @JsonKey(name: "split_number") int? splitNumber,
    @JsonKey(name: "split_total") int? splitTotal,
    @JsonKey(name: "split_description") String? splitDescription,
    @JsonKey(name: "payment_order_items")
    List<PaymentItemRequestDto>? paymentOrderItems,
  }) = _PaymentRequestDto;

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

  // Optional mapper ke domain
  PaymentRequest toDomain() => PaymentRequest(
    orderId: orderId ?? '',
    paymentMethodId: paymentMethodId ?? '',
    amount: amount ?? 0,
    transactionId: transactionId ?? '',
    splitNumber: splitNumber ?? 0,
    splitTotal: splitTotal ?? 0,
    splitDescription: splitDescription ?? '',
    paymentOrderItems:
        paymentOrderItems?.map((e) => e.toDomain()).toList() ?? const [],
  );

  factory PaymentRequestDto.fromDomain(PaymentRequest request) =>
      PaymentRequestDto(
        orderId: request.orderId,
        paymentMethodId: request.paymentMethodId,
        amount: request.amount,
        transactionId: request.transactionId,
        splitNumber: request.splitNumber,
        splitTotal: request.splitTotal,
        splitDescription: request.splitDescription,
        paymentOrderItems: request.paymentOrderItems
            .map((e) => PaymentItemRequestDto.fromDomain(e))
            .toList(),
      );
}

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

  const factory PaymentItemRequestDto({
    @JsonKey(name: "order_item_id") String? orderItemId,
    @JsonKey(name: "amount") int? amount,
  }) = _PaymentItemRequestDto;

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

  // Optional: mapper ke domain entity
  PaymentItemRequest toDomain() =>
      PaymentItemRequest(orderItemId: orderItemId ?? '', amount: amount ?? 0);

  factory PaymentItemRequestDto.fromDomain(PaymentItemRequest request) =>
      PaymentItemRequestDto(
        orderItemId: request.orderItemId,
        amount: request.amount,
      );
}

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

  const factory PaymentSplitBillRequestDto({
    @JsonKey(name: "order_id") String? orderId,
    @JsonKey(name: "payment_method_id") String? paymentMethodId,
    @JsonKey(name: "customer_id") String? customerId,
    @JsonKey(name: "customer_name") String? customerName,
    @JsonKey(name: "type") String? type, // e.g., "AMOUNT" or "ITEM"
    @JsonKey(name: "amount") int? amount,
    @JsonKey(name: "items") List<PaymentItemSplitBillRequestDto>? items,
  }) = _PaymentSplitBillRequestDto;

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

  // Optional mapper ke domain
  PaymentSplitBillRequest toDomain() => PaymentSplitBillRequest(
    orderId: orderId ?? '',
    paymentMethodId: paymentMethodId ?? '',
    customerId: customerId ?? '',
    type: type?.toSplitType() ?? SplitType.unknown,
    amount: amount ?? 0,
    items: items?.map((e) => e.toDomain()).toList() ?? [],
    customerName: customerName ?? '',
  );

  factory PaymentSplitBillRequestDto.fromDomain(
    PaymentSplitBillRequest request,
  ) => PaymentSplitBillRequestDto(
    orderId: request.orderId,
    paymentMethodId: request.paymentMethodId,
    customerId: request.customerId,
    type: request.type.toStringType(),
    amount: request.amount,
    customerName: request.customerName,
    items: request.items
        .map((e) => PaymentItemSplitBillRequestDto.fromDomain(e))
        .toList(),
  );

  Map<String, dynamic> toRequest() {
    Map<String, dynamic> data = {
      'order_id': orderId,
      'payment_method_id': paymentMethodId,
      'type': type,
    };

    if (customerId != null && customerId != '') {
      data['customer_id'] = customerId;
    }

    if (customerName != null && customerName != '') {
      data['customer_name'] = customerName;
    }

    if (type == 'AMOUNT') {
      data['amount'] = amount;
    }

    if (type == 'ITEM') {
      data['items'] = items?.map((item) => item.toRequest()).toList();
    }

    return data;
  }
}

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

  const factory PaymentItemSplitBillRequestDto({
    @JsonKey(name: "order_item_id") String? orderItemId,
    @JsonKey(name: "quantity") int? quantity,
  }) = _PaymentItemSplitBillRequestDto;

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

  // Optional mapper ke domain
  PaymentItemSplitBillRequest toDomain() => PaymentItemSplitBillRequest(
    orderItemId: orderItemId ?? '',
    quantity: quantity ?? 0,
  );

  factory PaymentItemSplitBillRequestDto.fromDomain(
    PaymentItemSplitBillRequest request,
  ) => PaymentItemSplitBillRequestDto(
    orderItemId: request.orderItemId,
    quantity: request.quantity,
  );

  Map<String, dynamic> toRequest() => {
    'order_item_id': orderItemId,
    'quantity': quantity,
  };
}
