<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\JobCard;
use App\Models\Customer;
use App\Models\Vehicle;
use App\Models\User;
use App\Services\WorkflowService;
use App\Services\InspectionChecklistService;
use Illuminate\Foundation\Testing\RefreshDatabase;

class WorkflowIntegrationTest extends TestCase
{
    use RefreshDatabase;

    private WorkflowService $workflowService;
    private Customer $customer;
    private Vehicle $vehicle;
    private User $serviceAdvisor;

    protected function setUp(): void
    {
        parent::setUp();
        
        $this->workflowService = app(WorkflowService::class);
        
        // Create test data
        $this->customer = Customer::factory()->create();
        $this->vehicle = Vehicle::factory()->create(['customer_id' => $this->customer->id]);
        $this->serviceAdvisor = User::factory()->create(['role' => 'service_advisor']);
    }

    public function test_complete_workflow_can_be_executed(): void
    {
        // Step 1: Create job card
        $jobCard = $this->workflowService->createJobCard([
            'customer_id' => $this->customer->id,
            'vehicle_id' => $this->vehicle->id,
            'branch_code' => 'ACC',
            'customer_reported_issues' => 'Engine making noise',
            'service_advisor_id' => $this->serviceAdvisor->id,
            'arrival_datetime' => now(),
        ]);

        $this->assertEquals(JobCard::STATUS_RECEIVED, $jobCard->status);
        $this->assertStringStartsWith('ACC/', $jobCard->job_card_number);

        // Step 2: Perform initial inspection
        $inspector = User::factory()->create(['role' => 'service_supervisor']);
        $inspectionData = [
            'engine' => 'good',
            'brakes' => 'needs_attention',
            'tires' => 'good',
            'mileage_in' => 50000,
            'fuel_level_in' => 'half',
            'inspection_checklist' => ['engine' => 'good', 'brakes' => 'needs_attention', 'tires' => 'good'],
            'overall_condition' => 'Generally good condition, brakes need attention',
        ];
        $updatedJobCard = $this->workflowService->performInitialInspection($jobCard, $inspectionData, $inspector->id);

        $this->assertEquals(JobCard::STATUS_INSPECTED, $updatedJobCard->status);
        $this->assertNotNull($updatedJobCard->incoming_inspection_data);
        $this->assertEquals(50000, $updatedJobCard->mileage_in);

        // Step 3: Assign to service coordinator
        $coordinator = User::factory()->create(['role' => 'service_coordinator']);
        $diagnosis = $this->workflowService->assignToServiceCoordinator($updatedJobCard, $coordinator->id);

        $updatedJobCard->refresh();
        $this->assertEquals(JobCard::STATUS_ASSIGNED_FOR_DIAGNOSIS, $updatedJobCard->status);
    }

    public function test_inspection_checklist_service_works_correctly(): void
    {
        $inspectionService = app(InspectionChecklistService::class);
        
        $checklist = $inspectionService->getStandardChecklistItems();
        $this->assertIsArray($checklist);
        $this->assertArrayHasKey('engine', $checklist);
        
        $incomingInspection = [
            'engine' => 'good',
            'brakes' => 'fair',
            'tires' => 'good',
        ];
        
        $outgoingInspection = [
            'engine' => 'excellent',
            'brakes' => 'excellent',
            'tires' => 'good',
        ];
        
        $comparison = $inspectionService->compareInspections($incomingInspection, $outgoingInspection);
        $this->assertIsArray($comparison);
        $this->assertArrayHasKey('improvements', $comparison);
        $this->assertContains('engine', $comparison['improvements']);
        $this->assertContains('brakes', $comparison['improvements']);
    }

    public function test_workflow_status_progression_is_enforced(): void
    {
        $jobCard = JobCard::factory()->create([
            'status' => JobCard::STATUS_RECEIVED,
            'customer_id' => $this->customer->id,
            'vehicle_id' => $this->vehicle->id,
        ]);

        // Should not be able to skip steps - job card needs to be inspected first
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('Job card must be inspected before assignment to service coordinator');
        $this->workflowService->assignToServiceCoordinator($jobCard, $this->serviceAdvisor->id);
    }

    public function test_branch_specific_job_card_numbering(): void
    {
        $accJobCard = $this->workflowService->createJobCard([
            'customer_id' => $this->customer->id,
            'vehicle_id' => $this->vehicle->id,
            'branch_code' => 'ACC',
            'service_advisor_id' => $this->serviceAdvisor->id,
            'arrival_datetime' => now(),
        ]);

        $ksiJobCard = $this->workflowService->createJobCard([
            'customer_id' => $this->customer->id,
            'vehicle_id' => $this->vehicle->id,
            'branch_code' => 'KSI',
            'service_advisor_id' => $this->serviceAdvisor->id,
            'arrival_datetime' => now(),
        ]);

        $this->assertStringStartsWith('ACC/', $accJobCard->job_card_number);
        $this->assertStringStartsWith('KSI/', $ksiJobCard->job_card_number);
        $this->assertNotEquals($accJobCard->job_card_number, $ksiJobCard->job_card_number);
    }
}
