<?php

namespace Tests\Unit\Models;

use Tests\TestCase;
use App\Models\Fstr;
use App\Models\FstrDetail;
use App\Models\User;
use App\Models\RawMaterial;
use Illuminate\Foundation\Testing\RefreshDatabase;

class FstrTest extends TestCase
{
    use RefreshDatabase;

    protected $testUser;
    protected $testRawMaterial;

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

        $this->testRawMaterial = RawMaterial::create([
            'code' => 'RM001',
            'name' => 'Test Raw Material',
            'unit_pakai' => 'KG',
            'unit_utuh' => 'SACK',
            'unit_kirim' => 'SACK',
            'konversi_satuan_utuh' => 'SACK',
            'konversi_satuan_pakai' => 'KG',
            'konversi_satuan_kirim' => 'SACK',
            'is_active' => true,
            'delete_flag' => false
        ]);
    }

    /** @test */
    public function it_can_create_fstr_with_auto_generated_code()
    {
        $fstr = Fstr::create([
            'name' => 'Kah Mie Ayam',
            'description' => 'Processed chicken noodle dish',
            'recipe_data' => [
                'ingredients' => [
                    ['raw_material_id' => $this->testRawMaterial->id, 'quantity' => 2, 'unit' => 'KG']
                ]
            ],
            'total_cost' => 50000,
            'is_active' => true,
            'created_by' => $this->testUser->id,
            'delete_flag' => false
        ]);

        $this->assertNotNull($fstr->code);
        $this->assertStringStartsWith('FSTR', $fstr->code);
        $this->assertEquals(10, strlen($fstr->code)); // FSTR + 6 digits
    }

    /** @test */
    public function it_generates_sequential_codes()
    {
        $fstr1 = Fstr::create([
            'name' => 'FSTR 1',
            'description' => 'Test FSTR 1',
            'total_cost' => 25000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $fstr2 = Fstr::create([
            'name' => 'FSTR 2',
            'description' => 'Test FSTR 2',
            'total_cost' => 30000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('FSTR000001', $fstr1->code);
        $this->assertEquals('FSTR000002', $fstr2->code);
    }

    /** @test */
    public function it_casts_attributes_correctly()
    {
        $recipeData = [
            'ingredients' => [
                ['raw_material_id' => $this->testRawMaterial->id, 'quantity' => 2, 'unit' => 'KG']
            ]
        ];

        $fstr = Fstr::create([
            'name' => 'Test FSTR',
            'description' => 'Test description',
            'recipe_data' => $recipeData,
            'total_cost' => '50000.75',
            'is_active' => '1',
            'delete_flag' => '0',
            'created_by' => $this->testUser->id
        ]);

        $this->assertIsArray($fstr->recipe_data);
        $this->assertEquals($recipeData, $fstr->recipe_data);
        $this->assertIsFloat($fstr->total_cost);
        $this->assertEquals(50000.75, $fstr->total_cost);
        $this->assertIsBool($fstr->is_active);
        $this->assertTrue($fstr->is_active);
        $this->assertIsBool($fstr->delete_flag);
        $this->assertFalse($fstr->delete_flag);
    }

    /** @test */
    public function it_has_correct_relationships()
    {
        $fstr = Fstr::create([
            'name' => 'Test FSTR',
            'description' => 'Test description',
            'total_cost' => 50000,
            'is_active' => true,
            'created_by' => $this->testUser->id,
            'updated_by' => $this->testUser->id,
            'delete_flag' => false
        ]);

        // Create FSTR details
        FstrDetail::create([
            'fstr_id' => $fstr->id,
            'raw_material_id' => $this->testRawMaterial->id,
            'quantity' => 2,
            'unit' => 'KG',
            'unit_cost' => 15000,
            'total_cost' => 30000,
            'delete_flag' => false
        ]);

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

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

        $this->assertCount(1, $fstr->fstrDetails);
        $this->assertInstanceOf(FstrDetail::class, $fstr->fstrDetails->first());
    }

    /** @test */
    public function it_can_scope_active_fstrs()
    {
        Fstr::create([
            'name' => 'Active FSTR',
            'description' => 'Active FSTR description',
            'total_cost' => 50000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        Fstr::create([
            'name' => 'Inactive FSTR',
            'description' => 'Inactive FSTR description',
            'total_cost' => 40000,
            'is_active' => false,
            'delete_flag' => false
        ]);

        Fstr::create([
            'name' => 'Deleted FSTR',
            'description' => 'Deleted FSTR description',
            'total_cost' => 45000,
            'is_active' => true,
            'delete_flag' => true
        ]);

        $activeFstrs = Fstr::active()->get();
        $this->assertCount(1, $activeFstrs);
        $this->assertEquals('Active FSTR', $activeFstrs->first()->name);
    }

    /** @test */
    public function it_formats_total_cost_correctly()
    {
        $fstr = Fstr::create([
            'name' => 'Test FSTR',
            'description' => 'Test description',
            'total_cost' => 50000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('Rp 50.000', $fstr->formatted_total_cost);

        $fstr->total_cost = 125500;
        $this->assertEquals('Rp 125.500', $fstr->formatted_total_cost);
    }

    /** @test */
    public function it_can_calculate_total_cost_from_details()
    {
        $fstr = Fstr::create([
            'name' => 'Test FSTR',
            'description' => 'Test description',
            'total_cost' => 0,
            'is_active' => true,
            'delete_flag' => false
        ]);

        // Create FSTR details
        FstrDetail::create([
            'fstr_id' => $fstr->id,
            'raw_material_id' => $this->testRawMaterial->id,
            'quantity' => 2,
            'unit' => 'KG',
            'unit_cost' => 15000,
            'total_cost' => 30000,
            'delete_flag' => false
        ]);

        FstrDetail::create([
            'fstr_id' => $fstr->id,
            'raw_material_id' => $this->testRawMaterial->id,
            'quantity' => 1,
            'unit' => 'KG',
            'unit_cost' => 20000,
            'total_cost' => 20000,
            'delete_flag' => false
        ]);

        $calculatedCost = $fstr->calculateTotalCost();
        $this->assertEquals(50000, $calculatedCost);
    }

    /** @test */
    public function it_handles_null_recipe_data()
    {
        $fstr = Fstr::create([
            'name' => 'Test FSTR',
            'description' => 'Test description',
            'recipe_data' => null,
            'total_cost' => 50000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertNull($fstr->recipe_data);
    }

    /** @test */
    public function it_handles_empty_recipe_data()
    {
        $fstr = Fstr::create([
            'name' => 'Test FSTR',
            'description' => 'Test description',
            'recipe_data' => [],
            'total_cost' => 50000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertIsArray($fstr->recipe_data);
        $this->assertEmpty($fstr->recipe_data);
    }

    /** @test */
    public function it_handles_complex_recipe_data()
    {
        $complexRecipe = [
            'ingredients' => [
                [
                    'raw_material_id' => $this->testRawMaterial->id,
                    'quantity' => 2.5,
                    'unit' => 'KG',
                    'notes' => 'Main ingredient'
                ]
            ],
            'instructions' => [
                'Step 1: Prepare ingredients',
                'Step 2: Cook for 30 minutes',
                'Step 3: Season to taste'
            ],
            'cooking_time' => 45,
            'serving_size' => 4
        ];

        $fstr = Fstr::create([
            'name' => 'Complex FSTR',
            'description' => 'Complex recipe FSTR',
            'recipe_data' => $complexRecipe,
            'total_cost' => 75000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals($complexRecipe, $fstr->recipe_data);
        $this->assertEquals(45, $fstr->recipe_data['cooking_time']);
        $this->assertCount(3, $fstr->recipe_data['instructions']);
    }

    /** @test */
    public function it_uses_correct_table_name()
    {
        $fstr = new Fstr();
        $this->assertEquals('m_fstrs', $fstr->getTable());
    }
}