import { business, finance } from '../index.js';
import type { TCurrency } from './currency.js';

/**
 * Status of an accounting document
 * 
 * draft: Document is in preparation (Entwurf)
 * issued: Document has been issued/sent (Ausgestellt)
 * paid: Document has been paid (Bezahlt)
 * canceled: Document has been canceled (Storniert)
 * refunded: Payment has been refunded (Erstattet)
 */
export type TAccountingDocStatus = 'draft' | 'issued' | 'paid' | 'canceled' | 'refunded';

/**
 * Type of accounting document
 * 
 * invoice: Standard invoice (Rechnung)
 * creditnote: Credit note (Gutschrift als Rechnungskorrektur)
 * debitnote: Debit note (Lastschrift/Belastungsanzeige)
 * self-billed-invoice: Self-billed invoice (Gutschrift im Gutschriftverfahren)
 */
export type TAccountingDocType = 'invoice' | 'creditnote' | 'debitnote' | 'self-billed-invoice';

/**
 * Item in an accounting document
 * (Position in einer Rechnung/Gutschrift/Lastschrift)
 */
export type TAccountingDocItem = {
  position: number;
  name: string;
  articleNumber?: string;
  unitType: string;
  unitQuantity: number;
  unitNetPrice: number;
  vatPercentage: number;
};

/**
 * Reference to a related document
 * (Referenz zu einem zugehörigen Dokument)
 */
export type TRelatedDocument = {
  /**
   * Type of relationship
   * (Art der Beziehung)
   */
  relationType: 'corrects' | 'replaces' | 'references';
  
  /**
   * ID of the related document
   * (ID des zugehörigen Dokuments)
   */
  documentId: string;
  
  /**
   * Issue date of the related document
   * (Ausstellungsdatum des zugehörigen Dokuments)
   */
  issueDate?: number;
};

/**
 * Base type for all accounting documents (Basis-Typ für alle Buchungsdokumente)
 */
export type TAccountingDocEnvelope<
  TYPE extends TAccountingDocType,
  FIELDS,
> = business.TLetterEnvelope<
  'accounting-doc',
  {
    /**
     * Unique identifier of the accounting document
     * (Eindeutige Kennung des Buchungsdokuments)
     */
    accountingDocId: string;
    
    /**
     * Type of accounting document
     * (Art des Buchungsdokuments)
     */
    accountingDocType: TYPE;
    
    /**
     * Current status of the accounting document
     * (Aktueller Status des Buchungsdokuments)
     */
    accountingDocStatus: TAccountingDocStatus;
    
    /**
     * Line items of the accounting document
     * (Positionen des Buchungsdokuments)
     */
    items: TAccountingDocItem[];
    
    /**
     * Period of performance/service delivery
     * (Leistungszeitraum)
     */
    periodOfPerformance?: {
      from: number;
      to: number;
    };
    
    /**
     * Date of delivery or service completion
     * (Lieferdatum oder Leistungsdatum)
     */
    deliveryDate?: number;
    
    /**
     * Payment due in days after issue
     * (Zahlungsfrist in Tagen)
     */
    dueInDays: number;
    
    /**
     * Whether reverse charge applies (VAT liability shifted to recipient)
     * (Steuerschuldnerschaft des Leistungsempfängers)
     */
    reverseCharge: boolean;
    
    /**
     * Reference provided by the buyer to identify the document
     * (Referenz des Käufers zur Identifizierung des Dokuments)
     */
    buyerReference?: string;
    
    /**
     * Electronic address information, needed for CII/XRechnung support
     * (Elektronische Adressinformationen, benötigt für CII/XRechnung)
     */
    electronicAddress?: {
      scheme: string;
      value: string;
    };
    
    /**
     * References to related documents (e.g., an invoice referenced by a credit note)
     * (Referenzen zu zugehörigen Dokumenten)
     */
    relatedDocuments?: TRelatedDocument[];
    
    /**
     * Result of document printing/generation
     * (Ergebnis der Dokumentenerstellung)
     */
    printResult?: {
      pdfBufferString: string;
      totalNet: number;
      totalGross: number;
      vatGroups: {
        percentage: number;
        items: TAccountingDocItem[];
      }[];
    };
    
    /**
     * Additional notes or comments
     * (Zusätzliche Anmerkungen oder Kommentare)
     */
    notes: string[];
    
    /**
     * Payment options information
     * (Zahlungsoptionen)
     */
    paymentOptions?: finance.IPaymentOptionInfo;
    
    /**
     * Currency used in the document
     * (Verwendete Währung)
     */
    currency: TCurrency;
  } & FIELDS
>;

/**
 * Credit Note - document reducing amount owed
 * (Gutschrift - Dokument zur Minderung einer Forderung)
 */
export type TCreditNote = TAccountingDocEnvelope<'creditnote', {}>;

/**
 * Debit Note - document increasing amount owed
 * (Lastschrift/Belastungsanzeige - Dokument zur Erhöhung einer Forderung)
 */
export type TDebitNote = TAccountingDocEnvelope<'debitnote', {}>;

/**
 * Standard Invoice
 * (Standardrechnung)
 */
export type TInvoice = TAccountingDocEnvelope<'invoice', {}>;

/**
 * Self-billed Invoice - invoice created by the buyer
 * (Gutschrift im Gutschriftverfahren - vom Käufer erstellte Rechnung)
 */
export type TSelfBilledInvoice = TAccountingDocEnvelope<'self-billed-invoice', {}>;

/**
 * Union type for all accounting document types
 * (Vereinigungstyp für alle Buchungsdokumentarten)
 */
export type TAccountingDoc = TCreditNote | TDebitNote | TInvoice | TSelfBilledInvoice;