<?php

namespace Tests\Feature;

use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\Client;
use App\Models\Tenant\Part;
use App\Models\Tenant\PartBatch;
use App\Models\Tenant\PartReservation;
use App\Models\Tenant\Vehicle;
use App\Models\Tenant\Warehouse;
use App\Models\Tenant\WarehouseEvent;
use App\Models\Tenant\WorkOrder;
use App\Models\Tenant\WorkOrderPart;
use App\Services\Warehouse\WarehouseService;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class WarehouseIssueReturnTest extends TestCase
{
    use RefreshDatabase;

    private WarehouseService $svc;

    protected function setUp(): void
    {
        parent::setUp();
        $this->svc = app(WarehouseService::class);
    }

    public function test_issue_now_consumes_immediately_without_wo_done(): void
    {
        $ctx = $this->ctx();
        $this->svc->receive($ctx['part'], 10, 25.0);

        $wop = WorkOrderPart::create([
            'work_order_id' => $ctx['wo']->id,
            'part_id' => $ctx['part']->id,
            'name' => $ctx['part']->name,
            'qty' => 3, 'unit' => 'buc',
            'buy_price' => 25, 'sell_price' => 40,
        ]);

        $ctx['part']->refresh();
        $this->assertEquals(3.0, (float) $ctx['part']->qty_reserved);

        $n = $this->svc->issueNow($wop);
        $this->assertGreaterThan(0, $n);

        $ctx['part']->refresh();
        $this->assertEquals(7.0, (float) $ctx['part']->qty, 'on-hand decreased without closing WO');
        $this->assertEquals(0.0, (float) $ctx['part']->qty_reserved, 'reservation no longer counted');

        $r = PartReservation::where('work_order_part_id', $wop->id)->first();
        $this->assertEquals('consumed', $r->status);
    }

    public function test_return_part_creates_positive_batch_and_event(): void
    {
        $ctx = $this->ctx();
        $this->svc->receive($ctx['part'], 10, 30.0);

        $wop = WorkOrderPart::create([
            'work_order_id' => $ctx['wo']->id,
            'part_id' => $ctx['part']->id,
            'name' => $ctx['part']->name,
            'qty' => 4, 'unit' => 'buc',
            'buy_price' => 30, 'sell_price' => 50,
        ]);
        $this->svc->issueNow($wop);

        $ctx['part']->refresh();
        $this->assertEquals(6.0, (float) $ctx['part']->qty);

        $batch = $this->svc->returnPart($wop, 2);
        $this->assertNotNull($batch);
        $this->assertEquals(2.0, (float) $batch->qty_in);
        $this->assertEquals(30.0, (float) $batch->buy_price);

        $ctx['part']->refresh();
        $this->assertEquals(8.0, (float) $ctx['part']->qty, 'returned 2 restored to on-hand');

        $this->assertEquals(1, WarehouseEvent::where('part_id', $ctx['part']->id)
            ->where('type', 'return')
            ->count());
    }

    public function test_return_more_than_consumed_is_capped(): void
    {
        $ctx = $this->ctx();
        $this->svc->receive($ctx['part'], 10, 10.0);

        $wop = WorkOrderPart::create([
            'work_order_id' => $ctx['wo']->id,
            'part_id' => $ctx['part']->id,
            'name' => $ctx['part']->name,
            'qty' => 3, 'unit' => 'buc',
            'buy_price' => 10, 'sell_price' => 15,
        ]);
        $this->svc->issueNow($wop);

        $batch = $this->svc->returnPart($wop, 99);
        $this->assertEquals(3.0, (float) $batch->qty_in, 'capped at consumed total');
    }

    private function ctx(): array
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id,
            'slug' => 'ir-' . uniqid(),
            'name' => 'IR Service',
            'status' => 'active',
        ]);
        app(TenantManager::class)->setCurrent($company);

        $wh = Warehouse::create([
            'code' => 'MAIN', 'name' => 'Depozit',
            'is_default' => true, 'is_active' => true,
        ]);
        $company->forceFill(['default_warehouse_id' => $wh->id])->saveQuietly();

        $part = Part::create([
            'name' => 'Filtru aer',
            'unit' => 'buc',
            'qty' => 0,
            'buy_price' => 0, 'sell_price' => 0,
            'is_active' => true,
        ]);

        $client = Client::create([
            'name' => 'WO Client',
            'phone' => '+37399' . random_int(100000, 999999),
            'type' => 'individual', 'status' => 'active',
        ]);
        $vehicle = Vehicle::create([
            'client_id' => $client->id,
            'make' => 'A', 'model' => 'B',
            'plate' => 'IR' . random_int(100, 999),
        ]);
        $wo = WorkOrder::create([
            'number' => WorkOrder::generateNumber($company->id),
            'client_id' => $client->id,
            'vehicle_id' => $vehicle->id,
            'opened_at' => now(),
            'status' => 'in_work',
        ]);

        return compact('company', 'wh', 'part', 'client', 'vehicle', 'wo');
    }
}
