<?php

declare(strict_types=1);

use App\Models\Artwork;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

uses(RefreshDatabase::class);

it('admin discovery feedback report includes negative feedback and undo metrics', function () {
    $admin = User::factory()->create(['role' => 'admin']);
    $user = User::factory()->create();
    $artwork = Artwork::factory()->create();
    $previousDate = now()->subDay()->toDateString();
    $date = now()->toDateString();

    $recordEvent = function (string $eventDate, string $eventType, array $meta = []) use ($user, $artwork) {
        $algoVersion = (string) ($meta['algo_version'] ?? 'clip-cosine-v2-adaptive');
        unset($meta['algo_version']);

        DB::table('user_discovery_events')->insert([
            'event_id' => (string) Str::uuid(),
            'user_id' => $user->id,
            'artwork_id' => $artwork->id,
            'category_id' => null,
            'event_type' => $eventType,
            'event_version' => 'event-v1',
            'algo_version' => $algoVersion,
            'weight' => 1.0,
            'event_date' => $eventDate,
            'occurred_at' => now(),
            'meta' => json_encode(array_merge([
                'gallery_type' => 'for-you',
                'surface' => 'for-you',
            ], $meta), JSON_THROW_ON_ERROR),
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    };

    $recordEvent($previousDate, 'view');
    $recordEvent($previousDate, 'click');
    $recordEvent($previousDate, 'favorite');
    $recordEvent($previousDate, 'hide_artwork', ['reason' => 'not_relevant']);
    $recordEvent($previousDate, 'dislike_tag', ['tag_slug' => 'abstract']);
    $recordEvent($previousDate, 'view', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1']);
    $recordEvent($previousDate, 'click', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1']);
    $recordEvent($previousDate, 'favorite', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1']);

    $recordEvent($date, 'view');
    $recordEvent($date, 'click');
    $recordEvent($date, 'favorite');
    $recordEvent($date, 'download');
    $recordEvent($date, 'hide_artwork', ['reason' => 'not_relevant']);
    $recordEvent($date, 'unhide_artwork', ['reason' => 'undo']);
    $recordEvent($date, 'view', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1']);
    $recordEvent($date, 'click', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1']);
    $recordEvent($date, 'hide_artwork', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1', 'reason' => 'not_relevant']);
    $recordEvent($date, 'dislike_tag', ['gallery_type' => 'homepage', 'surface' => 'homepage', 'algo_version' => 'clip-cosine-v1', 'tag_slug' => 'portrait']);

    $this->artisan('analytics:aggregate-discovery-feedback', ['--date' => $previousDate])
        ->assertExitCode(0);
    $this->artisan('analytics:aggregate-discovery-feedback', ['--date' => $date])
        ->assertExitCode(0);

    $response = $this->actingAs($admin)
        ->getJson('/api/admin/reports/discovery-feedback?from=' . $previousDate . '&to=' . $date . '&limit=10');

    $response->assertOk();
    $response->assertJsonPath('overview.views', 4);
    $response->assertJsonPath('overview.clicks', 4);
    $response->assertJsonPath('overview.feedback_actions', 4);
    $response->assertJsonPath('overview.hidden_artworks', 3);
    $response->assertJsonPath('overview.disliked_tags', 2);
    $response->assertJsonPath('overview.negative_feedback_actions', 5);
    $response->assertJsonPath('overview.undo_hidden_artworks', 1);
    $response->assertJsonPath('overview.undo_disliked_tags', 0);
    $response->assertJsonPath('overview.undo_actions', 1);
    $response->assertJsonPath('daily_feedback.0.negative_feedback_actions', 2);
    $response->assertJsonPath('daily_feedback.1.negative_feedback_actions', 3);
    $response->assertJsonPath('daily_feedback.1.undo_actions', 1);
    $response->assertJsonPath('trend_summary.latest_day.date', $date);
    $response->assertJsonPath('trend_summary.previous_day.date', $previousDate);
    $response->assertJsonPath('trend_summary.rolling_7d_average.feedback_actions', 2);
    $response->assertJsonPath('trend_summary.rolling_7d_average.negative_feedback_actions', 2.5);
    $response->assertJsonPath('trend_summary.rolling_7d_average.undo_actions', 0.5);
    $response->assertJsonPath('trend_summary.deltas.feedback_actions.label', 'Flat');
    $response->assertJsonPath('trend_summary.deltas.negative_feedback_actions.label', 'Worse +1 vs prev day');
    $response->assertJsonPath('trend_summary.overall_status.level', 'watch');
    $response->assertJsonPath('by_surface.0.surface', 'homepage');
    $response->assertJsonPath('by_surface.0.negative_feedback_actions', 2);
    $response->assertJsonPath('by_surface.0.trend.overall_status.level', 'risk');
    $response->assertJsonPath('by_surface.0.trend.deltas.feedback_actions.label', 'Worse -1 vs prev day');
    $response->assertJsonPath('by_surface.0.trend.deltas.negative_feedback_actions.label', 'Worse +2 vs prev day');
    $response->assertJsonPath('by_surface.1.surface', 'for-you');
    $response->assertJsonPath('by_surface.1.trend.overall_status.level', 'healthy');
    $response->assertJsonPath('by_algo_surface.0.algo_version', 'clip-cosine-v1');
    $response->assertJsonPath('by_algo_surface.0.surface', 'homepage');
    $response->assertJsonPath('by_algo_surface.0.negative_feedback_actions', 2);
    $response->assertJsonPath('by_algo_surface.0.trend.overall_status.level', 'risk');
    $response->assertJsonPath('by_algo_surface.0.trend.deltas.feedback_actions.label', 'Worse -1 vs prev day');
    $response->assertJsonPath('by_algo_surface.0.trend.deltas.negative_feedback_actions.label', 'Worse +2 vs prev day');
    $response->assertJsonPath('by_algo_surface.1.algo_version', 'clip-cosine-v2-adaptive');
    $response->assertJsonPath('top_artworks.0.artwork_id', $artwork->id);
    $response->assertJsonPath('top_artworks.0.negative_feedback_actions', 3);
    $response->assertJsonPath('top_artworks.0.undo_actions', 1);
    $response->assertJsonPath('latest_aggregated_date', $date);
});
