import { Invoice } from '../../types/invoice.types';
import fs from 'fs';
import path from 'path';

export interface ZUGFeRDOptions {
  profile?: 'BASIC' | 'COMFORT' | 'EXTENDED';
  version?: '2.1.1' | '2.2.0';
  conformanceLevel?: 'A' | 'B' | 'U';
  outputFormat?: 'PDF/A-3' | 'PDF/A-3b';
}

export class ZUGFeRDPDFA3Generator {
  private invoice: Invoice;
  private options: Required<ZUGFeRDOptions>;

  constructor(invoice: Invoice, options: ZUGFeRDOptions = {}) {
    this.invoice = invoice;
    this.options = {
      profile: 'BASIC',
      version: '2.1.1',
      conformanceLevel: 'A',
      outputFormat: 'PDF/A-3',
      ...options
    };
  }

  /**
   * Generiert eine vollständige ZUGFeRD-konforme PDF/A-3 Datei
   * Hinweis: Für echte PDF/A-3 Implementierung wird eine spezielle Library benötigt
   */
  public async generateZUGFeRDPDFA3(outputPath: string): Promise<void> {
    try {
      // Generiere XML-Inhalt
      const xmlContent = this.generateZUGFeRDXML();
      
      // Speichere XML separat (für Testzwecke)
      const xmlPath = outputPath.replace('.pdf', '.xml');
      fs.writeFileSync(xmlPath, xmlContent, 'utf8');
      
      // Generiere PDF mit eingebettetem XML
      await this.generatePDFWithEmbeddedXML(outputPath, xmlContent);
      
      console.log(`✅ ZUGFeRD PDF/A-3 erfolgreich erstellt: ${outputPath}`);
      console.log(`📄 XML-Inhalt gespeichert: ${xmlPath}`);
      
    } catch (error) {
      console.error('❌ Fehler beim Erstellen der ZUGFeRD PDF/A-3:', error);
      throw error;
    }
  }

  /**
   * Generiert das ZUGFeRD-konforme XML
   */
  private generateZUGFeRDXML(): string {
    const profile = this.getProfileIdentifier();
    
    const xml = `<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:ferd:CrossIndustryDocument:invoice:2p0" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:TestIndicator>
      <udt:Indicator>false</udt:Indicator>
    </ram:TestIndicator>
    <ram:BusinessProcessSpecifiedDocumentContextParameter>
      <ram:ID>${profile}</ram:ID>
    </ram:BusinessProcessSpecifiedDocumentContextParameter>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>${this.escapeXml(this.invoice.details.invoiceNumber)}</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">${this.formatDate(this.invoice.details.invoiceDate)}</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:IncludedSupplyChainTradeLineItem>
${this.generateLineItems()}
    </ram:IncludedSupplyChainTradeLineItem>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>${this.escapeXml(this.invoice.sender.name)}</ram:Name>
        <ram:PostalTradeAddress>
          <ram:LineOne>${this.escapeXml(this.invoice.sender.address.street)}</ram:LineOne>
          <ram:CityName>${this.escapeXml(this.invoice.sender.address.city)}</ram:CityName>
          <ram:PostcodeCode>${this.escapeXml(this.invoice.sender.address.postalCode)}</ram:PostcodeCode>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="FC">${this.escapeXml(this.invoice.sender.vatId || '')}</ram:ID>
        </ram:SpecifiedTaxRegistration>
        <ram:DefinedTradeContact>
          <ram:PersonName>${this.escapeXml(this.invoice.sender.businessOwner || '')}</ram:PersonName>
          <ram:TelephoneUniversalCommunication>
            <ram:CompleteNumber>${this.escapeXml(this.invoice.sender.contactInfo.phone)}</ram:CompleteNumber>
          </ram:TelephoneUniversalCommunication>
          <ram:EmailURIUniversalCommunication>
            <ram:URIID>${this.escapeXml(this.invoice.sender.contactInfo.email)}</ram:URIID>
          </ram:EmailURIUniversalCommunication>
        </ram:DefinedTradeContact>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>${this.escapeXml(this.invoice.recipient.name)}</ram:Name>
        <ram:PostalTradeAddress>
          <ram:LineOne>${this.escapeXml(this.invoice.recipient.address.street)}</ram:LineOne>
          <ram:CityName>${this.escapeXml(this.invoice.recipient.address.city)}</ram:CityName>
          <ram:PostcodeCode>${this.escapeXml(this.invoice.recipient.address.postalCode)}</ram:PostcodeCode>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>${this.invoice.totals.currency}</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementPaymentMeans>
        <ram:TypeCode>30</ram:TypeCode>
        <ram:Information>${this.escapeXml(this.invoice.paymentInfo.bank)}</ram:Information>
        <ram:PayeePartyCreditorFinancialAccount>
          <ram:IBANID>${this.escapeXml(this.invoice.paymentInfo.iban)}</ram:IBANID>
        </ram:PayeePartyCreditorFinancialAccount>
        <ram:PayeeSpecifiedCreditorFinancialInstitution>
          <ram:BICID>${this.escapeXml(this.invoice.paymentInfo.bic)}</ram:BICID>
        </ram:PayeeSpecifiedCreditorFinancialInstitution>
      </ram:SpecifiedTradeSettlementPaymentMeans>
      <ram:ApplicableTradeTax>
        <ram:CalculatedAmount>${this.invoice.totals.vatAmount.toFixed(2)}</ram:CalculatedAmount>
        <ram:TypeCode>VAT</ram:TypeCode>
        <ram:BasisAmount>${this.invoice.totals.netAmount.toFixed(2)}</ram:BasisAmount>
        <ram:ApplicablePercent>${this.invoice.totals.vatRate.toFixed(2)}</ram:ApplicablePercent>
      </ram:ApplicableTradeTax>
      <ram:SpecifiedTradePaymentTerms>
        <ram:Description>${this.escapeXml(this.invoice.paymentInfo.paymentTerms)}</ram:Description>
      </ram:SpecifiedTradePaymentTerms>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>${this.invoice.totals.netAmount.toFixed(2)}</ram:LineTotalAmount>
        <ram:TaxBasisTotalAmount>${this.invoice.totals.netAmount.toFixed(2)}</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount>${this.invoice.totals.vatAmount.toFixed(2)}</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>${this.invoice.totals.grossAmount.toFixed(2)}</ram:GrandTotalAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>`;

    return xml;
  }

  /**
   * Generiert die einzelnen Rechnungspositionen
   */
  private generateLineItems(): string {
    return this.invoice.items.map((item, index) => `
      <ram:IncludedSupplyChainTradeLineItem>
        <ram:AssociatedDocumentLineDocument>
          <ram:LineID>${index + 1}</ram:LineID>
        </ram:AssociatedDocumentLineDocument>
        <ram:SpecifiedTradeProduct>
          <ram:Name>${this.escapeXml(item.description)}</ram:Name>
        </ram:SpecifiedTradeProduct>
        <ram:SpecifiedLineTradeAgreement>
          <ram:NetPriceProductTradePrice>
            <ram:ChargeAmount>${item.unitPrice.toFixed(2)}</ram:ChargeAmount>
          </ram:NetPriceProductTradePrice>
        </ram:SpecifiedLineTradeAgreement>
        <ram:SpecifiedLineTradeDelivery>
          <ram:BilledQuantity>${item.quantity}</ram:BilledQuantity>
        </ram:SpecifiedLineTradeDelivery>
        <ram:SpecifiedLineTradeSettlement>
          <ram:ApplicableTradeTax>
            <ram:TypeCode>VAT</ram:TypeCode>
            <ram:ApplicablePercent>${item.vatRate.toFixed(2)}</ram:ApplicablePercent>
          </ram:ApplicableTradeTax>
          <ram:SpecifiedTradeSettlementLineMonetarySummation>
            <ram:LineTotalAmount>${item.total.toFixed(2)}</ram:LineTotalAmount>
          </ram:SpecifiedTradeSettlementLineMonetarySummation>
        </ram:SpecifiedLineTradeSettlement>
      </ram:IncludedSupplyChainTradeLineItem>`).join('');
  }

  /**
   * Ermittelt den korrekten Profil-Identifier basierend auf ZUGFeRD-Version und Profil
   */
  private getProfileIdentifier(): string {
    const { profile, version } = this.options;
    
    const profileMap: Record<string, Record<string, string>> = {
      '2.1.1': {
        'BASIC': 'urn:ferd:CrossIndustryDocument:invoice:2p0:basic',
        'COMFORT': 'urn:ferd:CrossIndustryDocument:invoice:2p0:comfort',
        'EXTENDED': 'urn:ferd:CrossIndustryDocument:invoice:2p0:extended'
      },
      '2.2.0': {
        'BASIC': 'urn:ferd:CrossIndustryDocument:invoice:2p0:basic',
        'COMFORT': 'urn:ferd:CrossIndustryDocument:invoice:2p0:comfort',
        'EXTENDED': 'urn:ferd:CrossIndustryDocument:invoice:2p0:extended'
      }
    };

    return profileMap[version]?.[profile] || profileMap['2.1.1']['BASIC'];
  }

  /**
   * Generiert PDF mit eingebettetem XML
   * Hinweis: Echte PDF/A-3 Implementierung erfordert spezielle Libraries
   */
  private async generatePDFWithEmbeddedXML(outputPath: string, xmlContent: string): Promise<void> {
    // Für diese Demo-Implementierung erstellen wir eine normale PDF
    // In einer echten Implementierung würde hier eine PDF/A-3 Library verwendet werden
    
    const { generateInvoicePDFToFile } = await import('../pdf-generator');
    
    // Erstelle normale PDF (ohne PDF/A-3 Features)
    await generateInvoicePDFToFile(this.invoice, outputPath, {
      template: 'default',
      language: 'de',
      includeLogo: false
    });

    console.log('⚠️  Hinweis: Echte PDF/A-3 Implementierung erfordert spezielle Libraries wie pdf-lib oder ähnliche');
    console.log('📄 XML-Inhalt wurde separat gespeichert und kann manuell in PDF/A-3 eingebettet werden');
  }

  /**
   * Validiert die ZUGFeRD-Konformität
   */
  public validateZUGFeRDConformance(): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];

    // Grundlegende Validierungen
    if (!this.invoice.details.invoiceNumber) {
      errors.push('Rechnungsnummer ist erforderlich');
    }

    if (!this.invoice.sender.vatId) {
      errors.push('USt-IdNr. des Absenders ist erforderlich');
    }

    if (!this.invoice.paymentInfo.iban) {
      errors.push('IBAN ist erforderlich');
    }

    if (this.invoice.items.length === 0) {
      errors.push('Mindestens eine Rechnungsposition ist erforderlich');
    }

    // Profil-spezifische Validierungen
    if (this.options.profile === 'COMFORT' || this.options.profile === 'EXTENDED') {
      if (!this.invoice.sender.businessOwner) {
        errors.push('Geschäftsinhaber ist für COMFORT/EXTENDED Profile erforderlich');
      }
    }

    return {
      isValid: errors.length === 0,
      errors
    };
  }

  private escapeXml(text: string): string {
    return text
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&apos;');
  }

  private formatDate(dateString: string): string {
    // Konvertiere DD.MM.YY zu YYYYMMDD
    const parts = dateString.split('.');
    if (parts.length === 3) {
      const day = parts[0].padStart(2, '0');
      const month = parts[1].padStart(2, '0');
      const year = '20' + parts[2]; // Annahme: 20xx
      return `${year}${month}${day}`;
    }
    return dateString;
  }
} 