import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
import {
  ExtendedPCNTransaction,
  getEntryTypeByRecord,
  getHeaderDataFromRecords,
  getPcn874String,
  getReferenceForTransaction,
  getTotalVAT,
  getVatIdForTransaction,
} from '../pcn.helper.js';
import { EntryType, validatePcn874 } from '@accounter/pcn874-generator';
import type { RawVatReportRecord } from '../vat-report.helper.js';
import { Currency } from '../../../../shared/enums.js';
import { getVatRecords } from '../../resolvers/get-vat-records.resolver.js';
import { IGetChargesByIdsResult } from '../../../charges/types.js';
import { TimelessDateString } from '../../../../shared/types/index.js';
import type { Injector } from 'graphql-modules';

type GetVatRecordsResponse = {
      income: Array<RawVatReportRecord>;
      expenses: Array<RawVatReportRecord>;
      missingInfo: Array<IGetChargesByIdsResult>;
      differentMonthDoc: Array<IGetChargesByIdsResult>;
      businessTrips: Array<IGetChargesByIdsResult>;
    };

vi.mock('../../resolvers/get-vat-records.resolver.js', () => ({
  getVatRecords: vi.fn(),
}));

const FIXED_DATE = new Date('2024-01-15');
const FIXED_REPORT_MONTH = '2024-01-15';
const FIXED_VAT_NUMBER = '123456789';
const FIXED_BUSINESS_ID = 'test-business-123';

beforeAll(() => {
  vi.useFakeTimers();
  vi.setSystemTime(FIXED_DATE);
});

afterAll(() => {
  vi.useRealTimers();
});

function createMockVatRecord(overrides?: Partial<RawVatReportRecord>): RawVatReportRecord {
  return {
    localAmountBeforeVAT: 1000,
    foreignAmountBeforeVAT: 0,
    businessId: FIXED_BUSINESS_ID,
    chargeAccountantStatus: 'PENDING',
    chargeDate: FIXED_DATE,
    chargeId: `charge-${Math.random().toString(36).substring(7)}`,
    currencyCode: Currency.Ils,
    documentAmount: '1170',
    documentId: `doc-${Math.random().toString(36).substring(7)}`,
    documentDate: FIXED_DATE,
    documentSerial: 'INV-001',
    documentUrl: null,
    eventLocalAmount: 1000,
    isExpense: false,
    isProperty: false,
    roundedVATToAdd: 0,
    foreignVat: 0,
    localVat: 170,
    foreignVatAfterDeduction: 0,
    localVatAfterDeduction: 170,
    vatNumber: FIXED_VAT_NUMBER,
    allocationNumber: null,
    pcn874RecordType: EntryType.SALE_REGULAR,
    ...overrides,
  };
}

function createMockBusiness(vatNumber: string = FIXED_VAT_NUMBER) {
  return {
    id: FIXED_BUSINESS_ID,
    name: 'Test Business Ltd',
    hebrewName: 'חברת בדיקה בע"מ',
    address: 'Tel Aviv',
    country: 'IL',
    vat_number: vatNumber,
  };
}

interface MockContextOptions {
  business?: any;
  vatRecords?: RawVatReportRecord[];
}

function createMockInjector(options: MockContextOptions = {}) {
  const { business, vatRecords } = options;

  const mockLoaders = {
    getFinancialEntityByIdLoader: {
      load: vi.fn().mockResolvedValue(business || createMockBusiness()),
    },
    getIncomeAndExpenseVatRecordsForReportLoader: {
      load: vi.fn().mockResolvedValue(vatRecords || []),
    },
  };
  const mockProviders = {
    BusinessesProvider: {
      getBusinessByIdLoader: {
        load: vi.fn().mockResolvedValue(business || createMockBusiness()),
      },
    },
  };

  return {
      get: vi.fn((token: any) => {
        const tokenName = typeof token === 'string' ? token : token.name;
        return (
          mockProviders[tokenName as keyof typeof mockProviders] ||
          mockLoaders[tokenName as keyof typeof mockLoaders]
        );
      }),
  } as unknown as Injector;
}

describe('pcn.helper', () => {
  describe('Mock Factories', () => {
    it('should create a mock VAT record with defaults', () => {
      const record = createMockVatRecord();
      expect(record.vatNumber).toBe(FIXED_VAT_NUMBER);
      expect(record.pcn874RecordType).toBe(EntryType.SALE_REGULAR);
    });

    it('should override defaults when provided', () => {
      const record = createMockVatRecord({ localVat: 200 });
      expect(record.localVat).toBe(200);
      expect(record.localAmountBeforeVAT).toBe(1000);
    });

    it('should create a mock business with VAT number', () => {
      const business = createMockBusiness('987654321');
      expect(business.vat_number).toBe('987654321');
    });

    it('should create a mock context with loaders', () => {
      const business = createMockBusiness();
      const vatRecords = [createMockVatRecord()];
      const injector = createMockInjector({ business, vatRecords });

      expect(injector).toBeDefined();
      expect(vi.isMockFunction(injector.get)).toBe(true);
    });
  });

  describe('Helper Functions', () => {
    describe('getEntryTypeByRecord', () => {
      describe('Sales Entry Types', () => {
        it('should map S1 to S1', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_REGULAR,
            isExpense: false,
          });
          expect(result).toBe('S1');
        });

        it('should map S2 to S2', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT,
            isExpense: false,
          });
          expect(result).toBe('S2');
        });

        it('should map L1 to L1', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_UNIDENTIFIED_CUSTOMER,
            isExpense: false,
          });
          expect(result).toBe('L1');
        });

        it('should map L2 to L2', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_UNIDENTIFIED_ZERO_OR_EXEMPT,
            isExpense: false,
          });
          expect(result).toBe('L2');
        });

        it('should map M to M', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_SELF_INVOICE,
            isExpense: false,
          });
          expect(result).toBe('M');
        });

        it('should map Y to Y', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_EXPORT,
            isExpense: false,
          });
          expect(result).toBe('Y');
        });

        it('should map I to I', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER,
            isExpense: false,
          });
          expect(result).toBe('I');
        });
      });

      describe('Input Entry Types', () => {
        it('should map T to T', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.INPUT_REGULAR,
            isExpense: true,
          });
          expect(result).toBe('T');
        });

        it('should map K to K', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.INPUT_PETTY_CASH,
            isExpense: true,
          });
          expect(result).toBe('K');
        });

        it('should map R to R', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.INPUT_IMPORT,
            isExpense: true,
          });
          expect(result).toBe('R');
        });

        it('should map P to P', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.INPUT_PALESTINIAN_SUPPLIER,
            isExpense: true,
          });
          expect(result).toBe('P');
        });

        it('should map H to H', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.INPUT_SINGLE_DOC_BY_LAW,
            isExpense: true,
          });
          expect(result).toBe('H');
        });

        it('should map C to C', () => {
          const result = getEntryTypeByRecord({
            pcn874RecordType: EntryType.INPUT_SELF_INVOICE,
            isExpense: true,
          });
          expect(result).toBe('C');
        });
      });

      describe('Edge Cases', () => {
        it('should throw for unmapped types', () => {
          expect(() =>
            getEntryTypeByRecord({
              pcn874RecordType: 'UNKNOWN_TYPE' as any,
              isExpense: false,
            }),
          ).toThrow(/Unhandled PCN874 Record Type/);
        });

        it('should infer sale unidentified customer when VAT number exists', () => {
          const result = getEntryTypeByRecord({
            isExpense: false,
            vatNumber: null,
            foreignVatAfterDeduction: 12,
          });
          expect(result).toBe('L1');
        });

        it('should infer sale unidentified zero/exempt when foreign VAT is zero', () => {
          const result = getEntryTypeByRecord({
            isExpense: false,
            vatNumber: null,
            foreignVatAfterDeduction: 0,
          });
          expect(result).toBe('L2');
        });

        it('should infer sale regular when VAT number and foreign VAT exists', () => {
          const result = getEntryTypeByRecord({
            isExpense: false,
            vatNumber: '123456789',
            foreignVatAfterDeduction: 12,
          });
          expect(result).toBe('S1');
        });

        it('should infer input regular for expenses without explicit type', () => {
          const result = getEntryTypeByRecord({
            isExpense: true,
            vatNumber: null,
            foreignVatAfterDeduction: 0,
          });
          expect(result).toBe('T');
        });
      });
    });

    describe('getVatIdForTransaction', () => {
      it('should return "0" for unidentified customer (L1)', () => {
        const record = createMockVatRecord({
          vatNumber: '123456789',
          pcn874RecordType: EntryType.SALE_UNIDENTIFIED_CUSTOMER,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('0');
      });

      it('should return "0" for unidentified customer zero-rated (L2)', () => {
        const record = createMockVatRecord({
          vatNumber: '123456789',
          pcn874RecordType: EntryType.SALE_UNIDENTIFIED_ZERO_OR_EXEMPT,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('0');
      });

      it('should return "0" for petty cash (K)', () => {
        const record = createMockVatRecord({
          vatNumber: '123456789',
          pcn874RecordType: EntryType.INPUT_PETTY_CASH,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('0');
      });

      it('should return "999999999" for INPUT_REGULAR without VAT number', () => {
        const record = createMockVatRecord({
          vatNumber: null,
          pcn874RecordType: EntryType.INPUT_REGULAR,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('999999999');
      });

      it('should return record VAT number for regular sales', () => {
        const record = createMockVatRecord({
          vatNumber: '123456789',
          pcn874RecordType: EntryType.SALE_REGULAR,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('123456789');
      });

      it('should return record VAT number for foreign business with VAT', () => {
        const record = createMockVatRecord({
          vatNumber: '987654321',
          pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('987654321');
      });

      it('should handle undefined entry type gracefully', () => {
        const record = createMockVatRecord({
          vatNumber: '123456789',
          pcn874RecordType: undefined,
        });
        const result = getVatIdForTransaction(record);
        expect(result).toBe('123456789');
      });
    });

    describe('getReferenceForTransaction', () => {
      it('should return "0" for import transactions (R)', () => {
        const record = createMockVatRecord({
          documentSerial: 'INV-123',
          pcn874RecordType: EntryType.INPUT_IMPORT,
        });
        const result = getReferenceForTransaction(record);
        expect(result).toBe('0');
      });

      it('should return document serial when available', () => {
        const record = createMockVatRecord({
          documentSerial: 'INV-1234',
          pcn874RecordType: EntryType.SALE_REGULAR,
        });
        const result = getReferenceForTransaction(record);
        expect(result).toBe('INV-1234');
      });

      it('should return "1" for unidentified customer (L1) without serial', () => {
        const record = createMockVatRecord({
          documentSerial: null,
          pcn874RecordType: EntryType.SALE_UNIDENTIFIED_CUSTOMER,
        });
        const result = getReferenceForTransaction(record);
        expect(result).toBe('1');
      });

      it('should return "1" for petty cash (K) without serial', () => {
        const record = createMockVatRecord({
          documentSerial: null,
          pcn874RecordType: EntryType.INPUT_PETTY_CASH,
        });
        const result = getReferenceForTransaction(record);
        expect(result).toBe('1');
      });

      it('should return "0" as fallback when no serial and standard type', () => {
        const record = createMockVatRecord({
          documentSerial: null,
          pcn874RecordType: EntryType.SALE_REGULAR,
        });
        const result = getReferenceForTransaction(record);
        expect(result).toBe('0');
      });
    });

    describe('getTotalVAT', () => {
      it('should round positive VAT amount', () => {
        const record = createMockVatRecord({
          roundedVATToAdd: 170.4,
          pcn874RecordType: EntryType.SALE_REGULAR,
        });
        const result = getTotalVAT(record);
        expect(result).toBe(170);
      });

      it('should take absolute value and round negative VAT', () => {
        const record = createMockVatRecord({
          roundedVATToAdd: -170.6,
          pcn874RecordType: EntryType.SALE_REGULAR,
        });
        const result = getTotalVAT(record);
        expect(result).toBe(171);
      });

      it('should return 0 for exempt transactions (S2)', () => {
        const record = createMockVatRecord({
          roundedVATToAdd: 170,
          pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT,
        });
        const result = getTotalVAT(record);
        expect(result).toBe(0);
      });

      it('should return 0 for export transactions (Y)', () => {
        const record = createMockVatRecord({
          roundedVATToAdd: 170,
          pcn874RecordType: EntryType.SALE_EXPORT,
        });
        const result = getTotalVAT(record);
        expect(result).toBe(0);
      });

      it('should return 0 for zero-rated transactions', () => {
        const record = createMockVatRecord({
          roundedVATToAdd: 0,
          pcn874RecordType: EntryType.SALE_REGULAR,
        });
        const result = getTotalVAT(record);
        expect(result).toBe(0);
      });

      it.skip('should handle foreign VAT correctly', () => {
        const record = createMockVatRecord({
          roundedVATToAdd: 85.3,
          pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER,
        });
        const result = getTotalVAT(record);
        expect(result).toBe(85);
      });
    });

    describe('getHeaderDataFromRecords', () => {
      const createPcnRecord = (overrides: Partial<ExtendedPCNTransaction> = {}): ExtendedPCNTransaction => ({
        entryType: EntryType.SALE_REGULAR,
        vatId: '123456789',
        invoiceDate: '20240115',
        refGroup: '0000',
        refNumber: '1',
        totalVat: 170,
        invoiceSum: 1000,
        isProperty: false,
        allocationNumber: undefined,
        ...overrides,
      });

      it('should return all zeros for empty array', () => {
        const result = getHeaderDataFromRecords([], '');
        expect(result.taxableSalesAmount).toBe(0);
        expect(result.zeroValOrExemptSalesCount).toBe(0);
        expect(result.salesRecordCount).toBe(0);
        expect(result.inputsCount).toBe(0);
        expect(result.taxableSalesVat).toBe(0);
        expect(result.otherInputsVat).toBe(0);
        expect(result.equipmentInputsVat).toBe(0);
      });

      it('should increment taxable sales for SALE_REGULAR (S1)', () => {
        const records = [
          createPcnRecord({
            entryType: EntryType.SALE_REGULAR,
            invoiceSum: 1000,
            totalVat: 170,
          }),
        ];
        const result = getHeaderDataFromRecords(records, '');
        expect(result.taxableSalesAmount).toBe(1000);
        expect(result.taxableSalesVat).toBe(170);
        expect(result.salesRecordCount).toBe(1);
        expect(result.zeroValOrExemptSalesCount).toBe(0);
      });

      it('should increment zero-rated sales for SALE_UNIDENTIFIED_ZERO_OR_EXEMPT (L2)', () => {
    const records = [
          createPcnRecord({
            entryType: EntryType.SALE_UNIDENTIFIED_ZERO_OR_EXEMPT,
            invoiceSum: 1000,
            totalVat: 0,
          }),
        ];
        const result = getHeaderDataFromRecords(records, '');
        expect(result.zeroValOrExemptSalesCount).toBe(1000);
        expect(result.taxableSalesAmount).toBe(0);
        expect(result.salesRecordCount).toBe(1);
      });

      describe.skip('Foreign Business with VAT', () => {
        it('should add SALE_FOREIGN_BUSINESS_WITH_VAT to exempt sales', () => {
          const records: ExtendedPCNTransaction[] = [
            createPcnRecord({
              entryType: EntryType.SALE_PALESTINIAN_CUSTOMER,
              invoiceSum: 1170,
              totalVat: 170,
            }),
          ];
          const result = getHeaderDataFromRecords(records, '');

          expect(result.zeroValOrExemptSalesCount).toBe(1170);
          expect(result.taxableSalesAmount).toBe(0);
          expect(result.salesRecordCount).toBe(1);
          expect(result.taxableSalesVat).toBe(170);
        });

        it('should separate foreign with VAT from regular sales', () => {
          const records = [
            createPcnRecord({
              entryType: EntryType.SALE_PALESTINIAN_CUSTOMER,
              invoiceSum: 1170,
              totalVat: 170,
            }),
            createPcnRecord({
              entryType: EntryType.SALE_REGULAR,
              invoiceSum: 2340,
              totalVat: 340,
            }),
          ];
          const result = getHeaderDataFromRecords(records, '');

          expect(result.zeroValOrExemptSalesCount).toBe(1170);
          expect(result.taxableSalesAmount).toBe(2340);
          expect(result.salesRecordCount).toBe(2);
          expect(result.taxableSalesVat).toBe(510);
        });
      });

      describe.skip('Mixed Sales and Input Transactions', () => {
        it('should handle mixed transaction types correctly', () => {
          const records = [
            createPcnRecord({ entryType: EntryType.SALE_REGULAR, invoiceSum: 1000, totalVat: 170 }),
            createPcnRecord({ entryType: EntryType.SALE_REGULAR, invoiceSum: 2000, totalVat: 340 }),
            createPcnRecord({ entryType: EntryType.SALE_PALESTINIAN_CUSTOMER, invoiceSum: 1170, totalVat: 170 }),
            createPcnRecord({
              entryType: EntryType.INPUT_REGULAR,
              invoiceSum: 500,
              totalVat: 85,
              isProperty: false,
            }),
          ];
          const result = getHeaderDataFromRecords(records, '');

          expect(result.taxableSalesAmount).toBe(3000);
          expect(result.zeroValOrExemptSalesCount).toBe(1170);
          expect(result.salesRecordCount).toBe(3);
          expect(result.inputsCount).toBe(1);
          expect(result.taxableSalesVat).toBe(680);
          expect(result.otherInputsVat).toBe(85);
        });

        it('should count input records correctly', () => {
          const records = [
            createPcnRecord({ entryType: EntryType.INPUT_REGULAR, invoiceSum: 500, totalVat: 85 }),
            createPcnRecord({ entryType: EntryType.INPUT_PETTY_CASH, invoiceSum: 100, totalVat: 17 }),
            createPcnRecord({ entryType: EntryType.INPUT_IMPORT, invoiceSum: 300, totalVat: 51 }),
          ];
          const result = getHeaderDataFromRecords(records, '');

          expect(result.inputsCount).toBe(3);
          expect(result.salesRecordCount).toBe(0);
          expect(result.otherInputsVat).toBe(153);
        });
      });
    });
  });

  describe('Integration Tests', () => {
    describe('getPcn874String', () => {
      describe('Standard Mixed Report', () => {
        it('should generate valid PCN874 for typical monthly report', async () => {
          const vatRecords = [
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_REGULAR,
              localAmountBeforeVAT: 1000,
              localVat: 170,
            }),
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_REGULAR,
              localAmountBeforeVAT: 2000,
              localVat: 340,
            }),
            createMockVatRecord({
              pcn874RecordType: EntryType.INPUT_REGULAR,
              localAmountBeforeVAT: 500,
              localVat: 85,
              isExpense: true,
            }),
            createMockVatRecord({
              pcn874RecordType: EntryType.INPUT_REGULAR,
              localAmountBeforeVAT: 300,
              localVat: 51,
              isExpense: true,
            }),
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_EXPORT,
              localAmountBeforeVAT: 5000,
              localVat: 0,
            }),
          ];

          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          vi.mocked(getVatRecords).mockResolvedValue({
            income: vatRecords,
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as GetVatRecordsResponse);

          const result = await getPcn874String(
            injector,
            FIXED_BUSINESS_ID,
            FIXED_REPORT_MONTH,
          );

          expect(validatePcn874(result.reportContent)).toBe(true);

          const lines = result.reportContent.split('\n').filter((line) => line.length > 0);
          expect(lines[0].length).toBe(131);
          expect(lines[lines.length - 1].length).toBe(10);

          const transactionLines = lines.slice(1, -1);
          expect(transactionLines.length).toBe(5);
          transactionLines.forEach((line) => {
            expect(line.length).toBe(60);
          });

          expect(result.reportMonth).toBe('202401');
          expect(result.financialEntity.vat_number).toBe(FIXED_VAT_NUMBER);
        });
      });

      describe('Foreign Businesses with VAT', () => {
        it('should place foreign business with VAT in exempt sales', async () => {
          const vatRecords = [
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER,
              localAmountBeforeVAT: 1000,
              localVat: 170,
              vatNumber: '987654321',
            }),
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_REGULAR,
              localAmountBeforeVAT: 2000,
              localVat: 340,
            }),
          ];

          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          vi.mocked(getVatRecords).mockResolvedValue({
            income: vatRecords,
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as GetVatRecordsResponse);

          const result = await getPcn874String(
            injector,
            FIXED_BUSINESS_ID,
            FIXED_REPORT_MONTH,
          );

          expect(validatePcn874(result.reportContent)).toBe(true);

          const lines = result.reportContent.split('\n').filter((line) => line.length > 0);
          const transactionLines = lines.slice(1, -1);

          const foreignTx = transactionLines.find((line) => line.startsWith('I'));
          expect(foreignTx).toBeDefined();
          expect(foreignTx).toContain('987654321');

          const regularTx = transactionLines.find((line) => line.startsWith('S'));
          expect(regularTx).toBeDefined();
        });
      });

      describe('Edge Cases', () => {
        it('should handle zero-VAT transactions only', async () => {
          const vatRecords = [
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT,
              localVat: 0,
              localAmountBeforeVAT: 1000,
            }),
            createMockVatRecord({
              pcn874RecordType: EntryType.SALE_EXPORT,
              localVat: 0,
              localAmountBeforeVAT: 2000,
            }),
          ];

          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          vi.mocked(getVatRecords).mockResolvedValue({
            income: vatRecords,
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as GetVatRecordsResponse);

          const result = await getPcn874String(
            injector,
            FIXED_BUSINESS_ID,
            FIXED_REPORT_MONTH,
          );

          expect(validatePcn874(result.reportContent)).toBe(true);

          const lines = result.reportContent.split('\n').filter((line) => line.length > 0);
          expect(lines.length).toBeGreaterThan(2);
        });

        it('should handle negative amounts (credit invoices)', async () => {
          const vatRecords = [
            createMockVatRecord({
              localAmountBeforeVAT: -500,
              localVat: -85,
            }),
          ];

          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          vi.mocked(getVatRecords).mockResolvedValue({
            income: vatRecords,
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as GetVatRecordsResponse);

          const result = await getPcn874String(
            injector,
            FIXED_BUSINESS_ID,
            FIXED_REPORT_MONTH,
          );

          expect(validatePcn874(result.reportContent)).toBe(true);

          const lines = result.reportContent.split('\n').filter((line) => line.length > 0);
          expect(lines.length).toBe(3);
        });

        it('should skip records with missing document dates', async () => {
          const vatRecords = [
            createMockVatRecord({ documentDate: null }),
            createMockVatRecord({ documentDate: FIXED_DATE }),
          ];

          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          const consoleDebugSpy = vi.spyOn(console, 'debug').mockImplementation(() => undefined);

          vi.mocked(getVatRecords).mockResolvedValue({
            income: vatRecords,
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as any);

          const result = await getPcn874String(
            injector,
            FIXED_BUSINESS_ID,
            FIXED_REPORT_MONTH,
          );

          expect(validatePcn874(result.reportContent)).toBe(true);

          const lines = result.reportContent.split('\n').filter((line) => line.length > 0);
          const transactionLines = lines.slice(1, -1);
          expect(transactionLines.length).toBe(1);
          expect(consoleDebugSpy).toHaveBeenCalled();

          consoleDebugSpy.mockRestore();
        });

        it('should generate minimal report for empty records', async () => {
          const vatRecords: RawVatReportRecord[] = [];

          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          vi.mocked(getVatRecords).mockResolvedValue({
            income: [],
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as any);

          const result = await getPcn874String(
            injector,
            FIXED_BUSINESS_ID,
            FIXED_REPORT_MONTH,
          );

          expect(validatePcn874(result.reportContent)).toBe(false); // Header/footer only is not valid but should still be generated

          const lines = result.reportContent.split('\n').filter((line) => line.length > 0);
          expect(lines.length).toBe(2);
          expect(lines[0].length).toBe(131);
          expect(lines[1].length).toBe(10);
        });
      });

      describe('Error Handling', () => {
        it('should throw error when business has no VAT number', async () => {
          const vatRecords = [createMockVatRecord()];
          const businessWithoutVAT = createMockBusiness(undefined) as any;
          businessWithoutVAT.vatNumber = null;
          businessWithoutVAT.vat_number = null;

          const injector = createMockInjector({
            business: businessWithoutVAT,
            vatRecords,
          });

          await expect(
            getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH),
          ).rejects.toThrow(/VAT/i);
        });

        it('should validate report month format', async () => {
          const vatRecords = [createMockVatRecord()];
          const business = createMockBusiness();
          const injector = createMockInjector({ business, vatRecords });

          vi.mocked(getVatRecords).mockResolvedValue({
            income: vatRecords,
            expenses: [],
            missingInfo: [],
            differentMonthDoc: [],
            businessTrips: [],
          } as GetVatRecordsResponse);

          const result = await getPcn874String(injector, FIXED_BUSINESS_ID, '2024-1' as TimelessDateString);
          expect(result.reportMonth).toBe('202401');
        });
      });
    });
  });

  describe('Snapshot Tests', () => {
    describe('PCN874 Format Snapshots', () => {
      it('should match snapshot for standard mixed report', async () => {
        const vatRecords = [
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_REGULAR,
            localAmountBeforeVAT: 1000,
            localVat: 170,
            documentSerial: 'INV-001',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_REGULAR,
            localAmountBeforeVAT: 2000,
            localVat: 340,
            documentSerial: 'INV-002',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.INPUT_REGULAR,
            localAmountBeforeVAT: 500,
            localVat: 85,
            isExpense: true,
            documentSerial: 'BILL-001',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.INPUT_REGULAR,
            localAmountBeforeVAT: 300,
            localVat: 51,
            isExpense: true,
            documentSerial: 'BILL-002',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_EXPORT,
            localAmountBeforeVAT: 5000,
            localVat: 0,
            documentSerial: 'EXP-001',
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: vatRecords,
          expenses: [],
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for PR #2940 foreign businesses', async () => {
        const vatRecords = [
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER,
            localAmountBeforeVAT: 1000,
            localVat: 170,
            vatNumber: '987654321',
            documentSerial: 'INTL-001',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_REGULAR,
            localAmountBeforeVAT: 2000,
            localVat: 340,
            documentSerial: 'INV-001',
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: vatRecords,
          expenses: [],
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for zero-VAT transactions', async () => {
        const vatRecords = [
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT,
            localAmountBeforeVAT: 1000,
            localVat: 0,
            documentSerial: 'EXEMPT-001',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_EXPORT,
            localAmountBeforeVAT: 2000,
            localVat: 0,
            documentSerial: 'EXP-001',
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: vatRecords,
          expenses: [],
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for imports and exports', async () => {
        const vatRecords = [
          createMockVatRecord({
            pcn874RecordType: EntryType.INPUT_IMPORT,
            localAmountBeforeVAT: 3000,
            localVat: 510,
            isExpense: true,
            documentSerial: 'IMP-001',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_EXPORT,
            localAmountBeforeVAT: 5000,
            localVat: 0,
            documentSerial: 'EXP-001',
          }),
          createMockVatRecord({
            pcn874RecordType: EntryType.SALE_REGULAR,
            localAmountBeforeVAT: 1000,
            localVat: 170,
            documentSerial: 'INV-001',
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: vatRecords,
          expenses: [],
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for property expenses', async () => {
        const vatRecords = [
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "0101-0202",
            documentAmount: "4680",
            foreignVat: null,
            localVat: 713.9,
            isProperty: true,
            vatNumber: FIXED_VAT_NUMBER,
            isExpense: true,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: 475.9333333333333,
            localVatAfterDeduction: 475.9333333333333,
            foreignAmountBeforeVAT: 4204.066666666667,
            localAmountBeforeVAT: 4204.066666666667,
            roundedVATToAdd: 476,
            eventLocalAmount: 4680,
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: [],
          expenses: vatRecords,
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for foreign customer, credit invoices (with & without VAT)', async () => {
        const vatRecords = [
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Usd,
            documentSerial: "10123",
            documentAmount: "6000",
            foreignVat: -1810.54,
            localVat: null,
            isProperty: false,
            vatNumber: null,
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: -1810.54,
            localVatAfterDeduction: -2597.4086299999996,
            foreignAmountBeforeVAT: -5084.74,
            localAmountBeforeVAT: -16596.59136,
            roundedVATToAdd: -2598,
            eventLocalAmount: -10584,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Usd,
            documentSerial: "20123",
            documentAmount: "6000",
            foreignVat: 1810.54,
            localVat: null,
            isProperty: false,
            vatNumber: null,
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: 1810.54,
            localVatAfterDeduction: 2597.4086299999996,
            foreignAmountBeforeVAT: 5084.74,
            localAmountBeforeVAT: 16596.59136,
            roundedVATToAdd: 2598,
            eventLocalAmount: 10584,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "80123",
            documentAmount: "2000.15",
            foreignVat: null,
            localVat: null,
            isProperty: false,
            vatNumber: null,
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: undefined,
            localVatAfterDeduction: undefined,
            foreignAmountBeforeVAT: undefined,
            localAmountBeforeVAT: -2000.15,
            roundedVATToAdd: undefined,
            eventLocalAmount: -2000.15,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "90123",
            documentAmount: "2000.15",
            foreignVat: undefined,
            localVat: undefined,
            isProperty: false,
            vatNumber: undefined,
            isExpense: false,
            allocationNumber: undefined,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: undefined,
            localVatAfterDeduction: undefined,
            foreignAmountBeforeVAT: undefined,
            localAmountBeforeVAT: 2000.15,
            roundedVATToAdd: undefined,
            eventLocalAmount: 2000.15,
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: [],
          expenses: vatRecords,
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for local customer, credit invoices with VAT', async () => {
        const vatRecords = [
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "10001",
            documentAmount: "4000",
            foreignVat: undefined,
            localVat: -610.17,
            isProperty: false,
            vatNumber: '191919191',
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: undefined,
            localVatAfterDeduction: -610.17,
            foreignAmountBeforeVAT: undefined,
            localAmountBeforeVAT: -3389.83,
            roundedVATToAdd: -610,
            eventLocalAmount: -4000,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "20002",
            documentAmount: "4000",
            foreignVat: undefined,
            localVat: 610.17,
            isProperty: false,
            vatNumber: '191919191',
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: undefined,
            localVatAfterDeduction: 610.17,
            foreignAmountBeforeVAT: undefined,
            localAmountBeforeVAT: 3389.83,
            roundedVATToAdd: 610,
            eventLocalAmount: 4000,
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: [],
          expenses: vatRecords,
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for local customer, credit invoices without VAT', async () => {
        const vatRecords = [
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "10001",
            documentAmount: "4000",
            foreignVat: undefined,
            localVat: undefined,
            isProperty: false,
            vatNumber: '191919191',
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: undefined,
            localVatAfterDeduction: undefined,
            foreignAmountBeforeVAT: undefined,
            localAmountBeforeVAT: -4000,
            roundedVATToAdd: undefined,
            eventLocalAmount: -4000,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "PENDING",
            currencyCode: Currency.Ils,
            documentSerial: "20002",
            documentAmount: "4000",
            foreignVat: undefined,
            localVat: undefined,
            isProperty: false,
            vatNumber: '191919191',
            isExpense: false,
            allocationNumber: null,
            pcn874RecordType: undefined,
            foreignVatAfterDeduction: undefined,
            localVatAfterDeduction: undefined,
            foreignAmountBeforeVAT: undefined,
            localAmountBeforeVAT: 4000,
            roundedVATToAdd: undefined,
            eventLocalAmount: 4000,
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: [],
          expenses: vatRecords,
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });

      it('should match snapshot for petty cash (taxi invoices - record type is overridden)', async () => {
        const vatRecords = [
          createMockVatRecord({
            chargeAccountantStatus: "APPROVED",
            currencyCode: Currency.Ils,
            documentSerial: "19",
            documentAmount: "441.7",
            foreignVat: null,
            localVat: 67.38,
            isProperty: false,
            vatNumber: null,
            isExpense: true,
            pcn874RecordType: "K",
            foreignVatAfterDeduction: 67.38,
            localVatAfterDeduction: 67.38,
            foreignAmountBeforeVAT: 374.32,
            localAmountBeforeVAT: 374.32,
            roundedVATToAdd: 67,
            eventLocalAmount: 441.7,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "APPROVED",
            currencyCode: Currency.Ils,
            documentSerial: "565",
            documentAmount: "199.8",
            foreignVat: null,
            localVat: 30.48,
            isProperty: false,
            vatNumber: null,
            isExpense: true,
            pcn874RecordType: "K",
            foreignVatAfterDeduction: 30.48,
            localVatAfterDeduction: 30.48,
            foreignAmountBeforeVAT: 169.32000000000002,
            localAmountBeforeVAT: 169.32000000000002,
            roundedVATToAdd: 30,
            eventLocalAmount: 199.8,
          }),
          createMockVatRecord({
            chargeAccountantStatus: "APPROVED",
            currencyCode: Currency.Ils,
            documentSerial: "9476",
            documentAmount: "165",
            foreignVat: null,
            localVat: 25.17,
            isProperty: false,
            vatNumber: null,
            isExpense: true,
            pcn874RecordType: "K",
            foreignVatAfterDeduction: 25.17,
            localVatAfterDeduction: 25.17,
            foreignAmountBeforeVAT: 139.82999999999998,
            localAmountBeforeVAT: 139.82999999999998,
            roundedVATToAdd: 25,
            eventLocalAmount: 165,
          }),
        ];

        const business = createMockBusiness();
        const injector = createMockInjector({ business, vatRecords });

        vi.mocked(getVatRecords).mockResolvedValue({
          income: [],
          expenses: vatRecords,
          missingInfo: [],
          differentMonthDoc: [],
          businessTrips: [],
        } as GetVatRecordsResponse);

        const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH);

        expect(validatePcn874(result.reportContent)).toBe(true);
        expect(result.reportContent).toMatchSnapshot();
      });
    });
  });

  it('should load test file', () => {
    expect(true).toBe(true);
  });
});
