<?php

namespace Tests\Feature;

use App\Agent\Workspace;
use App\Models\Campaign;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Laravel\Ai\Models\Conversation;
use Tests\TestCase;

/**
 * A click in the panel says which campaign it means.
 *
 * Two changes that were each correct alone produced this between them. The
 * panel became clickable, every step and row carrying a sentence about "this
 * campaign". Separately the panel became a view: a tab click changes what is
 * on screen without moving what the chat is working on, which is the whole
 * point of the note that says so.
 *
 * Together, "this campaign" is written while looking at one campaign and read
 * by an agent holding another. The step click also submitted on its own, so
 * one click on the wrong tab silently edited the other campaign.
 *
 * Both halves are asserted here: the sentence names its campaign, and it is
 * the one being looked at rather than the one in focus.
 */
class PanelClicksNameTheirCampaignTest extends TestCase
{
    use RefreshDatabase;

    /** The id is a uuid the table does not generate, so it is written directly. */
    private function conversationFor(User $user): Conversation
    {
        $id = (string) Str::uuid();

        DB::table('agent_conversations')->insert([
            'id' => $id,
            'participant_type' => $user->getMorphClass(),
            'participant_id' => $user->getKey(),
            'title' => 'Two platforms',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return Conversation::findOrFail($id);
    }

    /** @return array{0: User, 1: Conversation, 2: Campaign, 3: Campaign} */
    private function twoCampaigns(): array
    {
        $user = User::factory()->create();
        $conversation = $this->conversationFor($user);

        $workspace = app(Workspace::class);
        $workspace->bindTo($conversation->id);
        $workspace->ownedBy($user);

        $meta = Campaign::create([
            'user_id' => $user->id, 'name' => 'Winter Sale Meta', 'platform' => 'meta', 'status' => 'draft',
        ]);
        $google = Campaign::create([
            'user_id' => $user->id, 'name' => 'Winter Sale Google', 'platform' => 'google', 'status' => 'draft',
        ]);

        // Both belong to the conversation; the second one created is in focus,
        // which is what makes looking at the first one the interesting case.
        $workspace->produced($meta);
        $workspace->produced($google);

        return [$user, $conversation, $meta, $google];
    }

    private function viewing(User $user, Conversation $conversation, Campaign $campaign): string
    {
        return (string) $this->actingAs($user)->post(route('chat.view'), [
            'conversation' => $conversation->id,
            'campaign' => (string) $campaign->id,
        ])->assertOk()->json('panelHtml');
    }

    /** The defect: a click that does not say which campaign it is about. */
    public function test_no_click_target_says_this_campaign(): void
    {
        [$user, $conversation, $meta] = $this->twoCampaigns();

        $html = $this->viewing($user, $conversation, $meta);

        $this->assertStringNotContainsString(
            'for this campaign',
            $html,
            'A click sends a sentence the agent resolves against focus, not against the panel on screen.',
        );
    }

    public function test_a_step_click_names_the_campaign_being_looked_at(): void
    {
        [$user, $conversation, $meta, $google] = $this->twoCampaigns();

        $html = $this->viewing($user, $conversation, $meta);

        $this->assertStringContainsString('data-step-prompt', $html, 'The steps should still be clickable.');
        $this->assertStringContainsString('Winter Sale Meta', $html);
        $this->assertStringNotContainsString(
            'data-step-prompt="Help me configure the budget for Winter Sale Google"',
            $html,
            'The panel named the focused campaign rather than the one on screen.',
        );

        unset($google);
    }

    public function test_a_row_click_names_the_campaign_being_looked_at(): void
    {
        [$user, $conversation, $meta] = $this->twoCampaigns();

        $html = $this->viewing($user, $conversation, $meta);

        $this->assertMatchesRegularExpression(
            '/data-row-prompt="I want to update the [^"]+ for Winter Sale Meta\."/',
            $html,
        );
    }

    /**
     * And the warning is still there, because naming the campaign tells you
     * what a click will do, not what the next thing you type will do.
     */
    public function test_the_working_on_warning_still_appears(): void
    {
        [$user, $conversation, $meta] = $this->twoCampaigns();

        $this->assertStringContainsString(
            'Winter Sale Google',
            $this->viewing($user, $conversation, $meta),
            'Looking at one campaign while the chat works on another should still say so.',
        );
    }
}
