import { describe, expect, it } from 'vitest'
import ExcelJS from 'exceljs'

import {
  buildInventoryCountWorkbook,
  composeForm6111Rows,
  partitionExpenseSourcesForForm6111,
  type InventoryCountRow,
} from '../src/reports/form6111'

describe('Form 6111 stock-line composition', () => {
  it('moves stock-line net amounts out of ordinary expense categories into inventory stock', () => {
    const partitioned = partitionExpenseSourcesForForm6111([
      {
        expenseCategory: 'equipment',
        amount: '117.00',
        vatAmount: '17.00',
        businessPercent: 100,
        deductionPct: 100,
        vatDeductible: true,
        sourceMetadata: {
          stockLines: [
            {
              id: 'line-1',
              qty: 4,
              netAmount: 60,
            },
          ],
        },
      },
      {
        expenseCategory: 'equipment',
        amount: '58.50',
        vatAmount: '8.50',
        businessPercent: 100,
        deductionPct: 100,
        vatDeductible: true,
        sourceMetadata: null,
      },
    ])

    expect(partitioned.inventory_stock).toBe(60)
    expect(partitioned.by_category.equipment).toBe(90)
    expect(partitioned.total).toBe(150)
  })

  it('composes inventory stock under 6111 code 2000 with category breakdown', () => {
    const rows = composeForm6111Rows({
      revenue: {
        gross: 0,
        credit_notes: 0,
        bad_debts: 0,
        net: 0,
      },
      expenses: {
        by_category: { equipment: 90 },
        inventory_stock: 60,
        total: 150,
      },
      contractor_payouts: 0,
      net_profit: -150,
    }, [
      { code: '4900', name: 'מלאי / עלות המכר', type: 'expense', form6111Code: '2000' },
      { code: '5040', name: 'ציוד וחומרה', type: 'expense', form6111Code: '5000' },
    ], [
      { sourceKind: 'inventory_stock', accountCode: '4900' },
      { sourceKind: 'equipment', accountCode: '5040' },
    ])

    expect(rows.groupedRows).toEqual([
      expect.objectContaining({
        code: '2000',
        amount: 60,
        breakdown: [expect.objectContaining({ label: 'מלאי שנקלט מהוצאות', amount: 60 })],
      }),
      expect.objectContaining({
        code: '5000',
        amount: 90,
        breakdown: [expect.objectContaining({ label: 'ציוד וחומרה', amount: 90 })],
      }),
      expect.objectContaining({
        code: '6666',
        amount: -150,
      }),
    ])
    expect(rows.unmappedWithAmounts).toEqual([])
  })
})

describe('Inventory count workbook', () => {
  it('renders book quantities and blank physical-count columns into xlsx', async () => {
    const rows: InventoryCountRow[] = [
      {
        stockItemId: 'item-1',
        productName: 'Blue Widget',
        locationName: 'Main',
        locationCode: 'MAIN',
        qtyOnHand: 7,
        avgUnitCost: 12.5,
      },
    ]

    const bytes = await buildInventoryCountWorkbook(rows, '2026-12-31')

    const workbook = new ExcelJS.Workbook()
    await workbook.xlsx.load(bytes)

    const sheet = workbook.getWorksheet('מפקד מלאי')
    expect(sheet).toBeDefined()
    expect(sheet?.getCell('A1').value).toBe('מפקד מלאי ליום 2026-12-31')
    expect(sheet?.getCell('D3').value).toBe('מוצר')
    expect(sheet?.getCell('B4').value).toBe('MAIN')
    expect(sheet?.getCell('C4').value).toBe('Main')
    expect(sheet?.getCell('D4').value).toBe('Blue Widget')
    expect(sheet?.getCell('E4').value).toBe('item-1')
    expect(sheet?.getCell('F4').value).toBe(7)
    expect(sheet?.getCell('G4').value).toBe(12.5)
    expect(sheet?.getCell('H4').value).toBe(87.5)
    expect(sheet?.getCell('I4').value).toBeNull()
    expect(sheet?.getCell('J4').value).toBeNull()
    expect(sheet?.views?.[0]?.rightToLeft).toBe(true)
  })
})
