<?php

namespace Tests\Tenant;

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

class OfferBulkUpdateServiceTest extends TenantTestCase
{
    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 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);
    }

    public function testArchiveSoftDeletesSelectedOffersAndSkipsTrashed(): void
    {
        $active = VehicleOffer::factory(2)->create();
        $alreadyArchived = VehicleOffer::factory()->create();
        $alreadyArchived->delete();

        $ids = $active->pluck('id')->push($alreadyArchived->id)->all();
        $archived = new OfferBulkUpdateService()->archive($ids);

        $this->assertSame(2, $archived, 'Already-archived offers must not be re-counted.');
        foreach ($active as $offer) {
            $this->assertTrue($offer->fresh()->trashed());
        }
        $this->assertSame(0, VehicleOffer::query()->whereIn('id', $ids)->count());
        $this->assertSame(3, VehicleOffer::withTrashed()->whereIn('id', $ids)->count());
    }
}
