<?php

namespace Tests\Tenant;

use Mtc\MercuryDataModels\CatalogOffer;
use Mtc\MercuryDataModels\CatalogOfferRule;
use Mtc\MercuryDataModels\Label;
use Mtc\MercuryDataModels\VehicleMake;
use Tests\TenantTestCase;

class CatalogOfferRuleTest extends TenantTestCase
{
    public function testRuleBelongsToCatalogOffer()
    {
        $offer = CatalogOffer::factory()->create();
        $rule = CatalogOfferRule::query()->create([
            'catalog_offer_id' => $offer->id,
            'field' => 'make_id',
            'condition' => '=',
            'value' => '123',
        ]);

        $this->assertEquals($offer->id, $rule->catalogOffer->id);
    }

    public function testCatalogOfferHasManyRules()
    {
        $offer = CatalogOffer::factory()->create();
        CatalogOfferRule::query()->create([
            'catalog_offer_id' => $offer->id,
            'field' => 'make_id',
            'condition' => '=',
            'value' => '123',
        ]);
        CatalogOfferRule::query()->create([
            'catalog_offer_id' => $offer->id,
            'field' => 'price',
            'condition' => '>',
            'value' => '10000',
        ]);

        $this->assertCount(2, $offer->rules);
    }

    public function testFieldNameAttribute()
    {
        $rule = new CatalogOfferRule([
            'field' => 'make_id',
            'condition' => '=',
            'value' => '123',
        ]);

        $this->assertNotNull($rule->field_name);
        $this->assertIsString($rule->field_name);
    }

    public function testConditionNameAttribute()
    {
        $rule = new CatalogOfferRule([
            'field' => 'make_id',
            'condition' => '=',
            'value' => '123',
        ]);

        $this->assertNotNull($rule->condition_name);
        $this->assertIsString($rule->condition_name);
    }

    public function testValueNameAttributeWithRelatedModel()
    {
        // Use tenant VehicleMake since ImportConditionRepository uses Mtc\MercuryDataModels\VehicleMake
        $make = VehicleMake::factory()->create(['name' => 'Test Make']);

        $rule = new CatalogOfferRule([
            'field' => 'make_id',
            'condition' => '=',
            'value' => $make->id,
        ]);

        $this->assertEquals('Test Make', $rule->value_name);
    }

    public function testValueNameAttributeWithPlainValue()
    {
        $rule = new CatalogOfferRule([
            'field' => 'price',
            'condition' => '>',
            'value' => '10000',
        ]);

        $this->assertEquals('10000', $rule->value_name);
    }

    public function testRuleAppendsAttributes()
    {
        $offer = CatalogOffer::factory()->create();
        $rule = CatalogOfferRule::query()->create([
            'catalog_offer_id' => $offer->id,
            'field' => 'price',
            'condition' => '>',
            'value' => '5000',
        ]);

        $array = $rule->toArray();

        $this->assertArrayHasKey('field_name', $array);
        $this->assertArrayHasKey('condition_name', $array);
        $this->assertArrayHasKey('value_name', $array);
    }

    public function testValueNameAttributeWithJsonEncodedArray()
    {
        $make1 = VehicleMake::factory()->create(['name' => 'Ford']);
        $make2 = VehicleMake::factory()->create(['name' => 'BMW']);
        $make3 = VehicleMake::factory()->create(['name' => 'Audi']);

        $rule = new CatalogOfferRule([
            'field' => 'make_id',
            'condition' => 'in',
            'value' => json_encode([$make1->id, $make2->id, $make3->id]),
        ]);

        $this->assertEquals('Ford, BMW, Audi', $rule->value_name);
    }

    public function testParsedValueAttributeWithJsonEncodedArray()
    {
        $rule = new CatalogOfferRule([
            'field' => 'make_id',
            'condition' => 'in',
            'value' => json_encode([1, 2, 3]),
        ]);

        $this->assertIsArray($rule->parsed_value);
        $this->assertEquals([1, 2, 3], $rule->parsed_value);
    }

    public function testParsedValueAttributeWithPlainValue()
    {
        $rule = new CatalogOfferRule([
            'field' => 'make_id',
            'condition' => '=',
            'value' => '123',
        ]);

        $this->assertEquals('123', $rule->parsed_value);
    }

    public function testValueNameAttributeWithLabel()
    {
        $label = Label::factory()->create(['name' => 'Hot Deals']);

        $rule = new CatalogOfferRule([
            'field' => 'label',
            'condition' => '=',
            'value' => $label->id,
        ]);

        $this->assertEquals('Hot Deals', $rule->value_name);
    }

    public function testValueNameAttributeWithLabelInList()
    {
        $label1 = Label::factory()->create(['name' => 'Hot Deals']);
        $label2 = Label::factory()->create(['name' => 'Featured']);

        $rule = new CatalogOfferRule([
            'field' => 'label',
            'condition' => 'in',
            'value' => json_encode([$label1->id, $label2->id]),
        ]);

        $this->assertEquals('Hot Deals, Featured', $rule->value_name);
    }

    public function testValueNameAttributeWithConditionNew()
    {
        $rule = new CatalogOfferRule([
            'field' => 'condition',
            'condition' => '=',
            'value' => 1,
        ]);

        $this->assertEquals('New', $rule->value_name);
    }

    public function testValueNameAttributeWithConditionUsed()
    {
        $rule = new CatalogOfferRule([
            'field' => 'condition',
            'condition' => '=',
            'value' => 0,
        ]);

        $this->assertEquals('Used', $rule->value_name);
    }

    public function testRuleAppendsIncludesParsedValue()
    {
        $offer = CatalogOffer::factory()->create();
        $rule = CatalogOfferRule::query()->create([
            'catalog_offer_id' => $offer->id,
            'field' => 'make_id',
            'condition' => 'in',
            'value' => json_encode([1, 2, 3]),
        ]);

        $array = $rule->toArray();

        $this->assertArrayHasKey('parsed_value', $array);
        $this->assertIsArray($array['parsed_value']);
        $this->assertEquals([1, 2, 3], $array['parsed_value']);
    }
}
