import 'dart:convert';
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/core/database/models/enums.dart';

part 'order_model.g.dart';

/// Order Model - Type ID: 6
@HiveType(typeId: HiveTypeIds.orderModel)
class OrderModel extends HiveObject {
  OrderModel({
    required this.orderId,
    required this.orderNumber,
    required this.userId,
    required this.status,
    required this.totalAmount,
    required this.discountAmount,
    required this.taxAmount,
    required this.shippingFee,
    required this.finalAmount,
    this.shippingAddress,
    this.billingAddress,
    this.expectedDeliveryDate,
    this.actualDeliveryDate,
    this.notes,
    this.cancellationReason,
    this.erpnextSalesOrder,
    required this.createdAt,
    this.updatedAt,
  });

  @HiveField(0)
  final String orderId;

  @HiveField(1)
  final String orderNumber;

  @HiveField(2)
  final String userId;

  @HiveField(3)
  final OrderStatus status;

  @HiveField(4)
  final double totalAmount;

  @HiveField(5)
  final double discountAmount;

  @HiveField(6)
  final double taxAmount;

  @HiveField(7)
  final double shippingFee;

  @HiveField(8)
  final double finalAmount;

  @HiveField(9)
  final String? shippingAddress;

  @HiveField(10)
  final String? billingAddress;

  @HiveField(11)
  final DateTime? expectedDeliveryDate;

  @HiveField(12)
  final DateTime? actualDeliveryDate;

  @HiveField(13)
  final String? notes;

  @HiveField(14)
  final String? cancellationReason;

  @HiveField(15)
  final String? erpnextSalesOrder;

  @HiveField(16)
  final DateTime createdAt;

  @HiveField(17)
  final DateTime? updatedAt;

  factory OrderModel.fromJson(Map<String, dynamic> json) {
    return OrderModel(
      orderId: json['order_id'] as String,
      orderNumber: json['order_number'] as String,
      userId: json['user_id'] as String,
      status: OrderStatus.values.firstWhere((e) => e.name == json['status']),
      totalAmount: (json['total_amount'] as num).toDouble(),
      discountAmount: (json['discount_amount'] as num).toDouble(),
      taxAmount: (json['tax_amount'] as num).toDouble(),
      shippingFee: (json['shipping_fee'] as num).toDouble(),
      finalAmount: (json['final_amount'] as num).toDouble(),
      shippingAddress: json['shipping_address'] != null
          ? jsonEncode(json['shipping_address'])
          : null,
      billingAddress: json['billing_address'] != null
          ? jsonEncode(json['billing_address'])
          : null,
      expectedDeliveryDate: json['expected_delivery_date'] != null
          ? DateTime.parse(json['expected_delivery_date']?.toString() ?? '')
          : null,
      actualDeliveryDate: json['actual_delivery_date'] != null
          ? DateTime.parse(json['actual_delivery_date']?.toString() ?? '')
          : null,
      notes: json['notes'] as String?,
      cancellationReason: json['cancellation_reason'] as String?,
      erpnextSalesOrder: json['erpnext_sales_order'] as String?,
      createdAt: DateTime.parse(json['created_at']?.toString() ?? ''),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at']?.toString() ?? '')
          : null,
    );
  }

  Map<String, dynamic> toJson() => {
    'order_id': orderId,
    'order_number': orderNumber,
    'user_id': userId,
    'status': status.name,
    'total_amount': totalAmount,
    'discount_amount': discountAmount,
    'tax_amount': taxAmount,
    'shipping_fee': shippingFee,
    'final_amount': finalAmount,
    'shipping_address': shippingAddress != null
        ? jsonDecode(shippingAddress!)
        : null,
    'billing_address': billingAddress != null
        ? jsonDecode(billingAddress!)
        : null,
    'expected_delivery_date': expectedDeliveryDate?.toIso8601String(),
    'actual_delivery_date': actualDeliveryDate?.toIso8601String(),
    'notes': notes,
    'cancellation_reason': cancellationReason,
    'erpnext_sales_order': erpnextSalesOrder,
    'created_at': createdAt.toIso8601String(),
    'updated_at': updatedAt?.toIso8601String(),
  };

  Map<String, dynamic>? get shippingAddressMap {
    if (shippingAddress == null) return null;
    try {
      return jsonDecode(shippingAddress!) as Map<String, dynamic>;
    } catch (e) {
      return null;
    }
  }

  Map<String, dynamic>? get billingAddressMap {
    if (billingAddress == null) return null;
    try {
      return jsonDecode(billingAddress!) as Map<String, dynamic>;
    } catch (e) {
      return null;
    }
  }
}
