/// Data Model: Invoice Model
///
/// Model for invoice data with API serialization.
/// Not stored in local database.
library;

import 'package:worker/features/invoices/domain/entities/invoice.dart';

/// Seller Info Model
class SellerInfoModel {
  final String? phone;
  final String? email;
  final String? fax;
  final String? taxCode;
  final String? companyName;
  final String? addressLine1;
  final String? cityCode;
  final String? wardCode;
  final String? cityName;
  final String? wardName;

  const SellerInfoModel({
    this.phone,
    this.email,
    this.fax,
    this.taxCode,
    this.companyName,
    this.addressLine1,
    this.cityCode,
    this.wardCode,
    this.cityName,
    this.wardName,
  });

  factory SellerInfoModel.fromJson(Map<String, dynamic> json) {
    return SellerInfoModel(
      phone: json['phone'] as String?,
      email: json['email'] as String?,
      fax: json['fax'] as String?,
      taxCode: json['tax_code'] as String?,
      companyName: json['company_name'] as String?,
      addressLine1: json['address_line1'] as String?,
      cityCode: json['city_code'] as String?,
      wardCode: json['ward_code'] as String?,
      cityName: json['city_name'] as String?,
      wardName: json['ward_name'] as String?,
    );
  }

  Map<String, dynamic> toJson() => {
        'phone': phone,
        'email': email,
        'fax': fax,
        'tax_code': taxCode,
        'company_name': companyName,
        'address_line1': addressLine1,
        'city_code': cityCode,
        'ward_code': wardCode,
        'city_name': cityName,
        'ward_name': wardName,
      };

  SellerInfo toEntity() => SellerInfo(
        phone: phone,
        email: email,
        fax: fax,
        taxCode: taxCode,
        companyName: companyName,
        addressLine1: addressLine1,
        cityCode: cityCode,
        wardCode: wardCode,
        cityName: cityName,
        wardName: wardName,
      );
}

/// Buyer Info Model
class BuyerInfoModel {
  final String? name;
  final String? addressTitle;
  final String? addressLine1;
  final String? phone;
  final String? email;
  final String? fax;
  final String? taxCode;
  final String? cityCode;
  final String? wardCode;
  final String? cityName;
  final String? wardName;
  final String? customerName;

  const BuyerInfoModel({
    this.name,
    this.addressTitle,
    this.addressLine1,
    this.phone,
    this.email,
    this.fax,
    this.taxCode,
    this.cityCode,
    this.wardCode,
    this.cityName,
    this.wardName,
    this.customerName,
  });

  factory BuyerInfoModel.fromJson(Map<String, dynamic> json) {
    return BuyerInfoModel(
      name: json['name'] as String?,
      addressTitle: json['address_title'] as String?,
      addressLine1: json['address_line1'] as String?,
      phone: json['phone'] as String?,
      email: json['email'] as String?,
      fax: json['fax'] as String?,
      taxCode: json['tax_code'] as String?,
      cityCode: json['city_code'] as String?,
      wardCode: json['ward_code'] as String?,
      cityName: json['city_name'] as String?,
      wardName: json['ward_name'] as String?,
      customerName: json['customer_name'] as String?,
    );
  }

  Map<String, dynamic> toJson() => {
        'name': name,
        'address_title': addressTitle,
        'address_line1': addressLine1,
        'phone': phone,
        'email': email,
        'fax': fax,
        'tax_code': taxCode,
        'city_code': cityCode,
        'ward_code': wardCode,
        'city_name': cityName,
        'ward_name': wardName,
        'customer_name': customerName,
      };

  BuyerInfo toEntity() => BuyerInfo(
        name: name,
        addressTitle: addressTitle,
        addressLine1: addressLine1,
        phone: phone,
        email: email,
        fax: fax,
        taxCode: taxCode,
        cityCode: cityCode,
        wardCode: wardCode,
        cityName: cityName,
        wardName: wardName,
        customerName: customerName,
      );
}

/// Invoice Item Model
class InvoiceItemModel {
  final String itemName;
  final String itemCode;
  final double qty;
  final double rate;
  final double amount;

  const InvoiceItemModel({
    required this.itemName,
    required this.itemCode,
    required this.qty,
    required this.rate,
    required this.amount,
  });

  factory InvoiceItemModel.fromJson(Map<String, dynamic> json) {
    return InvoiceItemModel(
      itemName: json['item_name'] as String? ?? '',
      itemCode: json['item_code'] as String? ?? '',
      qty: (json['qty'] as num?)?.toDouble() ?? 0.0,
      rate: (json['rate'] as num?)?.toDouble() ?? 0.0,
      amount: (json['amount'] as num?)?.toDouble() ?? 0.0,
    );
  }

  Map<String, dynamic> toJson() => {
        'item_name': itemName,
        'item_code': itemCode,
        'qty': qty,
        'rate': rate,
        'amount': amount,
      };

  InvoiceItem toEntity() => InvoiceItem(
        itemName: itemName,
        itemCode: itemCode,
        qty: qty,
        rate: rate,
        amount: amount,
      );
}

/// Invoice Model
///
/// Model for API parsing only (no Hive storage).
class InvoiceModel {
  final String name;
  final String postingDate;
  final String status;
  final String statusColor;
  final String? orderId;
  final double grandTotal;

  // Detail-only fields
  final String? customerName;
  final SellerInfoModel? sellerInfo;
  final BuyerInfoModel? buyerInfo;
  final List<InvoiceItemModel>? items;
  final double? total;
  final double? discountAmount;

  const InvoiceModel({
    required this.name,
    required this.postingDate,
    required this.status,
    required this.statusColor,
    this.orderId,
    required this.grandTotal,
    this.customerName,
    this.sellerInfo,
    this.buyerInfo,
    this.items,
    this.total,
    this.discountAmount,
  });

  /// Create from JSON (API response - list item)
  factory InvoiceModel.fromJson(Map<String, dynamic> json) {
    return InvoiceModel(
      name: json['name'] as String? ?? '',
      postingDate: json['posting_date'] as String? ?? '',
      status: json['status'] as String? ?? '',
      statusColor: json['status_color'] as String? ?? 'Secondary',
      orderId: json['order_id'] as String?,
      grandTotal: (json['grand_total'] as num?)?.toDouble() ?? 0.0,
      customerName: json['customer_name'] as String?,
      sellerInfo: json['seller_info'] != null
          ? SellerInfoModel.fromJson(json['seller_info'] as Map<String, dynamic>)
          : null,
      buyerInfo: json['buyer_info'] != null
          ? BuyerInfoModel.fromJson(json['buyer_info'] as Map<String, dynamic>)
          : null,
      items: json['items'] != null
          ? (json['items'] as List<dynamic>)
              .map((e) => InvoiceItemModel.fromJson(e as Map<String, dynamic>))
              .toList()
          : null,
      total: (json['total'] as num?)?.toDouble(),
      discountAmount: (json['discount_amount'] as num?)?.toDouble(),
    );
  }

  /// Convert to JSON
  Map<String, dynamic> toJson() => {
        'name': name,
        'posting_date': postingDate,
        'status': status,
        'status_color': statusColor,
        'order_id': orderId,
        'grand_total': grandTotal,
        'customer_name': customerName,
        'seller_info': sellerInfo?.toJson(),
        'buyer_info': buyerInfo?.toJson(),
        'items': items?.map((e) => e.toJson()).toList(),
        'total': total,
        'discount_amount': discountAmount,
      };

  /// Convert to domain entity
  Invoice toEntity() {
    return Invoice(
      name: name,
      postingDate: DateTime.tryParse(postingDate) ?? DateTime.now(),
      status: status,
      statusColor: statusColor,
      orderId: orderId,
      grandTotal: grandTotal,
      customerName: customerName,
      sellerInfo: sellerInfo?.toEntity(),
      buyerInfo: buyerInfo?.toEntity(),
      items: items?.map((e) => e.toEntity()).toList(),
      total: total,
      discountAmount: discountAmount,
    );
  }

  /// Create from domain entity
  factory InvoiceModel.fromEntity(Invoice entity) {
    return InvoiceModel(
      name: entity.name,
      postingDate: entity.postingDate.toIso8601String().split('T').first,
      status: entity.status,
      statusColor: entity.statusColor,
      orderId: entity.orderId,
      grandTotal: entity.grandTotal,
      customerName: entity.customerName,
      total: entity.total,
      discountAmount: entity.discountAmount,
    );
  }

  @override
  String toString() {
    return 'InvoiceModel(name: $name, status: $status, grandTotal: $grandTotal)';
  }
}
