<?php

namespace Tests\Feature\Accounts;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Modules\Accounts\Models\ChartOfAccount;
use Modules\Accounts\Services\VoucherService;
use Tests\TestCase;

class VoucherPostingTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_posts_a_balanced_voucher_and_generates_transactions(): void
    {
        $assetRoot = ChartOfAccount::query()->create([
            'account_code' => 10,
            'account_name' => 'Assets',
            'parent_id' => null,
            'is_group' => true,
            'account_type' => 'Asset',
            'status' => true,
        ]);

        $incomeRoot = ChartOfAccount::query()->create([
            'account_code' => 40,
            'account_name' => 'Income',
            'parent_id' => null,
            'is_group' => true,
            'account_type' => 'Income',
            'status' => true,
        ]);

        $cash = ChartOfAccount::query()->create([
            'account_code' => 10001,
            'account_name' => 'Cash',
            'parent_id' => $assetRoot->id,
            'is_group' => false,
            'account_type' => 'Asset',
            'is_cash' => true,
            'status' => true,
        ]);

        $sales = ChartOfAccount::query()->create([
            'account_code' => 40001,
            'account_name' => 'Sales',
            'parent_id' => $incomeRoot->id,
            'is_group' => false,
            'account_type' => 'Income',
            'status' => true,
        ]);

        $service = app(VoucherService::class);

        $voucher = $service->store([
            'voucher_date' => '2026-04-15',
            'voucher_type' => 'Journal',
            'reference' => 'Opening entry',
            'status' => 'pending',
            'lines' => [
                ['account_id' => $cash->id, 'debit' => 1000, 'credit' => 0, 'sl_no' => 1],
                ['account_id' => $sales->id, 'debit' => 0, 'credit' => 1000, 'sl_no' => 2],
            ],
        ]);

        $posted = $service->post($voucher);

        $this->assertSame('posted', $posted->status);
        $this->assertDatabaseCount('account_transactions', 2);
        $this->assertDatabaseHas('account_transactions', [
            'voucher_id' => $posted->id,
            'account_id' => $cash->id,
        ]);
    }

    public function test_it_creates_a_reversal_voucher(): void
    {
        $assetRoot = ChartOfAccount::query()->create([
            'account_code' => 10,
            'account_name' => 'Assets',
            'parent_id' => null,
            'is_group' => true,
            'account_type' => 'Asset',
            'status' => true,
        ]);

        $liabilityRoot = ChartOfAccount::query()->create([
            'account_code' => 20,
            'account_name' => 'Liabilities',
            'parent_id' => null,
            'is_group' => true,
            'account_type' => 'Liability',
            'status' => true,
        ]);

        $cash = ChartOfAccount::query()->create([
            'account_code' => 10001,
            'account_name' => 'Cash',
            'parent_id' => $assetRoot->id,
            'is_group' => false,
            'account_type' => 'Asset',
            'status' => true,
        ]);

        $loan = ChartOfAccount::query()->create([
            'account_code' => 20001,
            'account_name' => 'Loan',
            'parent_id' => $liabilityRoot->id,
            'is_group' => false,
            'account_type' => 'Liability',
            'status' => true,
        ]);

        $service = app(VoucherService::class);

        $voucher = $service->post($service->store([
            'voucher_date' => '2026-04-15',
            'voucher_type' => 'Journal',
            'reference' => 'Loan received',
            'status' => 'pending',
            'lines' => [
                ['account_id' => $cash->id, 'debit' => 2500, 'credit' => 0, 'sl_no' => 1],
                ['account_id' => $loan->id, 'debit' => 0, 'credit' => 2500, 'sl_no' => 2],
            ],
        ]));

        $reversal = $service->reverse($voucher, ['voucher_date' => '2026-04-16']);

        $this->assertTrue($reversal->is_reversal);
        $this->assertSame($voucher->id, $reversal->reversed_from);
        $this->assertSame('posted', $reversal->status);
        $this->assertDatabaseCount('account_vouchers', 2);
    }
}
