import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:niogu_ecommerce_v1/core/utils/converter.dart';
import 'package:niogu_ecommerce_v1/features/checkout/domain/entities/checkout.dart';

part 'checkout_model.g.dart';

@JsonSerializable()
class OnlineOrderRequest {
  @JsonKey(name: 'outlet_id')
  final String outletId;

  @JsonKey(name: 'outlet_name_snapshot')
  final String outletNameSnapshot;

  @JsonKey(name: 'outlet_phone_number_snapshot')
  final String? outletPhoneNumberSnapshot;

  @JsonKey(name: 'outlet_address_snapshot')
  final OutletAddressSnapshotRequest? outletAddressSnapshot;

  @JsonKey(name: 'customer_id')
  final String customerId;

  @JsonKey(name: 'customer_name_snapshot')
  final String customerNameSnapshot;

  @JsonKey(name: 'customer_email_snapshot')
  final String? customerEmailSnapshot;

  @JsonKey(name: 'customer_phone_number_snapshot')
  final String customerPhoneNumberSnapshot;

  @JsonKey(name: 'customer_address_snapshot')
  final CustomerAddressSnapshotRequest? customerAddressSnapshot;

  @JsonKey(name: 'order_status')
  final String orderStatus;

  @JsonKey(name: 'delivery_type')
  final String deliveryType;

  @JsonKey(name: 'delivery_preference')
  final String deliveryPreference;

  @JsonKey(name: 'delivery_fee_type')
  final String? deliveryFeeType;

  @JsonKey(name: 'delivery_fee')
  final double deliveryFee;

  @JsonKey(name: 'total_delivery_fee')
  final double totalDeliveryFee;

  @JsonKey(name: 'total_order')
  final double totalOrder;

  @JsonKey(name: 'total_amount')
  final double totalAmount;

  @JsonKey(name: 'notes')
  final String? notes;

  @JsonKey(includeFromJson: false, includeToJson: false)
  final MultipartFile? paymentProofFile;

  @JsonKey(name: 'payment_method')
  final String paymentMethod;

  @JsonKey(name: 'items')
  final List<OnlineOrderItemRequest> items;

  const OnlineOrderRequest({
    required this.outletId,
    required this.outletNameSnapshot,
    required this.outletPhoneNumberSnapshot,
    required this.outletAddressSnapshot,
    required this.customerId,
    required this.customerNameSnapshot,
    this.customerEmailSnapshot,
    required this.customerPhoneNumberSnapshot,
    required this.customerAddressSnapshot,
    required this.orderStatus,
    required this.deliveryType,
    required this.deliveryPreference,
    this.deliveryFeeType,
    required this.deliveryFee,
    required this.totalDeliveryFee,
    required this.totalOrder,
    required this.totalAmount,
    this.notes,
    this.paymentProofFile,
    required this.paymentMethod,
    required this.items,
  });

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

  Map<String, dynamic> toJson() => _$OnlineOrderRequestToJson(this);
}

@JsonSerializable()
class OutletAddressSnapshotRequest {
  @JsonKey(name: 'full_address')
  final String fullAddress;

  final double latitude;

  final double longitude;

  const OutletAddressSnapshotRequest({
    required this.fullAddress,
    required this.latitude,
    required this.longitude,
  });

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

  Map<String, dynamic> toJson() => _$OutletAddressSnapshotRequestToJson(this);
}

@JsonSerializable()
class CustomerAddressSnapshotRequest {
  final String label;

  @JsonKey(name: 'full_address')
  final String fullAddress;

  final double latitude;

  final double longitude;

  const CustomerAddressSnapshotRequest({
    required this.label,
    required this.fullAddress,
    required this.latitude,
    required this.longitude,
  });

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

  Map<String, dynamic> toJson() => _$CustomerAddressSnapshotRequestToJson(this);
}

@JsonSerializable()
class OnlineOrderItemRequest {
  @JsonKey(name: 'product_variant_id')
  final String productVariantId;

  final int quantity;

  @JsonKey(name: 'product_image_url_snapshot')
  final String? productImageUrlSnapshot;

  @JsonKey(name: 'product_name_snapshot')
  final String productNameSnapshot;

  @JsonKey(name: 'product_variant_name_snapshot')
  final String? productVariantNameSnapshot;

  @JsonKey(name: 'selling_price_snapshot', fromJson: toDouble)
  final double sellingPriceSnapshot;

  @JsonKey(fromJson: toDouble)
  final double subtotal;

  const OnlineOrderItemRequest({
    required this.productVariantId,
    required this.quantity,
    this.productImageUrlSnapshot,
    required this.productNameSnapshot,
    this.productVariantNameSnapshot,
    required this.sellingPriceSnapshot,
    required this.subtotal,
  });

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

  Map<String, dynamic> toJson() => _$OnlineOrderItemRequestToJson(this);
}

@JsonSerializable()
class CheckoutResponse {
  @JsonKey(name: 'order_id')
  final String orderId;

  @JsonKey(name: 'order_number')
  final String orderNumber;

  const CheckoutResponse({required this.orderId, required this.orderNumber});

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

  Map<String, dynamic> toJson() => _$CheckoutResponseToJson(this);

  Checkout toCheckout() {
    return Checkout(orderId: orderId, orderNumber: orderNumber);
  }
}
