<?php

namespace Tests\Unit\Models;

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

class ReasonAdjustmentTest extends TestCase
{
    use RefreshDatabase;

    protected $testUser;

    protected function setUp(): void
    {
        parent::setUp();
        
        $this->testUser = User::create([
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => bcrypt('password'),
        ]);
    }

    /** @test */
    public function it_can_create_reason_adjustment_with_auto_generated_code()
    {
        $reasonAdjustment = ReasonAdjustment::create([
            'name' => 'Big Order',
            'description' => 'Adjustment due to big order from customer',
            'category' => 'Positive',
            'is_active' => true,
            'created_by' => $this->testUser->id,
            'delete_flag' => false
        ]);

        $this->assertNotNull($reasonAdjustment->code);
        $this->assertStringStartsWith('ADJ', $reasonAdjustment->code);
        $this->assertEquals(6, strlen($reasonAdjustment->code)); // ADJ + 3 digits
    }

    /** @test */
    public function it_generates_sequential_codes()
    {
        $reason1 = ReasonAdjustment::create([
            'name' => 'Reason 1',
            'description' => 'Test reason 1',
            'category' => 'Positive',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $reason2 = ReasonAdjustment::create([
            'name' => 'Reason 2',
            'description' => 'Test reason 2',
            'category' => 'Negative',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('ADJ001', $reason1->code);
        $this->assertEquals('ADJ002', $reason2->code);
    }

    /** @test */
    public function it_casts_attributes_correctly()
    {
        $reasonAdjustment = ReasonAdjustment::create([
            'name' => 'Test Reason',
            'description' => 'Test description',
            'category' => 'Neutral',
            'is_active' => '1',
            'delete_flag' => '0',
            'created_by' => $this->testUser->id
        ]);

        $this->assertIsBool($reasonAdjustment->is_active);
        $this->assertTrue($reasonAdjustment->is_active);
        $this->assertIsBool($reasonAdjustment->delete_flag);
        $this->assertFalse($reasonAdjustment->delete_flag);
    }

    /** @test */
    public function it_has_correct_relationships()
    {
        $reasonAdjustment = ReasonAdjustment::create([
            'name' => 'Test Reason',
            'description' => 'Test description',
            'category' => 'Positive',
            'is_active' => true,
            'created_by' => $this->testUser->id,
            'updated_by' => $this->testUser->id,
            'delete_flag' => false
        ]);

        $this->assertInstanceOf(User::class, $reasonAdjustment->creator);
        $this->assertEquals($this->testUser->id, $reasonAdjustment->creator->id);

        $this->assertInstanceOf(User::class, $reasonAdjustment->modificator);
        $this->assertEquals($this->testUser->id, $reasonAdjustment->modificator->id);
    }

    /** @test */
    public function it_can_scope_active_reasons()
    {
        ReasonAdjustment::create([
            'name' => 'Active Reason',
            'description' => 'Active reason description',
            'category' => 'Positive',
            'is_active' => true,
            'delete_flag' => false
        ]);

        ReasonAdjustment::create([
            'name' => 'Inactive Reason',
            'description' => 'Inactive reason description',
            'category' => 'Negative',
            'is_active' => false,
            'delete_flag' => false
        ]);

        ReasonAdjustment::create([
            'name' => 'Deleted Reason',
            'description' => 'Deleted reason description',
            'category' => 'Neutral',
            'is_active' => true,
            'delete_flag' => true
        ]);

        $activeReasons = ReasonAdjustment::active()->get();
        $this->assertCount(1, $activeReasons);
        $this->assertEquals('Active Reason', $activeReasons->first()->name);
    }

    /** @test */
    public function it_can_scope_by_category()
    {
        ReasonAdjustment::create([
            'name' => 'Big Order',
            'description' => 'Positive adjustment',
            'category' => 'Positive',
            'is_active' => true,
            'delete_flag' => false
        ]);

        ReasonAdjustment::create([
            'name' => 'Forecast Issue',
            'description' => 'Negative adjustment',
            'category' => 'Negative',
            'is_active' => true,
            'delete_flag' => false
        ]);

        ReasonAdjustment::create([
            'name' => 'GM Day',
            'description' => 'Neutral adjustment',
            'category' => 'Neutral',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $positiveReasons = ReasonAdjustment::byCategory('Positive')->get();
        $this->assertCount(1, $positiveReasons);
        $this->assertEquals('Big Order', $positiveReasons->first()->name);

        $negativeReasons = ReasonAdjustment::byCategory('Negative')->get();
        $this->assertCount(1, $negativeReasons);
        $this->assertEquals('Forecast Issue', $negativeReasons->first()->name);

        $neutralReasons = ReasonAdjustment::byCategory('Neutral')->get();
        $this->assertCount(1, $neutralReasons);
        $this->assertEquals('GM Day', $neutralReasons->first()->name);
    }

    /** @test */
    public function it_generates_category_badge_html()
    {
        $positiveReason = ReasonAdjustment::create([
            'name' => 'Big Order',
            'description' => 'Positive adjustment',
            'category' => 'Positive',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $negativeReason = ReasonAdjustment::create([
            'name' => 'Forecast Issue',
            'description' => 'Negative adjustment',
            'category' => 'Negative',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $neutralReason = ReasonAdjustment::create([
            'name' => 'GM Day',
            'description' => 'Neutral adjustment',
            'category' => 'Neutral',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('<span class="badge badge-success">Positive</span>', $positiveReason->category_badge);
        $this->assertEquals('<span class="badge badge-danger">Negative</span>', $negativeReason->category_badge);
        $this->assertEquals('<span class="badge badge-secondary">Neutral</span>', $neutralReason->category_badge);
    }

    /** @test */
    public function it_handles_unknown_category_in_badge()
    {
        $unknownReason = ReasonAdjustment::create([
            'name' => 'Unknown Reason',
            'description' => 'Unknown category',
            'category' => 'Unknown',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('<span class="badge badge-secondary">Unknown</span>', $unknownReason->category_badge);
    }

    /** @test */
    public function it_can_create_predefined_reasons()
    {
        $bigOrder = ReasonAdjustment::create([
            'name' => 'Big Order',
            'description' => 'Adjustment due to big order from customer',
            'category' => 'Positive',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $gmDay = ReasonAdjustment::create([
            'name' => 'GM Day',
            'description' => 'Adjustment for GM Day special event',
            'category' => 'Neutral',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $forecastIssue = ReasonAdjustment::create([
            'name' => 'Forecast Issue',
            'description' => 'Adjustment due to forecast calculation issue',
            'category' => 'Negative',
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertDatabaseHas('m_reason_adjustments', ['name' => 'Big Order', 'category' => 'Positive']);
        $this->assertDatabaseHas('m_reason_adjustments', ['name' => 'GM Day', 'category' => 'Neutral']);
        $this->assertDatabaseHas('m_reason_adjustments', ['name' => 'Forecast Issue', 'category' => 'Negative']);
    }

    /** @test */
    public function it_handles_fillable_attributes()
    {
        $attributes = [
            'code' => 'ADJ001',
            'name' => 'Test Reason',
            'description' => 'Test description',
            'category' => 'Positive',
            'is_active' => true,
            'delete_flag' => false,
            'created_by' => $this->testUser->id,
            'updated_by' => $this->testUser->id,
        ];

        $reasonAdjustment = new ReasonAdjustment();
        $reasonAdjustment->fill($attributes);

        foreach ($attributes as $key => $value) {
            if (in_array($key, ['created_at', 'updated_at'])) {
                continue;
            }
            $this->assertEquals($value, $reasonAdjustment->$key);
        }
    }

    /** @test */
    public function it_uses_correct_table_name()
    {
        $reasonAdjustment = new ReasonAdjustment();
        $this->assertEquals('m_reason_adjustments', $reasonAdjustment->getTable());
    }
}