<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use App\Services\OfferBulkUpdateService;
use Mtc\MercuryDataModels\VehicleOffer;
use Mtc\MercuryDataModels\VehicleOfferFinance;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class OfferBulkUpdateServiceTest extends TenantTestCase
{
    use UserForTenant;

    private function enableOfferVersioning(): void
    {
        tenant()->tier = 'pro';
        Settings::make([
            'tab' => 'test',
            'section' => 'test',
            'group' => 'test',
            'name' => 'test',
            'value' => true,
            'type' => 'bool',
            'config_key' => 'offers-versioning-enabled',
        ]);
    }

    public function testSameModeUpdateAppliesValueToEveryOffer(): void
    {
        $offers = VehicleOffer::factory(3)->create(['price' => 1000]);

        $count = new OfferBulkUpdateService()
            ->update('same', $offers->pluck('id')->all(), ['field' => 'price', 'value' => 7500]);

        $this->assertSame(3, $count);
        foreach ($offers as $offer) {
            $this->assertEquals(7500, $offer->fresh()->price);
        }
    }

    public function testDifferentModeUpdatesPerOfferFields(): void
    {
        $first = VehicleOffer::factory()->create(['price' => 1000, 'name' => 'first']);
        $second = VehicleOffer::factory()->create(['price' => 2000, 'name' => 'second']);

        $count = new OfferBulkUpdateService()
            ->update('different', [$first->id, $second->id], [
                'updates' => [
                    $first->id => ['price' => 1234],
                    $second->id => ['name' => 'renamed'],
                ],
            ]);

        $this->assertSame(2, $count);
        $this->assertEquals(1234, $first->fresh()->price);
        $this->assertSame('renamed', $second->fresh()->name);
    }

    public function testDeleteFinanceExamplesRemovesOfferFinance(): void
    {
        $offer = VehicleOffer::factory()->create();
        VehicleOfferFinance::query()->create(['offer_id' => $offer->id, 'monthly_price' => 100]);
        VehicleOfferFinance::query()->create(['offer_id' => $offer->id, 'monthly_price' => 200]);

        $count = new OfferBulkUpdateService()->deleteFinanceExamples([$offer->id]);

        $this->assertSame(1, $count);
        $this->assertCount(0, $offer->finance()->get());
    }

    public function testVersioningPublishAppliesLiveAndCreatesActiveVersion(): void
    {
        $this->enableOfferVersioning();
        $this->actingAs($this->getUser());
        $offer = VehicleOffer::factory()->create(['price' => 1000]);

        $count = new OfferBulkUpdateService()
            ->update('same', [$offer->id], ['field' => 'price', 'value' => 7500], 'publish');

        $this->assertSame(1, $count);
        $this->assertEquals(7500, $offer->fresh()->price);

        $versions = $offer->versions()->get();
        $this->assertCount(1, $versions);
        $this->assertTrue((bool) $versions->first()->is_active);
        $this->assertEquals(7500, $versions->first()->data['price'] ?? null);
    }

    public function testVersioningDraftAppliesLiveAndCreatesInactiveVersion(): void
    {
        $this->enableOfferVersioning();
        $this->actingAs($this->getUser());
        $offer = VehicleOffer::factory()->create(['price' => 1000]);

        $count = new OfferBulkUpdateService()
            ->update('same', [$offer->id], ['field' => 'price', 'value' => 5000], 'draft');

        $this->assertSame(1, $count);
        $this->assertEquals(5000, $offer->fresh()->price);

        $version = $offer->versions()->first();
        $this->assertNotNull($version);
        $this->assertFalse((bool) $version->is_active);
    }

    public function testExcludedFieldsAreNotInAllowedFields(): void
    {
        $allowed = new OfferBulkUpdateService()->getAllowedFields();

        $this->assertNotContains('slug', $allowed);
        $this->assertNotContains('uuid', $allowed);
        $this->assertNotContains('data', $allowed);
        $this->assertContains('price', $allowed);
        $this->assertContains('published', $allowed);
    }
}
