// Import main class
import { XInvoice } from './classes.xinvoice.js';

// Import interfaces
import * as common from './interfaces/common.js';

// Import factories
import { DecoderFactory } from './formats/factories/decoder.factory.js';
import { EncoderFactory } from './formats/factories/encoder.factory.js';
import { ValidatorFactory } from './formats/factories/validator.factory.js';

// Import base classes
import { BaseDecoder } from './formats/base/base.decoder.js';
import { BaseEncoder } from './formats/base/base.encoder.js';
import { BaseValidator } from './formats/base/base.validator.js';

// Import UBL base classes
import { UBLBaseDecoder } from './formats/ubl/ubl.decoder.js';
import { UBLBaseEncoder } from './formats/ubl/ubl.encoder.js';
import { UBLBaseValidator } from './formats/ubl/ubl.validator.js';

// Import CII base classes
import { CIIBaseDecoder } from './formats/cii/cii.decoder.js';
import { CIIBaseEncoder } from './formats/cii/cii.encoder.js';
import { CIIBaseValidator } from './formats/cii/cii.validator.js';

// Import PDF utilities
import { PDFEmbedder } from './formats/pdf/pdf.embedder.js';
import { PDFExtractor } from './formats/pdf/pdf.extractor.js';
import {
  BaseXMLExtractor,
  StandardXMLExtractor,
  AssociatedFilesExtractor,
  TextXMLExtractor
} from './formats/pdf/extractors/index.js';

// Import format detector
import { FormatDetector } from './formats/utils/format.detector.js';

// Import Factur-X implementation
import { FacturXDecoder } from './formats/cii/facturx/facturx.decoder.js';
import { FacturXEncoder } from './formats/cii/facturx/facturx.encoder.js';
import { FacturXValidator } from './formats/cii/facturx/facturx.validator.js';

// Import ZUGFeRD implementation
import { ZUGFeRDDecoder } from './formats/cii/zugferd/zugferd.decoder.js';
import { ZUGFeRDEncoder } from './formats/cii/zugferd/zugferd.encoder.js';
import { ZUGFeRDValidator } from './formats/cii/zugferd/zugferd.validator.js';
import { ZUGFeRDV1Decoder } from './formats/cii/zugferd/zugferd.v1.decoder.js';

// Export interfaces
export type {
  // Common interfaces
  TInvoice,
  TCreditNote,
  TDebitNote,
  TContact,
  TLetterEnvelope,
  TDocumentEnvelope,
  IPdf,

  // Validation interfaces
  ValidationError,
  ValidationResult,
  IValidator,

  // Format interfaces
  ExportFormat,
  XInvoiceOptions
} from './interfaces/common.js';

export { ValidationLevel, InvoiceFormat } from './interfaces/common.js';

// Export interfaces (legacy support)
export { common as interfaces };

// Export main class
export { XInvoice };

// Export factories
export { DecoderFactory, EncoderFactory, ValidatorFactory };

// Export base classes
export { BaseDecoder, BaseEncoder, BaseValidator };

// Export UBL base classes
export { UBLBaseDecoder, UBLBaseEncoder, UBLBaseValidator };

// Export CII base classes
export { CIIBaseDecoder, CIIBaseEncoder, CIIBaseValidator };

// Export Factur-X implementation
export { FacturXDecoder, FacturXEncoder, FacturXValidator };

// Export ZUGFeRD implementation
export { ZUGFeRDDecoder, ZUGFeRDEncoder, ZUGFeRDValidator, ZUGFeRDV1Decoder };

// Export PDF utilities
export {
  PDFEmbedder,
  PDFExtractor,
  BaseXMLExtractor,
  StandardXMLExtractor,
  AssociatedFilesExtractor,
  TextXMLExtractor
};

// Export format detector
export { FormatDetector };

/**
 * Validates an XML string against the appropriate format rules
 * @param xml XML content to validate
 * @param level Validation level (syntax, semantic, business)
 * @returns ValidationResult with the result of validation
 */
export function validateXml(
  xml: string,
  level: common.ValidationLevel = common.ValidationLevel.SYNTAX
): common.ValidationResult {
  try {
    const validator = ValidatorFactory.createValidator(xml);
    return validator.validate(level);
  } catch (error) {
    return {
      valid: false,
      errors: [{
        code: 'VAL-ERROR',
        message: `Validation error: ${error.message}`
      }],
      level
    };
  }
}

/**
 * Creates a new XInvoice instance
 * @returns A new XInvoice instance
 */
export function createXInvoice(): XInvoice {
  return new XInvoice();
}