<?php

namespace Tests\Feature;

use App\Enums\LandingPageLayoutMode;
use App\Enums\LandingPageVersion;
use App\Models\CatalogLandingPageClickout;
use App\Models\CatalogLandingPageVisit;
use App\Models\LandingPage;
use App\Models\LandingPageGeneration;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CatalogLandingPageAnalyticsTest extends TestCase
{
    use RefreshDatabase;

    public function test_show_records_a_visit_with_query_params(): void
    {
        $page = $this->publicCatalogPage();

        $this->get($this->showUrl($page).'?utm_source=google&utm_campaign=spring&utm_medium=cpc')
            ->assertOk()
            ->assertSee('__admediaCatalogPageLoadId', false)
            ->assertSee('__admediaCatalogClickoutUrl', false);

        $this->assertDatabaseCount('catalog_landing_page_visits', 1);

        $visit = CatalogLandingPageVisit::query()->first();

        $this->assertNotNull($visit);
        $this->assertSame($page->id, $visit->landing_page_id);
        $this->assertSame([
            'utm_source' => 'google',
            'utm_campaign' => 'spring',
            'utm_medium' => 'cpc',
        ], $visit->query_params);
    }

    public function test_clickout_endpoint_records_a_clickout_for_the_visit(): void
    {
        $page = $this->publicCatalogPage();
        $visit = CatalogLandingPageVisit::factory()->for($page, 'landingPage')->create();

        $this->postJson($this->clickoutUrl($page), [
            'page_load_id' => $visit->page_load_id,
            'destination_url' => 'https://click.validclick.net/rdr3.php?url=https%3A%2F%2Fexample.com%2Fproduct',
        ])->assertCreated()
            ->assertJson(['ok' => true]);

        $this->assertDatabaseCount('catalog_landing_page_clickouts', 1);

        $clickout = CatalogLandingPageClickout::query()->first();

        $this->assertNotNull($clickout);
        $this->assertSame($visit->id, $clickout->catalog_landing_page_visit_id);
        $this->assertSame($page->id, $clickout->landing_page_id);
    }

    public function test_clickout_endpoint_rejects_an_unknown_page_load_id(): void
    {
        $page = $this->publicCatalogPage();

        $this->postJson($this->clickoutUrl($page), [
            'page_load_id' => '00000000-0000-4000-8000-000000000001',
            'destination_url' => 'https://example.com/product',
        ])->assertNotFound();
    }

    public function test_analytics_page_lists_visits_and_clickout_counts(): void
    {
        $user = User::factory()->create();
        $page = $this->publicCatalogPage($user);

        $visitWithClick = CatalogLandingPageVisit::factory()
            ->for($page, 'landingPage')
            ->create([
                'query_params' => ['utm_source' => 'google', 'utm_campaign' => 'spring'],
            ]);

        CatalogLandingPageClickout::factory()
            ->forVisit($visitWithClick)
            ->count(2)
            ->create();

        CatalogLandingPageVisit::factory()
            ->for($page, 'landingPage')
            ->withoutQueryParams()
            ->create();

        $this->actingAs($user)
            ->get(route('catalog-landing-pages.analytics', [$page->generation, $page]))
            ->assertOk()
            ->assertSee('Analytics')
            ->assertSee('utm_source=google, utm_campaign=spring')
            ->assertSee('2')
            ->assertSee('Visits')
            ->assertSee('Clickouts');
    }

    public function test_analytics_page_is_forbidden_for_other_users(): void
    {
        $owner = User::factory()->create();
        $other = User::factory()->create();
        $page = $this->publicCatalogPage($owner);

        $this->actingAs($other)
            ->get(route('catalog-landing-pages.analytics', [$page->generation, $page]))
            ->assertForbidden();
    }

    /**
     * @param  array<string, mixed>  $overrides
     */
    private function publicCatalogPage(?User $user = null, array $overrides = []): LandingPage
    {
        $generation = LandingPageGeneration::factory()
            ->catalog()
            ->withPartnerWebsite()
            ->withAffiliateTracking()
            ->for($user ?? User::factory())
            ->create([
                'layout_mode' => LandingPageLayoutMode::Catalog,
            ]);

        $page = LandingPage::factory()
            ->for($generation, 'generation')
            ->completed()
            ->create(array_merge([
                'version' => LandingPageVersion::Benefits,
                'html' => '<section class="product-rows"><a class="row-cta" href="https://example.com/product">Shop</a></section>',
            ], $overrides));

        $generation->update([
            'published_landing_page_id' => $page->id,
            'published_at' => now(),
        ]);

        return $page->fresh(['generation']);
    }

    private function showUrl(LandingPage $page): string
    {
        $page->load('generation');

        return route('public-prompt-landing-pages.show', [
            'domain' => $page->generation->publicHost(),
            'purpose' => $page->purposeSlug(),
            'landing_page' => $page->id,
        ]);
    }

    private function clickoutUrl(LandingPage $page): string
    {
        $page->load('generation');

        return route('public-catalog-landing-pages.clickouts.store', [
            'domain' => $page->generation->publicHost(),
            'purpose' => $page->purposeSlug(),
            'landing_page' => $page->id,
        ]);
    }
}
