<?php

namespace Tests\Tenant;


use App\Models\ImportCondition;
use App\Models\ImportMap;
use Illuminate\Support\Str;
use Mtc\MercuryDataModels\Label;
use Mtc\MercuryDataModels\Setting;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class ImportConditionControllerTest extends TenantTestCase
{
    use UserForTenant;

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testIndex()
    {
        ImportCondition::factory(3)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.import-conditions.index'));

        $response->assertStatus(200);
        $this->assertIsArray($response->json('data'));
        $this->assertCount(3, $response->json('data'));
    }

    public function testStore()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.import-conditions.store'), [
                'provider' => 'foo'
            ]);

        $response->assertStatus(201);
        $this->assertEquals('foo', $response->json('provider'));
        $this->assertTrue(ImportCondition::query()->where('provider', 'foo')->exists());

    }

    public function testUpdate()
    {
        $condition = ImportCondition::factory()->create(['provider' => 'foo']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.import-conditions.update', $condition->id), [
                'provider' => 'baz',
                'active' => true,
                'do_not_publish' => true,
                'rules' => [
                    [
                        'id' => Str::random(12),
                        'field' => 'baz',
                        'condition' => '=',
                        'value' => 'faz',
                    ]
                ]
            ]);

        $condition->refresh();
        $response->assertStatus(200);
        $this->assertEquals('baz', $condition->provider);
        $this->assertEquals(1, $condition->rules()->count());
        $rule = $condition->rules()->first();
        $this->assertEquals('baz', $rule->field);
        $this->assertEquals('=', $rule->condition);
        $this->assertEquals('faz', $rule->value);

    }

    public function testShow()
    {
        $condition = ImportCondition::factory()->create(['provider' => 'foo']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.import-conditions.show', $condition->id));

        $response->assertStatus(200);
        $this->assertEquals($condition->id, $response->json('id'));
        $this->assertEquals('foo', $response->json('provider'));

    }

    public function testDelete()
    {
        $condition = ImportCondition::factory()->create(['provider' => 'foo']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->deleteJson(route('tenant.import-conditions.destroy', $condition->id));

        $response->assertStatus(200);
        $this->assertFalse(ImportCondition::query()->where('id', $condition->id)->exists());
    }

    public function testGetProviders()
    {
        $map = ImportMap::factory()->create();
        Setting::query()->create([
            'tab' => 'foo',
            'section' => 'foo',
            'group' => 'foo',
            'name' => 'foo',
            'config_key' => 'stock-file-enabled',
            'type' => 'boolean',
            'value' => true
        ]);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.import-conditions.get-providers'));

        $response->assertStatus(200);
        $this->assertArrayHasKey('import_maps', $response->json());
        $this->assertArrayHasKey('providers', $response->json());
        $this->assertCount(1, $response->json('import_maps'));
        $this->assertEquals($map->id, $response->json('import_maps.0.id'));
        $this->assertEquals($map->name, $response->json('import_maps.0.name'));
        $this->assertCount(1, $response->json('providers'));
        $this->assertEquals('import-map', $response->json('providers.0.id'));
    }

    public function testGetRules()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.import-conditions.get-rules'), [
                'field' => 'make_id',
            ]);

        $response->assertStatus(200);
        $this->assertArrayHasKey('fields', $response->json());
        $this->assertArrayHasKey('conditions', $response->json());
        $this->assertArrayHasKey('values', $response->json());
    }

    public function testGetRulesIncludesLabelField()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.import-conditions.get-rules'), []);

        $response->assertStatus(200);
        $fieldIds = collect($response->json('fields'))->pluck('id')->all();
        $this->assertContains('label', $fieldIds);
    }

    public function testGetRulesReturnsActiveLabelsAsValues()
    {
        $active = Label::factory()->create(['name' => 'Hot Deals', 'active' => true]);
        $inactive = Label::factory()->create(['name' => 'Old', 'active' => false]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.import-conditions.get-rules'), [
                'field' => 'label',
            ]);

        $response->assertStatus(200);
        $valueIds = collect($response->json('values'))->pluck('id')->all();
        $this->assertContains($active->id, $valueIds);
        $this->assertNotContains($inactive->id, $valueIds);
    }
}
