import { tap, expect } from '@push.rocks/tapbundle';
import { XInvoice } from '../ts/classes.xinvoice.js';
import { ValidationLevel } from '../ts/interfaces/common.js';
import * as fs from 'fs/promises';
import * as path from 'path';

// Test for XInvoice class functionality
tap.test('XInvoice should load XML correctly', async () => {
  // Create a sample XML string
  const sampleXml = `<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
  xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
  xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>INV-2023-001</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20230101</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>Supplier Company</ram:Name>
        <ram:PostalTradeAddress>
          <ram:LineOne>Supplier Street</ram:LineOne>
          <ram:LineTwo>123</ram:LineTwo>
          <ram:PostcodeCode>12345</ram:PostcodeCode>
          <ram:CityName>Supplier City</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="VA">DE123456789</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>Customer Company</ram:Name>
        <ram:PostalTradeAddress>
          <ram:LineOne>Customer Street</ram:LineOne>
          <ram:LineTwo>456</ram:LineTwo>
          <ram:PostcodeCode>54321</ram:PostcodeCode>
          <ram:CityName>Customer City</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery/>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>200.00</ram:LineTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">38.00</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>238.00</ram:GrandTotalAmount>
        <ram:DuePayableAmount>238.00</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>`;

  // Save the sample XML to a file
  const testDir = path.join(process.cwd(), 'test', 'output');
  await fs.mkdir(testDir, { recursive: true });
  const xmlPath = path.join(testDir, 'sample-invoice.xml');
  await fs.writeFile(xmlPath, sampleXml);
  
  // Create XInvoice from XML
  const xinvoice = await XInvoice.fromXml(sampleXml);
  
  // Check that the XInvoice instance has the expected properties
  expect(xinvoice.id).toEqual('INV-2023-001');
  expect(xinvoice.from.name).toEqual('Supplier Company');
  expect(xinvoice.to.name).toEqual('Customer Company');
});

tap.test('XInvoice should export XML correctly', async () => {
  // Create a sample XML string
  const sampleXml = `<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
  xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
  xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>INV-2023-001</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20230101</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>Supplier Company</ram:Name>
        <ram:PostalTradeAddress>
          <ram:LineOne>Supplier Street</ram:LineOne>
          <ram:LineTwo>123</ram:LineTwo>
          <ram:PostcodeCode>12345</ram:PostcodeCode>
          <ram:CityName>Supplier City</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="VA">DE123456789</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>Customer Company</ram:Name>
        <ram:PostalTradeAddress>
          <ram:LineOne>Customer Street</ram:LineOne>
          <ram:LineTwo>456</ram:LineTwo>
          <ram:PostcodeCode>54321</ram:PostcodeCode>
          <ram:CityName>Customer City</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery/>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>200.00</ram:LineTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">38.00</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>238.00</ram:GrandTotalAmount>
        <ram:DuePayableAmount>238.00</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>`;

  // Create XInvoice from XML
  const xinvoice = await XInvoice.fromXml(sampleXml);
  
  // Export XML
  const exportedXml = await xinvoice.exportXml('facturx');
  
  // Check that the exported XML contains expected elements
  expect(exportedXml).toInclude('CrossIndustryInvoice');
  expect(exportedXml).toInclude('INV-2023-001');
  expect(exportedXml).toInclude('Supplier Company');
  expect(exportedXml).toInclude('Customer Company');
  
  // Save the exported XML to a file
  const testDir = path.join(process.cwd(), 'test', 'output');
  await fs.mkdir(testDir, { recursive: true });
  const exportedXmlPath = path.join(testDir, 'exported-invoice.xml');
  await fs.writeFile(exportedXmlPath, exportedXml);
});

// Run the tests
tap.start();
