import { BaseDecoder } from '../base/base.decoder.js';
import { InvoiceFormat } from '../../interfaces/common.js';
import { FormatDetector } from '../utils/format.detector.js';

// Import specific decoders
import { XRechnungDecoder } from '../ubl/xrechnung/xrechnung.decoder.js';
import { FacturXDecoder } from '../cii/facturx/facturx.decoder.js';
import { ZUGFeRDDecoder } from '../cii/zugferd/zugferd.decoder.js';
import { ZUGFeRDV1Decoder } from '../cii/zugferd/zugferd.v1.decoder.js';

/**
 * Factory to create the appropriate decoder based on the XML format
 */
export class DecoderFactory {
  /**
   * Creates a decoder for the specified XML content
   * @param xml XML content to decode
   * @returns Appropriate decoder instance
   */
  public static createDecoder(xml: string): BaseDecoder {
    const format = FormatDetector.detectFormat(xml);

    switch (format) {
      case InvoiceFormat.UBL:
      case InvoiceFormat.XRECHNUNG:
        return new XRechnungDecoder(xml);

      case InvoiceFormat.CII:
        // For now, use Factur-X decoder for generic CII
        return new FacturXDecoder(xml);

      case InvoiceFormat.ZUGFERD:
        // Determine if it's ZUGFeRD v1 or v2 based on root element
        if (xml.includes('CrossIndustryDocument') ||
            xml.includes('urn:ferd:CrossIndustryDocument:invoice:1p0') ||
            (xml.includes('ZUGFeRD') && !xml.includes('CrossIndustryInvoice'))) {
          return new ZUGFeRDV1Decoder(xml);
        } else {
          return new ZUGFeRDDecoder(xml);
        }

      case InvoiceFormat.FACTURX:
        return new FacturXDecoder(xml);

      case InvoiceFormat.FATTURAPA:
        // return new FatturaPADecoder(xml);
        throw new Error('FatturaPA decoder not yet implemented');

      default:
        // If format is unknown but contains CrossIndustryInvoice, try ZUGFeRD decoder
        if (xml.includes('CrossIndustryInvoice')) {
          return new ZUGFeRDDecoder(xml);
        }
        // If format is unknown but contains CrossIndustryDocument, try ZUGFeRD v1 decoder
        if (xml.includes('CrossIndustryDocument')) {
          return new ZUGFeRDV1Decoder(xml);
        }
        throw new Error(`Unsupported invoice format: ${format}`);
    }
  }
}