<?php

namespace Tests\Unit\Facades;

use App\Enums\LogLevelEnum;
use App\Enums\PlatformEnum;
use App\Facades\LogSaver;
use App\Models\Log;
use App\Models\PlatformChannel;
use App\Models\PlatformInstance;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LogSaverTest extends TestCase
{
    use RefreshDatabase;

    public function test_facade_accessor_returns_correct_service(): void
    {
        $reflection = new \ReflectionClass(LogSaver::class);
        $method = $reflection->getMethod('getFacadeAccessor');
        $method->setAccessible(true);

        $this->assertEquals(\App\Services\Log\LogSaver::class, $method->invoke(null));
    }

    public function test_facade_info_method_works(): void
    {
        $message = 'Facade info test';
        $context = ['facade' => true];

        LogSaver::info($message, null, $context);

        $this->assertDatabaseHas('logs', [
            'level' => LogLevelEnum::INFO,
            'message' => $message,
        ]);

        $log = Log::first();
        $this->assertEquals($context, $log->context);
    }

    public function test_facade_error_method_works(): void
    {
        $message = 'Facade error test';
        $context = ['facade' => true, 'error' => 'test_error'];

        LogSaver::error($message, null, $context);

        $this->assertDatabaseHas('logs', [
            'level' => LogLevelEnum::ERROR,
            'message' => $message,
        ]);

        $log = Log::first();
        $this->assertEquals($context, $log->context);
    }

    public function test_facade_warning_method_works(): void
    {
        $message = 'Facade warning test';
        $context = ['facade' => true, 'warning_type' => 'test'];

        LogSaver::warning($message, null, $context);

        $this->assertDatabaseHas('logs', [
            'level' => LogLevelEnum::WARNING,
            'message' => $message,
        ]);

        $log = Log::first();
        $this->assertEquals($context, $log->context);
    }

    public function test_facade_debug_method_works(): void
    {
        $message = 'Facade debug test';
        $context = ['facade' => true, 'debug_info' => 'test'];

        LogSaver::debug($message, null, $context);

        $this->assertDatabaseHas('logs', [
            'level' => LogLevelEnum::DEBUG,
            'message' => $message,
        ]);

        $log = Log::first();
        $this->assertEquals($context, $log->context);
    }

    public function test_facade_works_with_channel(): void
    {
        $platformInstance = PlatformInstance::factory()->create([
            'platform' => PlatformEnum::LEMMY,
            'url' => 'https://facade.test.com',
        ]);

        $channel = PlatformChannel::factory()->create([
            'name' => 'Facade Test Channel',
            'platform_instance_id' => $platformInstance->id,
        ]);

        $message = 'Facade channel test';
        $context = ['facade_test' => true];

        LogSaver::info($message, $channel, $context);

        $log = Log::first();

        $expectedContext = array_merge($context, [
            'channel_id' => $channel->id,
            'channel_name' => 'Facade Test Channel',
            'platform' => PlatformEnum::LEMMY->value,
            'instance_url' => 'https://facade.test.com',
        ]);

        $this->assertEquals($expectedContext, $log->context);
        $this->assertEquals($message, $log->message);
        $this->assertEquals(LogLevelEnum::INFO, $log->level);
    }

    public function test_facade_static_calls_resolve_to_service_instance(): void
    {
        LogSaver::info('Test message 1');
        LogSaver::error('Test message 2');

        $this->assertDatabaseCount('logs', 2);

        $logs = Log::orderBy('id')->get();
        $this->assertEquals('Test message 1', $logs[0]->message);
        $this->assertEquals('Test message 2', $logs[1]->message);
        $this->assertEquals(LogLevelEnum::INFO, $logs[0]->level);
        $this->assertEquals(LogLevelEnum::ERROR, $logs[1]->level);
    }
}
