<?php

namespace Tests\Tenant\Reporting;

use App\DashboardRepository;
use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Mtc\Crm\Models\EnquiryObject;
use Mtc\MercuryDataModels\Enquiry;
use Mtc\MercuryDataModels\NewCar;
use Mtc\MercuryDataModels\ResourceView;
use Mtc\MercuryDataModels\VehicleOffer;
use Tests\TenantTestCase;

class PopularSegmentsTest extends TenantTestCase
{
    private Carbon $from;
    private Carbon $to;

    protected function setUp(): void
    {
        parent::setUp();
        $this->from = Carbon::now()->subDays(7);
        $this->to = Carbon::now();
    }

    public function testPopularOffersRankByViewsAndEnquiries(): void
    {
        $popular = VehicleOffer::factory()->create(['published' => true]);
        VehicleOffer::factory()->create(['published' => true]);

        ResourceView::create([
            'viewable_type' => 'offer',
            'viewable_id' => $popular->id,
            'date' => Carbon::today(),
            'hits' => 25,
        ]);

        $this->linkEnquiry('offer', $popular->id, Carbon::now());

        $result = App::make(DashboardRepository::class)->popularOffers($this->from, $this->to);

        $this->assertArrayHasKey('views', $result);
        $this->assertArrayHasKey('enquiries', $result);

        $this->assertSame($popular->id, $result['views'][0]['id']);
        $this->assertEquals(25, $result['views'][0]['view_count']);

        $this->assertSame($popular->id, $result['enquiries'][0]['id']);
        $this->assertEquals(1, $result['enquiries'][0]['enquiry_count']);
    }

    public function testPopularNewCarsRankByEnquiriesAndExposeNoViews(): void
    {
        $popular = NewCar::factory()->create(['published' => 1, 'published_at' => Carbon::now()->subDay()]);
        NewCar::factory()->create(['published' => 1, 'published_at' => Carbon::now()->subDay()]);

        $this->linkEnquiry('new-car', $popular->id, Carbon::now());

        $result = App::make(DashboardRepository::class)->popularNewCars($this->from, $this->to);

        // New car views are not tracked, so only enquiries are exposed.
        $this->assertArrayNotHasKey('views', $result);
        $this->assertArrayHasKey('enquiries', $result);

        $this->assertSame($popular->id, $result['enquiries'][0]['id']);
        $this->assertEquals(1, $result['enquiries'][0]['enquiry_count']);
    }

    public function testEnquiriesOutsideTheRangeAreExcluded(): void
    {
        $offer = VehicleOffer::factory()->create(['published' => true]);
        $this->linkEnquiry('offer', $offer->id, Carbon::now()->subDays(40));

        $result = App::make(DashboardRepository::class)->popularOffers($this->from, $this->to);

        $row = collect($result['enquiries'])->firstWhere('id', $offer->id);
        $this->assertEquals(0, $row['enquiry_count']);
    }

    public function testPopularDataGatesOffersAndNewCarsByFeature(): void
    {
        $data = App::make(DashboardRepository::class)->popularData($this->from, $this->to);

        // Vehicles always present; offers/new cars require the new-vehicles feature (off here).
        $this->assertArrayHasKey('vehicles', $data);
        $this->assertArrayNotHasKey('offers', $data);
        $this->assertArrayNotHasKey('new_cars', $data);
    }

    private function linkEnquiry(string $objectType, int $objectId, Carbon $ingestedAt): void
    {
        $enquiry = Enquiry::factory()->create(['ingested_at' => $ingestedAt]);

        EnquiryObject::factory()->create([
            'enquiry_id' => $enquiry->id,
            'object_type' => $objectType,
            'object_id' => $objectId,
        ]);
    }
}
