<?php

namespace Tests\Feature\Api\V1\Workflows;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SeedsE2ETestFixtures;
use Tests\TestCase;

/**
 * Scenario E: Finance Edge Lifecycle (carryforward + installments + follow-ups).
 *
 * @see docs/alrahma_end_to_end_use_case_test_plan.md Scenario E
 */
class ScenarioEFinanceEdgeTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;

    public function test_admin_carries_forward_balance_and_manages_installments(): void
    {
        $this->seedE2EConfiguration();
        $this->seedClosedSchoolYear();
        $admin = $this->actingAsApiAdministrator();

        $parent = $this->createApiUserWithRole('parent');
        $priorInvoiceId = $this->seedPriorYearUnpaidInvoice($parent->id);

        $preview = $this->getJson('/api/v1/finance/carryforwards/preview?' . http_build_query([
            'from_school_year' => self::E2E_PREV_SCHOOL_YEAR,
            'to_school_year' => self::E2E_SCHOOL_YEAR,
            'parent_id' => $parent->id,
        ]));
        $preview->assertOk()->assertJsonPath('ok', true);
        $this->assertNotEmpty($preview->json('preview.rows'));

        $draft = $this->postJson('/api/v1/finance/carryforwards/draft', [
            'from_school_year' => self::E2E_PREV_SCHOOL_YEAR,
            'to_school_year' => self::E2E_SCHOOL_YEAR,
            'parent_id' => $parent->id,
            'reason' => 'E2E carryforward',
        ]);
        $draft->assertOk()->assertJsonPath('ok', true);
        $this->assertNotEmpty($draft->json('result.created'));

        $carryforwardId = (int) $draft->json('result.created.0.id');
        $this->postJson('/api/v1/finance/carryforwards/' . $carryforwardId . '/approve')
            ->assertOk()
            ->assertJsonPath('ok', true);

        $posted = $this->postJson('/api/v1/finance/carryforwards/' . $carryforwardId . '/post')
            ->assertOk()
            ->assertJsonPath('ok', true);
        $newInvoiceId = (int) ($posted->json('carryforward.posted_invoice_id') ?? 0);
        $this->assertGreaterThan(0, $newInvoiceId);

        $plan = $this->postJson('/api/v1/finance/invoices/' . $newInvoiceId . '/installment-plans', [
            'number_of_installments' => 2,
            'first_due_date' => '2025-09-15',
            'interval_months' => 1,
        ])->assertCreated()->assertJsonPath('ok', true);

        $planId = (int) $plan->json('plan.id');
        $this->postJson('/api/v1/finance/installment-plans/' . $planId . '/activate')
            ->assertOk()
            ->assertJsonPath('ok', true);

        $paymentId = DB::table('payments')->insertGetId([
            'parent_id' => $parent->id,
            'invoice_id' => $newInvoiceId,
            'total_amount' => 75.00,
            'paid_amount' => 75.00,
            'balance' => 0,
            'number_of_installments' => 1,
            'payment_method' => 'cash',
            'payment_date' => '2025-09-20',
            'school_year' => self::E2E_SCHOOL_YEAR,
            'semester' => self::E2E_SEMESTER,
            'status' => 'Paid',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $this->postJson('/api/v1/finance/payments/' . $paymentId . '/allocate-installments', [])
            ->assertOk()
            ->assertJsonPath('ok', true);

        $this->getJson('/api/v1/finance/installments/overdue')
            ->assertOk()
            ->assertJsonPath('ok', true);

        $this->postJson('/api/v1/finance/parent-payment-followups/' . $parent->id . '/note', [
            'invoice_id' => $newInvoiceId,
            'school_year' => self::E2E_SCHOOL_YEAR,
            'note' => 'Called parent about prior-year balance.',
            'contact_method' => 'phone',
        ])->assertCreated()->assertJsonPath('ok', true);

        $this->postJson('/api/v1/finance/parent-payment-followups/' . $parent->id . '/promise-to-pay', [
            'invoice_id' => $newInvoiceId,
            'promise_to_pay_date' => '2025-10-15',
            'promise_to_pay_amount' => 50,
        ])->assertCreated()->assertJsonPath('ok', true);

        $this->postJson('/api/v1/finance/parent-payment-followups/' . $parent->id . '/resolve', [
            'invoice_id' => $newInvoiceId,
            'note' => 'Balance plan agreed.',
        ])->assertCreated()->assertJsonPath('ok', true);

        $this->assertDatabaseHas('finance_balance_carryforwards', [
            'id' => $carryforwardId,
            'parent_id' => $parent->id,
            'status' => 'posted_to_new_year',
        ]);

        $this->assertDatabaseHas('invoices', [
            'id' => $priorInvoiceId,
            'parent_id' => $parent->id,
            'school_year' => self::E2E_PREV_SCHOOL_YEAR,
        ]);
    }
}
