<?php

namespace Tests\Unit;

use App\Http\Controllers\SportsController;
use App\Models\Category;
use App\Services\SkySportsService;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Http\Request;
use Tests\TestCase;
use Mockery;

class SportsControllerTest extends TestCase
{
    use DatabaseMigrations;

    private $skySportsService;
    private $controller;

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

        // Seed test categories
        Category::create([
            'name' => 'Football',
            'slug' => 'football',
            'description' => 'Football news and updates'
        ]);

        Category::create([
            'name' => 'Basketball',
            'slug' => 'basketball',
            'description' => 'Basketball news and updates'
        ]);

        $this->skySportsService = Mockery::mock(SkySportsService::class);
        $this->controller = new SportsController($this->skySportsService);
    }

    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    /**
     * Test index method returns correct view with data
     */
    public function test_index_returns_correct_view_with_data()
    {
        $mockData = [
            [
                'poster' => 'https://example.com/image.jpg',
                'title' => 'Test Sports News',
                'tag' => 'Football',
                'link' => '/football/news/123/456/test',
                'sports' => 'football',
                'type' => 'news',
                'news' => 'test',
                'idsport' => '123',
                'id' => '456',
                'more' => '0'
            ],
            'total_results' => 1
        ];

        $this->skySportsService
            ->shouldReceive('getSportsCategories')
            ->once()
            ->with('sports', '29876', 1)
            ->andReturn($mockData);

        // Categories are already seeded in setUp, no need to mock

        $request = Request::create('/sports', 'GET', ['page' => 1]);

        $response = $this->controller->index($request);

        $this->assertEquals('sports.index', $response->name());
        $this->assertArrayHasKey('sportsData', $response->getData());
        $this->assertArrayHasKey('categories', $response->getData());
        $this->assertArrayHasKey('pagename', $response->getData());
        $this->assertArrayHasKey('page', $response->getData());
        $this->assertArrayHasKey('term', $response->getData());
        $this->assertArrayHasKey('id', $response->getData());

        $data = $response->getData();
        $this->assertEquals('Sports', $data['pagename']);
        $this->assertEquals(1, $data['page']);
        $this->assertEquals('sports', $data['term']);
        $this->assertEquals('29876', $data['id']);
    }

    /**
     * Test category method filters data correctly
     */
    public function test_category_filters_data_by_category()
    {
        $mockData = [
            [
                'poster' => 'https://example.com/basketball.jpg',
                'title' => 'Basketball Championship',
                'tag' => 'Basketball',
                'link' => '/basketball/news/789/012/championship',
                'sports' => 'basketball',
                'type' => 'news',
                'news' => 'championship',
                'idsport' => '789',
                'id' => '012',
                'more' => '0'
            ],
            [
                'poster' => 'https://example.com/football.jpg',
                'title' => 'Football Match',
                'tag' => 'Football',
                'link' => '/football/news/345/678/match',
                'sports' => 'football',
                'type' => 'news',
                'news' => 'match',
                'idsport' => '345',
                'id' => '678',
                'more' => '0'
            ],
            'total_results' => 2
        ];

        $this->skySportsService
            ->shouldReceive('getSportsCategories')
            ->once()
            ->with('basketball', '11095', 1)
            ->andReturn($mockData);

        $request = Request::create('/sports/basketball', 'GET', ['page' => 1]);

        $response = $this->controller->category($request, 'basketball');

        $this->assertEquals('sports.index', $response->name());
        $data = $response->getData();

        // Check that category name is properly formatted
        $this->assertEquals('Basketball', $data['pagename']);
        $this->assertEquals('basketball', $data['term']);
    }

    /**
     * Test search method with valid query
     */
    public function test_search_with_valid_query()
    {
        $mockData = [
            [
                'poster' => 'https://example.com/search.jpg',
                'title' => 'Championship Results',
                'tag' => 'Football',
                'link' => '/football/news/999/888/results',
                'sports' => 'football',
                'type' => 'news',
                'news' => 'results',
                'idsport' => '999',
                'id' => '888',
                'more' => '0'
            ],
            [
                'poster' => 'https://example.com/other.jpg',
                'title' => 'Other News',
                'tag' => 'Basketball',
                'link' => '/basketball/news/777/666/other',
                'sports' => 'basketball',
                'type' => 'news',
                'news' => 'other',
                'idsport' => '777',
                'id' => '666',
                'more' => '0'
            ],
            'total_results' => 2
        ];

        $this->skySportsService
            ->shouldReceive('getSportsCategories')
            ->once()
            ->with('search', '29876', 1)
            ->andReturn($mockData);

        $request = Request::create('/sports/search', 'GET', ['s' => 'championship', 'page' => 1]);

        $response = $this->controller->search($request);

        $this->assertEquals('sports.search', $response->name());
        $data = $response->getData();

        $this->assertEquals('championship', $data['query']);
        $this->assertArrayHasKey('sportsData', $data);

        // Verify filtered results (only items containing 'championship' should remain)
        $this->assertEquals(1, $data['sportsData']['total_results']);
    }

    /**
     * Test search method redirects when query is empty
     */
    public function test_search_redirects_when_query_is_empty()
    {
        $request = Request::create('/sports/search', 'GET', ['s' => '', 'page' => 1]);

        $response = $this->controller->search($request);

        $this->assertEquals(302, $response->getStatusCode());
        $this->assertEquals(route('home'), $response->getTargetUrl());
    }

    /**
     * Test article method with valid parameters
     */
    public function test_article_with_valid_parameters()
    {
        $mockArticleData = [
            'title' => 'Match Preview: Team A vs Team B',
            'date' => '2024-01-15 15:00',
            'images' => 'https://example.com/match-image.jpg',
            'og-images' => 'https://example.com/og-image.jpg',
            'article' => [
                'Team A will face Team B in this crucial match.',
                'Both teams have been preparing extensively for this encounter.',
                'The match promises to be an exciting affair.'
            ]
        ];

        $this->skySportsService
            ->shouldReceive('getSportsArticle')
            ->once()
            ->with('football', 'news', '12345', '67890', 'match-preview', '')
            ->andReturn($mockArticleData);

        $request = Request::create('/sports/football/news/12345/67890/match-preview', 'GET');

        $response = $this->controller->article($request, 'football', 'news', '12345', '67890', 'match-preview');

        $this->assertEquals('sports.article', $response->name());
        $data = $response->getData();

        $this->assertArrayHasKey('articleData', $data);
        $this->assertArrayHasKey('categories', $data);
        $this->assertArrayHasKey('sport', $data);
        $this->assertArrayHasKey('type', $data);

        $this->assertEquals('football', $data['sport']);
        $this->assertEquals('news', $data['type']);
        $this->assertEquals('Match Preview: Team A vs Team B', $data['articleData']['title']);
    }

    /**
     * Test article method redirects when required parameters are missing
     */
    public function test_article_redirects_when_required_parameters_are_missing()
    {
        $request = Request::create('/sports/football/news//67890/match-preview', 'GET');

        $response = $this->controller->article($request, 'football', 'news', '', '67890', 'match-preview');

        $this->assertEquals(302, $response->getStatusCode());
        $this->assertEquals(route('sports.index'), $response->getTargetUrl());
        $this->assertTrue(session()->has('error'));
        $this->assertEquals('Invalid article parameters', session('error'));
    }

    /**
     * Test article method with more parameter
     */
    public function test_article_with_more_parameter()
    {
        $mockArticleData = [
            'title' => 'Tennis Championship Update',
            'date' => '2024-01-15 16:00',
            'images' => 'https://example.com/tennis-image.jpg',
            'og-images' => 'https://example.com/og-tennis.jpg',
            'article' => ['Tennis championship details here.']
        ];

        $this->skySportsService
            ->shouldReceive('getSportsArticle')
            ->once()
            ->with('tennis', 'news', '11111', '22222', 'championship', 'more-sports')
            ->andReturn($mockArticleData);

        $request = Request::create('/sports/tennis/news/11111/22222/championship', 'GET', ['more' => 'more-sports']);

        $response = $this->controller->article($request, 'tennis', 'news', '11111', '22222', 'championship');

        $this->assertEquals('sports.article', $response->name());
        $data = $response->getData();

        $this->assertEquals('tennis', $data['sport']);
        $this->assertEquals('news', $data['type']);
        $this->assertEquals('Tennis Championship Update', $data['articleData']['title']);
    }

    /**
     * Test pagination parameters are passed correctly
     */
    public function test_pagination_parameters_passed_correctly()
    {
        $mockData = [
            [
                'poster' => 'https://example.com/page2.jpg',
                'title' => 'Page 2 News',
                'tag' => 'Football',
                'link' => '/football/news/111/222/page2',
                'sports' => 'football',
                'type' => 'news',
                'news' => 'page2',
                'idsport' => '111',
                'id' => '222',
                'more' => '0'
            ],
            'total_results' => 1
        ];

        $this->skySportsService
            ->shouldReceive('getSportsCategories')
            ->once()
            ->with('sports', '55555', 3)
            ->andReturn($mockData);

        $request = Request::create('/sports', 'GET', ['page' => 3, 'term' => 'custom-term', 'id' => '55555']);

        $response = $this->controller->index($request);

        $data = $response->getData();

        $this->assertEquals(3, $data['page']);
        $this->assertEquals('custom-term', $data['term']);
        $this->assertEquals('55555', $data['id']);
    }
}
