/// Domain Entity: Invoice
///
/// Represents an invoice from the API.
/// Used for both list and detail views.
library;

import 'package:equatable/equatable.dart';

/// Seller/Company Information
class SellerInfo extends Equatable {
  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 SellerInfo({
    this.phone,
    this.email,
    this.fax,
    this.taxCode,
    this.companyName,
    this.addressLine1,
    this.cityCode,
    this.wardCode,
    this.cityName,
    this.wardName,
  });

  /// Get formatted full address
  String get fullAddress {
    final parts = <String>[];
    if (addressLine1 != null && addressLine1!.isNotEmpty) {
      parts.add(addressLine1!);
    }
    if (wardName != null && wardName!.isNotEmpty) {
      parts.add(wardName!);
    }
    if (cityName != null && cityName!.isNotEmpty) {
      parts.add(cityName!);
    }
    return parts.join(', ');
  }

  @override
  List<Object?> get props => [
        phone,
        email,
        fax,
        taxCode,
        companyName,
        addressLine1,
        cityCode,
        wardCode,
        cityName,
        wardName,
      ];
}

/// Buyer/Customer Information
class BuyerInfo extends Equatable {
  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 BuyerInfo({
    this.name,
    this.addressTitle,
    this.addressLine1,
    this.phone,
    this.email,
    this.fax,
    this.taxCode,
    this.cityCode,
    this.wardCode,
    this.cityName,
    this.wardName,
    this.customerName
  });

  /// Get formatted full address
  String get fullAddress {
    final parts = <String>[];
    if (addressLine1 != null && addressLine1!.isNotEmpty) {
      parts.add(addressLine1!);
    }
    if (wardName != null && wardName!.isNotEmpty) {
      parts.add(wardName!);
    }
    if (cityName != null && cityName!.isNotEmpty) {
      parts.add(cityName!);
    }
    return parts.join(', ');
  }

  @override
  List<Object?> get props => [
        name,
        addressTitle,
        addressLine1,
        phone,
        email,
        fax,
        taxCode,
        cityCode,
        wardCode,
        cityName,
        wardName,
        customerName
      ];
}

/// Invoice Line Item
class InvoiceItem extends Equatable {
  final String itemName;
  final String itemCode;
  final double qty;
  final double rate;
  final double amount;

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

  @override
  List<Object?> get props => [itemName, itemCode, qty, rate, amount];
}

/// Invoice Entity
///
/// Contains invoice information from API:
/// - name: Invoice ID (e.g., "ACC-SINV-2025-00041")
/// - postingDate: Invoice date
/// - status: Status label (Vietnamese)
/// - statusColor: Status color (Danger, Success, etc.)
/// - orderId: Related order ID (nullable)
/// - grandTotal: Total amount
/// - customerName: Customer name (detail only)
/// - sellerInfo: Seller company info (detail only)
/// - buyerInfo: Buyer info (detail only)
/// - items: Invoice line items (detail only)
/// - total: Subtotal before discount (detail only)
/// - discountAmount: Discount amount (detail only)
class Invoice extends Equatable {
  /// Invoice ID (e.g., "ACC-SINV-2025-00041")
  final String name;

  /// Invoice posting date
  final DateTime postingDate;

  /// Status label (Vietnamese)
  final String status;

  /// Status color (Danger, Success, Warning, etc.)
  final String statusColor;

  /// Related order ID (nullable)
  final String? orderId;

  /// Grand total amount
  final double grandTotal;

  // Detail-only fields (nullable for list view)

  /// Customer name
  final String? customerName;

  /// Seller company information
  final SellerInfo? sellerInfo;

  /// Buyer information
  final BuyerInfo? buyerInfo;

  /// Invoice line items
  final List<InvoiceItem>? items;

  /// Subtotal before discount
  final double? total;

  /// Discount amount
  final double? discountAmount;

  const Invoice({
    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,
  });

  /// Check if this is a detail invoice (has all detail fields)
  bool get isDetail => sellerInfo != null && buyerInfo != null && items != null;

  /// Get formatted posting date
  String get formattedDate {
    return '${postingDate.day.toString().padLeft(2, '0')}/${postingDate.month.toString().padLeft(2, '0')}/${postingDate.year}';
  }

  /// Copy with method for immutability
  Invoice copyWith({
    String? name,
    DateTime? postingDate,
    String? status,
    String? statusColor,
    String? orderId,
    double? grandTotal,
    String? customerName,
    SellerInfo? sellerInfo,
    BuyerInfo? buyerInfo,
    List<InvoiceItem>? items,
    double? total,
    double? discountAmount,
  }) {
    return Invoice(
      name: name ?? this.name,
      postingDate: postingDate ?? this.postingDate,
      status: status ?? this.status,
      statusColor: statusColor ?? this.statusColor,
      orderId: orderId ?? this.orderId,
      grandTotal: grandTotal ?? this.grandTotal,
      customerName: customerName ?? this.customerName,
      sellerInfo: sellerInfo ?? this.sellerInfo,
      buyerInfo: buyerInfo ?? this.buyerInfo,
      items: items ?? this.items,
      total: total ?? this.total,
      discountAmount: discountAmount ?? this.discountAmount,
    );
  }

  @override
  List<Object?> get props => [
        name,
        postingDate,
        status,
        statusColor,
        orderId,
        grandTotal,
        customerName,
        sellerInfo,
        buyerInfo,
        items,
        total,
        discountAmount,
      ];

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