/**
 * Sales Return Domain Model
 * Represents returns of goods from customers back to the vendor
 * Supports partial returns and multiple return statuses
 */

export type SalesReturnStatus = 'pending' | 'approved' | 'received' | 'processed' | 'rejected' | 'cancelled';
export type SalesReturnReason = 'defective' | 'wrong_item' | 'customer_request' | 'quality_issue' | 'damaged' | 'other';

/**
 * Core sales return entity - represents a return transaction
 */
export type SalesReturn = {
  readonly id: string;
  readonly returnNumber: string;                   // R/YYYY/XXXX format
  readonly date: string;                           // ISO date - when return was initiated
  
  // Reference to original invoice
  readonly invoiceId: string;
  readonly invoiceNumber: string;
  readonly originalInvoiceDate: string;
  
  // Customer Information
  readonly customerId: string;
  readonly customerName: string;
  
  // Currency information
  readonly currencyCode?: string;
  readonly exchangeRate?: number;
  
  // Return Items
  readonly items: SalesReturnItem[];
  readonly subTotal: number;                      // Sum of returned items value
  readonly taxAmount?: number;
  readonly totalAmount: number;                   // Total return amount
  
  // Credit Note
  readonly creditNoteId?: string;                 // If credit note was issued
  readonly creditNoteNumber?: string;
  
  // Refund Information
  readonly refundAmount?: number;                 // Amount to be refunded
  readonly refundDueDate?: string;
  readonly refundIssuedDate?: string;
  readonly refundMethod?: 'cash' | 'check' | 'bank_transfer' | 'credit_to_account';
  readonly refundReference?: string;              // Check#, transfer ref, etc
  
  // Status
  readonly status: SalesReturnStatus;
  readonly rejectionReason?: string;              // If status = 'rejected'
  readonly approvalDate?: string;
  readonly approvalBy?: string;
  readonly approvalByName?: string;
  
  // Receiving
  readonly receivedDate?: string;
  readonly receivedBy?: string;
  readonly receivedByName?: string;
  readonly receivedQuantity?: number;             // Total qty received
  readonly receivedNotes?: string;
  
  // Processing
  readonly processedDate?: string;
  readonly processedBy?: string;
  readonly processedByName?: string;
  readonly processingNotes?: string;
  
  // Shipping (return to warehouse)
  readonly shipmentId?: string;
  readonly expectedReturnDate?: string;
  readonly actualReturnDate?: string;
  
  // Reason & Documentation
  readonly primaryReason: SalesReturnReason;
  readonly reasonDescription: string;
  readonly documents?: SalesReturnDocument[];
  
  // Customer Notes & Internal Notes
  readonly customerNotes?: string;
  readonly internalNotes?: string;
  
  // Activity Log
  readonly activityLog?: SalesReturnLogEntry[];
  
  // Metadata
  readonly createdBy: string;
  readonly createdAt: string;
  readonly updatedBy?: string;
  readonly updatedAt?: string;
  readonly cancelledBy?: string;
  readonly cancelledAt?: string;
  readonly cancelledReason?: string;
};

/**
 * Individual item being returned
 */
export type SalesReturnItem = {
  readonly lineId: string;                        // Reference to original invoice line
  readonly materialId: string;
  readonly name: string;
  readonly returnedQuantity: number;              // How many units returned
  readonly originalQuantity: number;              // How many were on invoice
  readonly unitPrice: number;                     // Original unit price
  readonly returnValue: number;                   // returnedQuantity × unitPrice
  
  // Condition Assessment
  readonly condition: 'good' | 'damaged' | 'defective' | 'faulty';
  readonly conditionNotes?: string;
  
  // Restocking
  readonly restockable: boolean;                  // Can it be resold?
  readonly restockedDate?: string;
  readonly restockWarehouseId?: string;
  readonly restockShelfId?: string;
  
  // Reference
  readonly warehouseId?: string;
  readonly shelfId?: string;
  readonly serialNumber?: string;
  readonly rfidCode?: string;
  
  // Tracking
  readonly inspectionDate?: string;
  readonly inspectionBy?: string;
  readonly inspectionNotes?: string;
};

/**
 * Document attachment for a return
 */
export type SalesReturnDocument = {
  readonly id: string;
  readonly fileName: string;
  readonly fileUrl: string;
  readonly documentType: 'photo' | 'certificate' | 'receipt' | 'other';
  readonly uploadedAt: string;
  readonly uploadedBy: string;
};

/**
 * Activity log entry for return lifecycle
 */
export type SalesReturnLogEntry = {
  readonly id: string;
  readonly timestamp: string;
  readonly action: 
    | 'created' 
    | 'submitted' 
    | 'approved' 
    | 'received' 
    | 'inspected' 
    | 'processed' 
    | 'credited' 
    | 'refunded'
    | 'rejected'
    | 'cancelled';
  readonly message: string;
  readonly by: string;
  readonly byName?: string;
  readonly details?: Record<string, unknown>;
};

/**
 * DTO for creating a sales return
 */
export type CreateSalesReturnRecord = {
  invoiceId: string;
  date: string;
  primaryReason: SalesReturnReason;
  reasonDescription: string;
  items: Array<{
    lineId: string;
    materialId: string;
    returnedQuantity: number;
    condition: 'good' | 'damaged' | 'defective' | 'faulty';
    conditionNotes?: string;
    inspectionNotes?: string;
  }>;
  customerNotes?: string;
  internalNotes?: string;
  documents?: Array<{
    fileName: string;
    fileUrl: string;
    documentType: 'photo' | 'certificate' | 'receipt' | 'other';
  }>;
};

/**
 * DTO for approving a return
 */
export type ApproveSalesReturnRecord = {
  returnId: string;
  approvalDate: string;
};

/**
 * DTO for receiving a returned shipment
 */
export type ReceiveSalesReturnRecord = {
  returnId: string;
  receivedDate: string;
  receivedQuantity: number;
  receivedNotes?: string;
};

/**
 * DTO for processing an approved return
 */
export type ProcessSalesReturnRecord = {
  returnId: string;
  processedDate: string;
  creditNoteId?: string;
  refundAmount: number;
  refundMethod: 'cash' | 'check' | 'bank_transfer' | 'credit_to_account';
  refundReference?: string;
  processingNotes?: string;
};

/**
 * DTO for rejecting a return
 */
export type RejectSalesReturnRecord = {
  returnId: string;
  rejectionReason: string;
};
