<?php

namespace Tests\Controller\App;

use App\Enums\ApiToken;
use App\Models\Link;
use App\Models\LinkList;
use App\Models\Tag;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Testing\TestResponse;
use Tests\TestCase;

class FeedControllerTest extends TestCase
{
    use RefreshDatabase;

    private User $user;

    protected function setUp(): void
    {
        parent::setUp();

        $this->user = User::factory()->create();
    }

    public function test_unauthorized_request(): void
    {
        $response = $this->get('links/feed');

        $response->assertRedirect('login');
    }

    public function test_links_feed(): void
    {
        $link = Link::factory()->create();

        $response = $this->getAuthorized('links/feed');

        $response->assertOk()->assertSee($link->url);
    }

    public function test_lists_feed(): void
    {
        $list = LinkList::factory()->create();

        $response = $this->getAuthorized('lists/feed');

        $response->assertOk()->assertSee($list->name);
    }

    public function test_list_link_feed(): void
    {
        $link = LinkList::factory()->create();
        $listLink = Link::factory()->create();
        $unrelatedLink = Link::factory()->create();

        $listLink->lists()->sync([$link->id]);

        $response = $this->getAuthorized('lists/1/feed');

        $response->assertOk()
            ->assertSee($link->name)
            ->assertSee($listLink->url)
            ->assertDontSee($unrelatedLink->url);
    }

    public function test_tags_feed(): void
    {
        $tag = Tag::factory()->create();

        $response = $this->getAuthorized('tags/feed');

        $response->assertOk()->assertSee($tag->name);
    }

    public function test_tag_link_feed(): void
    {
        $tag = Tag::factory()->create();
        $tagLink = Link::factory()->create();
        $unrelatedLink = Link::factory()->create();

        $tagLink->tags()->sync([$tag->id]);

        $response = $this->getAuthorized('tags/1/feed');

        $response->assertOk()
            ->assertSee($tag->name)
            ->assertSee($tagLink->url)
            ->assertDontSee($unrelatedLink->url);
    }

    /**
     * Send an authorized request for the GET method.
     *
     * @param string $uri
     * @param array  $headers
     * @return TestResponse
     */
    public function getAuthorized(string $uri, array $headers = []): TestResponse
    {
        $token = $this->user->createToken('test', [ApiToken::ABILITY_USER_ACCESS])->plainTextToken;
        $headers['Authorization'] = 'Bearer ' . $token;
        return $this->get($uri, $headers);
    }
}
