/**
 * Sales Invoice Domain Model
 * Pure domain logic with no dependencies on infrastructure or infrastructure
 * This represents the core business logic for a sales invoice
 */

export type SalesInvoiceStatus = 'active' | 'delivered' | 'cancelled';
export type SalesInvoicePaymentStatus = 'due' | 'partial' | 'paid' | 'overdue';
export type SalesInvoicePostingStatus = 'draft' | 'saved' | 'posted';
export type SalesInvoiceShippingStatus = 'pending' | 'shipped' | 'partial' | 'delivered' | 'cancelled';
export type PaymentMethod = 'cash' | 'check' | 'bank_transfer' | 'credit';
export type TaxMethod = 'tax-inclusive' | 'invoice-level' | 'line-level' | 'tax-exempt';

/**
 * Core sales invoice entity - represents a sales transaction
 */
export type SalesInvoice = {
  readonly id: string;
  readonly invoiceNumber: string;                    // S/YYYY/XXXX
  readonly date: string;                            // ISO date
  readonly manualDocNumber?: string;                // Optional external/manual reference
  
  // Customer Information
  readonly customerId: string;
  readonly customerName: string;
  readonly secondaryCustomerId?: string;
  readonly secondaryCustomerName?: string;
  readonly primaryCoveragePercent?: number;
  readonly secondaryCoveragePercent?: number;
  readonly primaryCoverageAmount?: number;
  readonly secondaryCoverageAmount?: number;
  readonly customerCategory?: string;               // 'general' | 'vip' | 'retail'
  
  // Sales Rep (optional)
  readonly salesRepId?: string;
  readonly salesRepName?: string;
  
  // Currency & Exchange
  readonly currencyCode?: string;                   // USD, EUR, JOD, etc
  readonly baseCurrencyCode?: string;               // System base currency
  readonly exchangeRate?: number;                   // Base per 1 unit of currency
  readonly rateDate?: string;
  readonly rateSource?: string;
  readonly isAutoRate?: boolean;
  
  // Line Items
  readonly items: SalesInvoiceItem[];
  readonly subTotal: number;                        // Sum of (qty × price)
  
  // Discounts
  readonly lineDiscountTotal?: number;              // Sum of all line discounts
  readonly invoiceDiscountPercent?: number;
  readonly invoiceDiscountAmount?: number;
  readonly totalDiscount?: number;
  
  // Tax
  readonly taxMethod?: TaxMethod;
  readonly taxExemptionReason?: string;
  readonly taxExemptionReference?: string;
  readonly taxAmount?: number;
  
  // Totals
  readonly grandTotal: number;
  readonly grandTotalBase?: number;                 // At exchange rate of date
  
  // Payment Status
  readonly amountDue: number;                       // Remaining to receive
  readonly amountReceived: number;
  readonly amountDueBase?: number;
  readonly amountReceivedBase?: number;
  
  readonly paymentMethods?: SalesInvoicePaymentMethod[];
  
  // Real Estate Sale Contract (optional)
  readonly realEstateProjectId?: string;
  readonly realEstateProjectName?: string;
  readonly realEstateUnitId?: string;
  readonly realEstateUnitName?: string;
  readonly realEstateContractNumber?: string;
  readonly realEstateContractDate?: string;
  readonly realEstateHandoverDate?: string;
  readonly realEstateContractValue?: number;
  readonly realEstateDownPayment?: number;
  readonly realEstateDeferredAmount?: number;
  readonly realEstateInstallmentMode?: 'existing' | 'auto';
  readonly realEstateInstallmentCount?: number;
  readonly realEstateFirstDueDate?: string;
  readonly realEstateInstallmentInterval?: 'monthly' | 'quarterly';
  
  // Shipping
  readonly shipmentId?: string;
  readonly shipmentDate?: string;
  readonly shippingAddress?: string;
  readonly deliveryLocation?: string;
  readonly expectedDeliveryDate?: string;
  readonly actualDeliveryDate?: string;
  
  // Status
  readonly postingStatus?: SalesInvoicePostingStatus;
  readonly shippingStatus?: SalesInvoiceShippingStatus;
  readonly paymentStatus?: SalesInvoicePaymentStatus;
  readonly status: SalesInvoiceStatus;
  
  // Additional
  readonly customerNotes?: string;                  // Visible on invoice
  readonly internalNotes?: string;                  // For company use
  
  // Locking (for concurrent edit protection)
  readonly lockedById?: string;
  readonly lockedByName?: string;
  readonly lockedAt?: string;
  
  // Documents
  readonly documents?: SalesInvoiceDocument[];
  
  // Activity Log
  readonly activityLog?: SalesInvoiceLogEntry[];
  
  // Metadata
  readonly createdBy: string;
  readonly createdAt: string;
  readonly shippedBy?: string;
  readonly shippedAt?: string;
  readonly cancelledBy?: string;
  readonly cancelledAt?: string;
  readonly cancelledReason?: string;

  // Whether this is a delivery note (inventory only, no accounting) or a full tax invoice
  readonly documentType?: 'shipment' | 'tax_invoice';

  // Shipment ↔ Tax Invoice linking
  // For tax invoices: IDs of shipments that this invoice settles
  readonly linkedShipmentIds?: string[];
  // For shipments: ID of the tax invoice that was issued for this shipment
  readonly taxInvoiceId?: string;
};

/**
 * Individual line item in a sales invoice
 */
export type SalesInvoiceItem = {
  readonly materialId: string;
  readonly name: string;
  readonly realEstateProjectId?: string;
  readonly realEstateProjectName?: string;
  readonly realEstateUnitId?: string;
  readonly realEstateUnitName?: string;
  readonly quantity: number;
  readonly unitPrice: number;
  readonly total: number;                          // qty × unitPrice
  
  readonly lineDiscountPercent?: number;
  readonly lineDiscountAmount?: number;
  
  readonly warehouseId?: string;                   // Source warehouse
  readonly shelfId?: string;
  readonly printSectionId?: string;                // Kitchen / bar / dessert routing
  readonly printLabel?: string;                    // Short label for prep ticket
  readonly excludeFromPrepTicket?: boolean;
  
  readonly taxRate?: number;
  readonly taxAmount?: number;
  
  readonly shippedQuantity?: number;               // For partial shipments
  readonly returnedQuantity?: number;              // For returns tracking
  readonly description?: string;
  readonly serialNumber?: string;
  readonly rfidCode?: string;
};

/**
 * Payment method allocation for a sales invoice
 */
export type SalesInvoicePaymentMethod = {
  readonly method: PaymentMethod;
  readonly amount: number;
  readonly date?: string;
  readonly currency?: string;
  readonly reference?: string;
  // For checks:
  readonly checkNumber?: string;
  readonly checkDate?: string;
  readonly bankId?: string;
  readonly bankName?: string;
  readonly status?: 'pending' | 'cleared' | 'rejected' | 'returned';
  readonly incomingCheckId?: string;
};

/**
 * Document attachment
 */
export type SalesInvoiceDocument = {
  readonly id: string;
  readonly fileName: string;
  readonly fileUrl: string;
  readonly uploadedAt: string;
  readonly uploadedBy: string;
};

/**
 * Activity log entry
 */
export type SalesInvoiceLogEntry = {
  readonly id: string;
  readonly timestamp: string;
  readonly action: 'created' | 'updated' | 'posted' | 'shipped' | 'received' | 'cancelled' | 'notes';
  readonly message: string;
  readonly by: string;
  readonly byName?: string;
  readonly details?: Record<string, unknown>;
};

/**
 * DTO for creating a sales invoice
 */
export type CreateSalesInvoiceRecord = {
  customerId: string;
  secondaryCustomerId?: string;
  primaryCoveragePercent?: number;
  secondaryCoveragePercent?: number;
  primaryCoverageAmount?: number;
  secondaryCoverageAmount?: number;
  date: string;
  manualDocNumber?: string;
  items: Array<{
    materialId: string;
    quantity: number;
    unitPrice: number;
    realEstateProjectId?: string;
    realEstateProjectName?: string;
    realEstateUnitId?: string;
    realEstateUnitName?: string;
    lineDiscountPercent?: number;
    lineDiscountAmount?: number;
    taxRate?: number;
    warehouseId?: string;
    shelfId?: string;
  }>;
  salesRepId?: string;
  currencyCode?: string;
  exchangeRate?: number;
  rateSource?: string;
  invoiceDiscountPercent?: number;
  invoiceDiscountAmount?: number;
  amountReceived: number;
  paymentMethods?: SalesInvoicePaymentMethod[];
  realEstateProjectId?: string;
  realEstateProjectName?: string;
  realEstateUnitId?: string;
  realEstateUnitName?: string;
  realEstateContractNumber?: string;
  realEstateContractDate?: string;
  realEstateHandoverDate?: string;
  realEstateContractValue?: number;
  realEstateDownPayment?: number;
  realEstateDeferredAmount?: number;
  realEstateInstallmentMode?: 'existing' | 'auto';
  realEstateInstallmentCount?: number;
  realEstateFirstDueDate?: string;
  realEstateInstallmentInterval?: 'monthly' | 'quarterly';
  customerNotes?: string;
  internalNotes?: string;
  taxMethod?: TaxMethod;
  taxExemptionReason?: string;
  taxExemptionReference?: string;
  postingStatus?: SalesInvoicePostingStatus;
  shippingStatus?: SalesInvoiceShippingStatus;
  documentType?: 'shipment' | 'tax_invoice';
  linkedShipmentIds?: string[];
};
