<?php

namespace Tests\Feature\Api\V1\Workflows;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Tests\Concerns\AssertsE2EApiResponses;
use Tests\Concerns\SeedsE2ETestFixtures;
use Tests\TestCase;

/**
 * Scenario V: Procurement, suppliers, purchase orders, and reimbursements.
 *
 * This tests the less glamorous truth: supplies arrive, people ask for money
 * back, batches are locked, files exist, and reports still need to reconcile.
 */
class ScenarioVProcurementReimbursementAndSupplyLifecycleTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;
    use AssertsE2EApiResponses;

    public function test_admin_manages_suppliers_supply_categories_purchase_order_and_receipt(): void
    {
        $this->seedE2EConfiguration();
        $admin = $this->actingAsApiAdministrator();
        $this->actingAs($admin, 'api');

        $category = $this->postJson('/api/v1/inventory/supply-categories', [
            'name' => 'E2E Office Supplies',
            'description' => 'Supplies used by E2E procurement tests.',
        ]);
        $this->assertSuccessfulOrValidation($category, 'Supply category creation');

        $supplier = $this->postJson('/api/v1/inventory/suppliers', [
            'name' => 'E2E Supplier LLC',
            'contact_name' => 'Supply Contact',
            'email' => 'supplier@example.test',
            'phone' => '5552223333',
            'address' => '1 Supply Road',
        ]);
        $this->assertSuccessfulOrValidation($supplier, 'Supplier creation');

        $supplierId = (int) DB::table('suppliers')->where('name', 'E2E Supplier LLC')->value('id');
        $categoryId = (int) DB::table('supply_categories')->where('name', 'E2E Office Supplies')->value('id');

        if ($supplierId > 0 && $categoryId > 0) {
            $order = $this->postJson('/api/v1/finance/purchase-orders', [
                'supplier_id' => $supplierId,
                'order_date' => '2025-10-05',
                'expected_date' => '2025-10-12',
                'status' => 'draft',
                'items' => [
                    [
                        'name' => 'Printer paper',
                        'category_id' => $categoryId,
                        'quantity' => 10,
                        'unit_price' => 6.50,
                    ],
                ],
                'notes' => 'E2E purchase order.',
            ]);
            $this->assertNoServerError($order, 'Purchase order creation');

            $purchaseOrderId = (int) DB::table('purchase_orders')
                ->where('supplier_id', $supplierId)
                ->value('id');

            if ($purchaseOrderId > 0) {
                $this->getJson('/api/v1/finance/purchase-orders/' . $purchaseOrderId)
                    ->assertSuccessful();
                $this->postJson('/api/v1/finance/purchase-orders/' . $purchaseOrderId . '/receive', [
                    'received_date' => '2025-10-12',
                    'items' => [
                        ['name' => 'Printer paper', 'quantity_received' => 10],
                    ],
                ])->assertSuccessful();
            }
        }

        $this->getJson('/api/v1/finance/purchase-orders/options')
            ->assertSuccessful();
    }

    public function test_reimbursement_request_batch_lock_export_and_mark_donation_flow(): void
    {
        Storage::fake('local');
        $this->seedE2EConfiguration();
        $admin = $this->actingAsApiAdministrator();
        $this->actingAs($admin, 'api');

        $request = $this->post('/api/v1/finance/reimbursements', [
            'requester_id' => $admin->id,
            'amount' => 45.75,
            'description' => 'E2E classroom material reimbursement.',
            'expense_date' => '2025-10-05',
            'category' => 'classroom',
            'receipt' => UploadedFile::fake()->create('receipt.pdf', 20, 'application/pdf'),
        ]);
        $this->assertNoServerError($request, 'Reimbursement creation');

        $reimbursementId = (int) DB::table('reimbursements')
            ->where('requester_id', $admin->id)
            ->value('id');

        if ($reimbursementId > 0) {
            $this->putJson('/api/v1/finance/reimbursements/' . $reimbursementId, [
                'amount' => 45.75,
                'description' => 'Updated E2E reimbursement description.',
                'status' => 'under_processing',
            ])->assertSuccessful();

            $this->postJson('/api/v1/finance/reimbursements/process', [
                'ids' => [$reimbursementId],
                'status' => 'approved',
            ])->assertSuccessful();
        }

        $batch = $this->postJson('/api/v1/finance/reimbursements/batches', [
            'name' => 'E2E Reimbursement Batch',
            'reimbursement_ids' => $reimbursementId > 0 ? [$reimbursementId] : [],
        ]);
        $this->assertNoServerError($batch, 'Reimbursement batch creation');

        $batchId = (int) DB::table('reimbursement_batches')
            ->where('name', 'E2E Reimbursement Batch')
            ->value('id');

        if ($batchId > 0) {
            $this->postJson('/api/v1/finance/reimbursements/batches/assign', [
                'batch_id' => $batchId,
                'reimbursement_ids' => $reimbursementId > 0 ? [$reimbursementId] : [],
            ])->assertSuccessful();
            $this->postJson('/api/v1/finance/reimbursements/batches/lock', [
                'batch_id' => $batchId,
            ])->assertSuccessful();
            $this->getJson('/api/v1/finance/reimbursements/batches/export?batch_id=' . $batchId)
                ->assertSuccessful();
        }

        if ($reimbursementId > 0) {
            $this->postJson('/api/v1/finance/reimbursements/mark-donation', [
                'id' => $reimbursementId,
                'donation_note' => 'Donated back to school.',
            ])->assertSuccessful();
        }

        $this->getJson('/api/v1/finance/reimbursements/under-processing')
            ->assertSuccessful();
    }
}
