<?php

namespace Tests\Unit;

use App\Models\SystemSetting;
use App\Services\SystemSettingService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;

/**
 * 系统设置服务缓存功能测试
 */
class SystemSettingServiceCacheTest extends TestCase
{
    use RefreshDatabase;

    private SystemSettingService $service;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = new SystemSettingService();
        Cache::flush(); // 清空缓存
    }

    /**
     * 测试getGroupedSettings方法使用缓存
     */
    public function test_get_grouped_settings_uses_cache(): void
    {
        // 创建测试数据
        SystemSetting::factory()->create([
            'key' => 'test_key',
            'value' => ['test' => 'value'],
            'group' => 'test_group',
        ]);

        // 第一次调用 - 应该从数据库读取并缓存
        $result1 = $this->service->getGroupedSettings();
        
        // 验证缓存已创建
        $this->assertTrue(Cache::has('system_settings_grouped'));

        // 修改数据库数据（不清除缓存）
        SystemSetting::where('key', 'test_key')->update([
            'value' => ['test' => 'modified'],
        ]);

        // 第二次调用 - 应该从缓存读取，不反映数据库变更
        $result2 = $this->service->getGroupedSettings();
        
        // 验证返回的是缓存数据（未修改的）
        $this->assertEquals($result1, $result2);
        $this->assertEquals('value', $result2['test_group'][0]['value']['test']);
    }

    /**
     * 测试updateSettings方法清除缓存
     */
    public function test_update_settings_clears_cache(): void
    {
        // 创建测试数据
        SystemSetting::factory()->create([
            'key' => 'test_key',
            'value' => ['test' => 'value'],
            'group' => 'test_group',
        ]);

        // 第一次调用以创建缓存
        $this->service->getGroupedSettings();
        $this->assertTrue(Cache::has('system_settings_grouped'));

        // 更新设置
        $this->service->updateSettings([
            'test_key' => ['test' => 'updated'],
        ]);

        // 验证缓存已被清除
        $this->assertFalse(Cache::has('system_settings_grouped'));

        // 再次获取设置，应该从数据库读取新数据
        $result = $this->service->getGroupedSettings();
        
        // 注意：updateSettings 使用 SystemSetting::set，它会将 group 设置为 'general'
        // 所以更新后的数据会在 'general' 组中
        $this->assertArrayHasKey('general', $result);
        $this->assertEquals('updated', $result['general'][0]['value']['test']);
    }

    /**
     * 测试clearCache方法
     */
    public function test_clear_cache_method(): void
    {
        // 创建测试数据并生成缓存
        SystemSetting::factory()->create([
            'key' => 'test_key',
            'value' => ['test' => 'value'],
            'group' => 'test_group',
        ]);

        $this->service->getGroupedSettings();
        $this->assertTrue(Cache::has('system_settings_grouped'));

        // 调用clearCache方法
        $this->service->clearCache();

        // 验证缓存已被清除
        $this->assertFalse(Cache::has('system_settings_grouped'));
    }

    /**
     * 测试缓存在多次调用时的性能优势
     */
    public function test_cache_improves_performance(): void
    {
        // 创建多个测试数据
        SystemSetting::factory()->count(50)->create();

        // 第一次调用（从数据库读取）
        $start1 = microtime(true);
        $this->service->getGroupedSettings();
        $time1 = microtime(true) - $start1;

        // 第二次调用（从缓存读取）
        $start2 = microtime(true);
        $this->service->getGroupedSettings();
        $time2 = microtime(true) - $start2;

        // 缓存读取应该更快（至少快50%）
        $this->assertLessThan($time1 * 0.5, $time2);
    }
}
