<?php

namespace Tests\Tenant\Reporting;

use App\Reporting\Repositories\CRMReportRepository;
use App\Reporting\StatsModels\EnquiryUtmBreakdown;
use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\Enquiry;
use Mtc\MercuryDataModels\ReportingStat;
use Tests\TenantTestCase;

class EnquiryUtmStatsTest extends TenantTestCase
{
    public function testGenerateAggregatesUtmBucketsIntoReportingStats(): void
    {
        $day = Carbon::yesterday();

        $this->enquiryWithUtm($day, ['utm_source' => 'google']);
        $this->enquiryWithUtm($day, ['utm_source' => 'google']);
        $this->enquiryWithUtm($day, ['utm_source' => 'facebook']);

        App::make(EnquiryUtmBreakdown::class)->generate($day);

        $this->assertSame(2, (int) $this->statValue('enquiry-utm:source:google', $day));
        $this->assertSame(1, (int) $this->statValue('enquiry-utm:source:facebook', $day));
    }

    public function testMissingUtmFallsBackToUncategorised(): void
    {
        $day = Carbon::yesterday();

        $this->enquiryWithUtm($day, ['utm_source' => '']);
        $this->enquiryWithUtm($day, []);

        App::make(EnquiryUtmBreakdown::class)->generate($day);

        $this->assertSame(2, (int) $this->statValue('enquiry-utm:source:uncategorised', $day));
    }

    public function testBackfillDaysOptionAggregatesEachDay(): void
    {
        $this->enquiryWithUtm(Carbon::yesterday(), ['utm_medium' => 'cpc']);
        $this->enquiryWithUtm(Carbon::today()->subDays(2), ['utm_medium' => 'cpc']);

        $this->artisan('stats:generate-utm', ['--days' => 3])->assertExitCode(0);

        $this->assertSame(1, (int) $this->statValue('enquiry-utm:medium:cpc', Carbon::yesterday()));
        $this->assertSame(1, (int) $this->statValue('enquiry-utm:medium:cpc', Carbon::today()->subDays(2)));
    }

    public function testRepositoryGroupsSumsAndFiltersByDate(): void
    {
        $this->stat('enquiry-utm:source:google', Carbon::today()->subDays(2), 4);
        $this->stat('enquiry-utm:source:google', Carbon::today()->subDays(1), 6);
        $this->stat('enquiry-utm:source:facebook', Carbon::today()->subDays(1), 3);
        // Outside the queried range.
        $this->stat('enquiry-utm:source:google', Carbon::today()->subDays(40), 99);

        $result = App::make(CRMReportRepository::class)->utmBreakdown(
            'source',
            Carbon::today()->subDays(7),
            Carbon::today(),
        );

        $this->assertSame(['google', 'facebook'], $result->pluck('type')->all());
        $this->assertSame(10, $result->firstWhere('type', 'google')['enquiry_count']);
        $this->assertSame(3, $result->firstWhere('type', 'facebook')['enquiry_count']);
    }

    public function testResolveDimensionDefaultsToSource(): void
    {
        $repository = App::make(CRMReportRepository::class);

        $this->assertSame('medium', $repository->resolveDimension('medium'));
        $this->assertSame('source', $repository->resolveDimension('not-a-dimension'));
        $this->assertSame('source', $repository->resolveDimension(null));
    }

    private function enquiryWithUtm(Carbon $date, array $utm): void
    {
        Enquiry::factory()->create([
            'ingested_at' => $date->copy()->setTime(10, 0),
            'data' => ['meta' => $utm],
        ]);
    }

    private function stat(string $key, Carbon $date, int $value): void
    {
        ReportingStat::create(['key' => $key, 'date' => $date->format('Y-m-d'), 'value' => $value]);
    }

    private function statValue(string $key, Carbon $date): ?string
    {
        return ReportingStat::query()
            ->where('key', $key)
            ->whereDate('date', $date->format('Y-m-d'))
            ->value('value');
    }
}
