<?php

namespace Tests\Feature;

use App\Models\Order;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class OrderApprovalTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    public function test_order_starts_with_stage_1_created_status()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        $this->assertEquals(Order::STATUS_CREATED, $order->status);
    }

    public function test_order_can_be_approved_to_next_stage()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        $this->assertTrue($order->canApproveToNextStage());
        $this->assertEquals(Order::STATUS_PENDING_RECOMMENDATION, $order->getNextStatus());

        $this->actingAs($user);
        $result = $order->approveToNextStage('Test approval notes');

        $this->assertTrue($result);
        $this->assertEquals(Order::STATUS_PENDING_RECOMMENDATION, $order->status);
    }

    public function test_order_activity_log_records_approval()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        $this->actingAs($user);
        $order->approveToNextStage('Test approval notes');

        $this->assertDatabaseHas('activity_log', [
            'subject_id' => $order->id,
            'subject_type' => Order::class,
            'causer_id' => $user->id,
            'description' => 'Order approved to next stage',
        ]);
    }

    public function test_order_can_check_previous_status()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        // Created status has no previous status
        $this->assertNull($order->getPreviousStatus());
        $this->assertFalse($order->canSendBackToPreviousStage());

        // Move to next stage
        $this->actingAs($user);
        $order->approveToNextStage('Test approval');

        // Pending recommendation can go back to created
        $this->assertEquals(Order::STATUS_CREATED, $order->getPreviousStatus());
        $this->assertTrue($order->canSendBackToPreviousStage());
    }

    public function test_order_can_be_sent_back_to_previous_stage()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        // Move to pending recommendation
        $this->actingAs($user);
        $order->approveToNextStage('Test approval');
        $this->assertEquals(Order::STATUS_PENDING_RECOMMENDATION, $order->status);

        // Send back to created
        $result = $order->sendBackToPreviousStage('Test send back notes');

        $this->assertTrue($result);
        $this->assertEquals(Order::STATUS_CREATED, $order->status);
    }

    public function test_order_send_back_logs_activity()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        // Move to pending recommendation
        $this->actingAs($user);
        $order->approveToNextStage('Test approval');

        // Send back to created
        $order->sendBackToPreviousStage('Test send back notes');

        $this->assertDatabaseHas('activity_log', [
            'subject_id' => $order->id,
            'subject_type' => Order::class,
            'causer_id' => $user->id,
        ]);
    }

    public function test_order_send_back_deletes_finance_record()
    {
        $user = User::factory()->create();

        $order = Order::create([
            'name' => 'Test Order',
            'type' => Order::TYPE_STATION,
            'created_by' => $user->id,
            'state_id' => 1,
            'city_id' => 1,
            'coordinates' => '24.7136, 46.6753',
            'number_of_families' => 100,
            'water_source' => [Order::WATER_SOURCE_GOVERNMENT],
            'water_distance' => 5.5,
            'development_impact' => 'Test development impact',
            'order_justifications' => 'Test order justifications',
        ]);

        // Move order to PROJECT_MANAGER_APPROVED status (where finance records are created)
        $this->actingAs($user);
        $order->status = Order::STATUS_PROJECT_MANAGER_APPROVED;
        $order->save();

        // Create a finance record
        $order->finance()->create([
            'order_requirement_id' => 1,
            'count' => 1,
            'capacity' => '1000L',
            'execution_duration' => 30,
            'company_name' => 'Test Company',
            'offer_price' => 10000,
            'additional_fees' => 1000,
            'operation_cost_percentage' => 10,
        ]);

        $this->assertNotNull($order->finance);

        // Send back should delete the finance record
        $order->sendBackToPreviousStage('Sending back to fix requirements');

        $this->assertEquals(Order::STATUS_TECHNICAL_FINANCIAL_APPROVED, $order->status);
        $order->refresh();
        $this->assertNull($order->finance);
    }
}
