<?php

namespace Tests\Unit\Models;

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

class MenuTest 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_menu_with_auto_generated_code()
    {
        $menu = Menu::create([
            'name' => 'Bakmi Ayam',
            'menu_group' => 'Noodles',
            'plu_code' => 'PLU001',
            'category' => 'Main Course',
            'price' => 25000,
            'description' => 'Delicious chicken noodles',
            'is_active' => true,
            'created_by' => $this->testUser->id,
            'delete_flag' => false
        ]);

        $this->assertNotNull($menu->code);
        $this->assertStringStartsWith('MN', $menu->code);
        $this->assertEquals(8, strlen($menu->code)); // MN + 6 digits
    }

    /** @test */
    public function it_generates_sequential_codes()
    {
        $menu1 = Menu::create([
            'name' => 'Menu 1',
            'menu_group' => 'Test',
            'plu_code' => 'PLU001',
            'category' => 'Test',
            'price' => 10000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $menu2 = Menu::create([
            'name' => 'Menu 2',
            'menu_group' => 'Test',
            'plu_code' => 'PLU002',
            'category' => 'Test',
            'price' => 15000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('MN000001', $menu1->code);
        $this->assertEquals('MN000002', $menu2->code);
    }

    /** @test */
    public function it_casts_attributes_correctly()
    {
        $menu = Menu::create([
            'name' => 'Test Menu',
            'menu_group' => 'Test',
            'plu_code' => 'PLU001',
            'category' => 'Test',
            'price' => '25000.50',
            'is_active' => '1',
            'delete_flag' => '0',
            'created_by' => $this->testUser->id
        ]);

        $this->assertIsFloat($menu->price);
        $this->assertEquals(25000.50, $menu->price);
        $this->assertIsBool($menu->is_active);
        $this->assertTrue($menu->is_active);
        $this->assertIsBool($menu->delete_flag);
        $this->assertFalse($menu->delete_flag);
    }

    /** @test */
    public function it_has_correct_relationships()
    {
        $menu = Menu::create([
            'name' => 'Test Menu',
            'menu_group' => 'Test',
            'plu_code' => 'PLU001',
            'category' => 'Test',
            'price' => 25000,
            'is_active' => true,
            'created_by' => $this->testUser->id,
            'updated_by' => $this->testUser->id,
            'delete_flag' => false
        ]);

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

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

    /** @test */
    public function it_can_scope_active_menus()
    {
        Menu::create([
            'name' => 'Active Menu',
            'menu_group' => 'Test',
            'plu_code' => 'PLU001',
            'category' => 'Test',
            'price' => 25000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        Menu::create([
            'name' => 'Inactive Menu',
            'menu_group' => 'Test',
            'plu_code' => 'PLU002',
            'category' => 'Test',
            'price' => 25000,
            'is_active' => false,
            'delete_flag' => false
        ]);

        Menu::create([
            'name' => 'Deleted Menu',
            'menu_group' => 'Test',
            'plu_code' => 'PLU003',
            'category' => 'Test',
            'price' => 25000,
            'is_active' => true,
            'delete_flag' => true
        ]);

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

    /** @test */
    public function it_can_scope_by_group()
    {
        Menu::create([
            'name' => 'Noodle Menu',
            'menu_group' => 'Noodles',
            'plu_code' => 'PLU001',
            'category' => 'Main Course',
            'price' => 25000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        Menu::create([
            'name' => 'Rice Menu',
            'menu_group' => 'Rice',
            'plu_code' => 'PLU002',
            'category' => 'Main Course',
            'price' => 30000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $noodleMenus = Menu::byGroup('Noodles')->get();
        $this->assertCount(1, $noodleMenus);
        $this->assertEquals('Noodle Menu', $noodleMenus->first()->name);

        $riceMenus = Menu::byGroup('Rice')->get();
        $this->assertCount(1, $riceMenus);
        $this->assertEquals('Rice Menu', $riceMenus->first()->name);
    }

    /** @test */
    public function it_formats_price_correctly()
    {
        $menu = Menu::create([
            'name' => 'Test Menu',
            'menu_group' => 'Test',
            'plu_code' => 'PLU001',
            'category' => 'Test',
            'price' => 25000,
            'is_active' => true,
            'delete_flag' => false
        ]);

        $this->assertEquals('Rp 25.000', $menu->formatted_price);

        $menu->price = 125500;
        $this->assertEquals('Rp 125.500', $menu->formatted_price);
    }

    /** @test */
    public function it_handles_fillable_attributes()
    {
        $attributes = [
            'code' => 'MN000001',
            'name' => 'Test Menu',
            'menu_group' => 'Test Group',
            'plu_code' => 'PLU001',
            'category' => 'Test Category',
            'price' => 25000,
            'description' => 'Test description',
            'is_active' => true,
            'delete_flag' => false,
            'created_by' => $this->testUser->id,
            'updated_by' => $this->testUser->id,
        ];

        $menu = new Menu();
        $menu->fill($attributes);

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

    /** @test */
    public function it_uses_correct_table_name()
    {
        $menu = new Menu();
        $this->assertEquals('m_menus', $menu->getTable());
    }
}