<?php

use App\Enums\CuttingStatus;
use App\Enums\Permission as PermissionEnum;
use App\Models\Cutting;
use App\Models\CuttingMaterial;
use App\Models\CuttingResult;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\RawMaterial;
use App\Models\RawMaterialPrice;
use App\Models\User;
use Database\Seeders\RolePermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function () {
    $this->seed(RolePermissionSeeder::class);
});

// ─── Helper ───────────────────────────────────────────────

function createStockUserWithPermission(PermissionEnum ...$permissions): User
{
    $user = User::factory()->create();

    $user->givePermissionTo(
        array_merge(
            [PermissionEnum::DASHBOARD_VIEW->value],
            array_map(fn (PermissionEnum $p) => $p->value, $permissions)
        )
    );

    $user->forgetCachedPermissions();

    return $user;
}

function createCompletedCuttingSetup(): array
{
    $product = Product::factory()->create();
    $variant = ProductVariant::factory()->create([
        'product_id' => $product->id,
        'stock' => 10,
        'reject_stock' => 5,
    ]);

    $rawMaterial = RawMaterial::factory()->create();
    $rawMaterialPrice = RawMaterialPrice::factory()->create([
        'raw_material_id' => $rawMaterial->id,
    ]);

    $cutting = Cutting::factory()->create([
        'status' => CuttingStatus::COMPLETED,
    ]);

    CuttingMaterial::factory()->create([
        'cutting_id' => $cutting->id,
        'raw_material_price_id' => $rawMaterialPrice->id,
    ]);

    CuttingResult::factory()->create([
        'cutting_id' => $cutting->id,
        'product_variant_id' => $variant->id,
        'cutting_result' => 7,
        'sample' => 5, // Good stock result
        'original_outside_sample' => 2, // Reject stock result
    ]);

    return [
        'cutting' => $cutting,
        'variant' => $variant,
        'raw_material_price' => $rawMaterialPrice,
    ];
}

// ─── Tests ────────────────────────────────────────────────

describe('Stock Warehouse Management', function () {
    test('authenticated user with permission can view stocks index', function () {
        $user = createStockUserWithPermission(PermissionEnum::STOCKS_VIEW);

        $this->actingAs($user)
            ->get(route('admin.manage.stocks.index'))
            ->assertOk();
    });

    test('user with permission can submit verification for completed cutting', function () {
        $user = createStockUserWithPermission(
            PermissionEnum::STOCKS_VIEW,
            PermissionEnum::CUTTINGS_VERIFY
        );

        $setup = createCompletedCuttingSetup();
        $cutting = $setup['cutting'];

        $payload = [
            'verification_note' => 'Verification notes',
            'results' => [
                [
                    'product_variant_id' => $setup['variant']->id,
                    'good' => 6, // changed from 5 to 6
                    'reject' => 1, // changed from 2 to 1
                ]
            ],
            'result_prices' => [
                [
                    'product_variant_id' => $setup['variant']->id,
                    'prices' => [
                        [
                            'type' => 'harga_modal',
                            'price' => 50000,
                        ],
                        [
                            'type' => 'retail',
                            'price' => 75000,
                        ]
                    ]
                ]
            ],
        ];

        $this->actingAs($user)
            ->post(route('admin.manage.stocks.verify', $cutting), $payload)
            ->assertRedirect(route('admin.manage.stocks.index'));

        $cutting->refresh();
        $this->assertEquals(CuttingStatus::PENDING_VERIFICATION, $cutting->status);

        // Verify cutting results are updated
        $this->assertDatabaseHas('cutting_results', [
            'cutting_id' => $cutting->id,
            'product_variant_id' => $setup['variant']->id,
            'sample' => 6,
            'original_outside_sample' => 1,
        ]);
    });

    test('user with permission can approve verification and increase stock', function () {
        $user = createStockUserWithPermission(
            PermissionEnum::STOCKS_VIEW,
            PermissionEnum::OWNER_VERIFICATIONS_VERIFY
        );

        $setup = createCompletedCuttingSetup();
        $cutting = $setup['cutting'];
        $cutting->status = CuttingStatus::PENDING_VERIFICATION;
        $cutting->save();

        $this->actingAs($user)
            ->post(route('admin.manage.owner_verifications.approve', $cutting), [
                'approval_note' => 'Approved by owner',
            ])
            ->assertRedirect();

        $cutting->refresh();
        $setup['variant']->refresh();

        $this->assertEquals(CuttingStatus::VERIFIED, $cutting->status);

        // Stock (good) should increment by 5 (10 + 5 = 15)
        $this->assertEquals(15, $setup['variant']->stock);

        // Reject stock should increment by 2 (5 + 2 = 7)
        $this->assertEquals(7, $setup['variant']->reject_stock);
    });

    test('user with permission can reject verification', function () {
        $user = createStockUserWithPermission(
            PermissionEnum::STOCKS_VIEW,
            PermissionEnum::OWNER_VERIFICATIONS_REJECT
        );

        $setup = createCompletedCuttingSetup();
        $cutting = $setup['cutting'];
        $cutting->status = CuttingStatus::PENDING_VERIFICATION;
        $cutting->save();

        $this->actingAs($user)
            ->post(route('admin.manage.owner_verifications.reject', $cutting), [
                'reason' => 'Invalid results',
            ])
            ->assertRedirect();

        $cutting->refresh();

        // Status should revert to COMPLETED
        $this->assertEquals(CuttingStatus::COMPLETED, $cutting->status);

        $this->assertDatabaseHas('rejections', [
            'rejectable_id' => $cutting->id,
            'rejectable_type' => Cutting::class,
            'reason' => 'Invalid results',
        ]);
    });
});
