<?php

namespace Tests\Feature;

use App\Models\Category;
use App\Services\SkySportsService;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;

class SportsErrorHandlingTest extends TestCase
{
    use DatabaseMigrations;

    protected function setUp(): void
    {
        parent::setUp();
        
        // Seed test data
        Category::create([
            'name' => 'Football',
            'slug' => 'football',
            'description' => 'Football news and updates'
        ]);
    }

    /**
     * Test service handles network timeouts gracefully
     */
    public function test_service_handles_network_timeouts_gracefully()
    {
        // Mock the service to return fallback data on timeout
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Fallback',
                    'title' => 'Fallback Sports News',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/fallback',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'fallback',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports');

        $response->assertStatus(200);
        $response->assertViewIs('sports.index');
        // Should show mock data when API fails
        $response->assertSee('Fallback Sports News');
    }

    /**
     * Test service handles malformed HTML responses
     */
    public function test_service_handles_malformed_html_responses()
    {
        // Mock the service to handle malformed HTML gracefully
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => '',
                    'title' => 'Malformed HTML Handled',
                    'tag' => '',
                    'link' => '/football/news/123/456/malformed',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'malformed',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports');

        $response->assertStatus(200);
        // Should handle malformed data gracefully
        $response->assertViewIs('sports.index');
        $response->assertSee('Malformed HTML Handled');
    }

    /**
     * Test service handles empty API responses
     */
    public function test_service_handles_empty_api_responses()
    {
        // Mock the service to return empty data
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                'total_results' => 0
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports');

        $response->assertStatus(200);
        $response->assertViewIs('sports.index');
        // Should handle empty data gracefully
    }

    /**
     * Test service handles API rate limiting
     */
    public function test_service_handles_api_rate_limiting()
    {
        // Mock the service to return fallback data on rate limiting
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Rate+Limited',
                    'title' => 'Latest Sports News Update',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/latest-news',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'latest-news',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports');

        $response->assertStatus(200);
        // Should fall back to mock data
        $response->assertViewIs('sports.index');
        $response->assertSee('Latest Sports News Update');
    }

    /**
     * Test service handles invalid URL parameters
     */
    public function test_service_handles_invalid_url_parameters()
    {
        // Mock the service to handle invalid parameters
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Invalid+Params',
                    'title' => 'Invalid Parameters Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/invalid',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'invalid',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports/football');

        $response->assertStatus(200);
        // Should handle invalid parameters without crashing
        $response->assertViewIs('sports.index');
        $response->assertSee('Invalid Parameters Handled');
    }

    /**
     * Test service handles database connection errors
     */
    public function test_service_handles_database_connection_errors()
    {
        // Mock database failure by making Category::all() throw an exception
        $this->mock(\App\Models\Category::class)
            ->shouldReceive('all')
            ->andThrow(new \Exception('Database connection failed'));

        // But still mock the sports service to work
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=DB+Error',
                    'title' => 'Database Error Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/db-error',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'db-error',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports/football');

        // Should still return 200 even with database errors
        $response->assertStatus(200);
    }

    /**
     * Test service handles cache failures
     */
    public function test_service_handles_cache_failures()
    {
        // Mock cache failure
        Cache::shouldReceive('remember')
            ->andThrow(new \Exception('Cache error'));

        // Mock the service to work without cache
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Cache+Error',
                    'title' => 'Cache Error Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/cache-error',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'cache-error',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        $response = $this->get('/sports');

        $response->assertStatus(200);
        // Should still work even if cache fails
        $response->assertViewIs('sports.index');
        $response->assertSee('Cache Error Handled');
    }

    /**
     * Test service handles special characters in parameters
     */
    public function test_service_handles_special_characters_in_parameters()
    {
        // Test with special characters that should be handled properly
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Special+Chars',
                    'title' => 'Special Characters Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/special-chars',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'special-chars',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports/football');

        $response->assertStatus(200);
        // Should handle special characters properly
        $response->assertViewIs('sports.index');
        $response->assertSee('Special Characters Handled');
    }

    /**
     * Test service handles very long URLs
     */
    public function test_service_handles_very_long_urls()
    {
        $longTerm = str_repeat('a', 500); // Very long term

        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Long+URL',
                    'title' => 'Long URL Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/long-url',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'long-url',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports/football');

        $response->assertStatus(200);
        // Should handle long URLs without issues
        $response->assertViewIs('sports.index');
        $response->assertSee('Long URL Handled');
    }

    /**
     * Test service handles concurrent requests
     */
    public function test_service_handles_concurrent_requests()
    {
        // Mock the service for concurrent requests
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Concurrent',
                    'title' => 'Concurrent Request Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/concurrent',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'concurrent',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        // Simulate concurrent requests
        $response1 = $this->get('/sports/football');
        $response2 = $this->get('/sports/basketball');

        $response1->assertStatus(200);
        $response2->assertStatus(200);

        $response1->assertViewIs('sports.index');
        $response2->assertViewIs('sports.index');
    }

    /**
     * Test service handles memory limit scenarios
     */
    public function test_service_handles_memory_limit_scenarios()
    {
        // Mock the service to handle large responses
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=Large+Data',
                    'title' => 'Large Data Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/large-data',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'large-data',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports');

        $response->assertStatus(200);
        // Should handle large responses without memory issues
        $response->assertViewIs('sports.index');
        $response->assertSee('Large Data Handled');
    }

    /**
     * Test service handles SSL certificate errors
     */
    public function test_service_handles_ssl_certificate_errors()
    {
        // Mock the service to handle SSL errors gracefully
        $this->mock(SkySportsService::class)
            ->shouldReceive('getSportsCategories')
            ->andReturn([
                [
                    'poster' => 'https://via.placeholder.com/300x200?text=SSL+Error',
                    'title' => 'SSL Error Handled',
                    'tag' => 'Football',
                    'link' => '/football/news/123/456/ssl-error',
                    'sports' => 'football',
                    'type' => 'news',
                    'news' => 'ssl-error',
                    'idsport' => '123',
                    'id' => '456',
                    'more' => '0'
                ],
                'total_results' => 1
            ]);

        Cache::shouldReceive('remember')
            ->andReturnUsing(function ($key, $ttl, $callback) {
                return $callback();
            });

        $response = $this->get('/sports');

        $response->assertStatus(200);
        // Should fall back to mock data on SSL errors
        $response->assertViewIs('sports.index');
        $response->assertSee('SSL Error Handled');
    }
}
