<?php

namespace Tests\Unit;

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

class SystemSettingServiceTest extends TestCase
{
    use RefreshDatabase;

    protected SystemSettingService $service;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = new SystemSettingService();
    }

    /**
     * 测试getGroupedSettings方法返回按group分组的配置
     */
    public function test_get_grouped_settings_returns_settings_grouped_by_group(): void
    {
        // 创建测试数据
        SystemSetting::create([
            'key' => 'embedding.model_name',
            'value' => ['model' => 'text-embedding-ada-002'],
            'group' => 'embedding',
            'description' => '嵌入模型名称',
        ]);

        SystemSetting::create([
            'key' => 'embedding.api_key',
            'value' => ['key' => 'sk-test123'],
            'group' => 'embedding',
            'description' => 'API密钥',
        ]);

        SystemSetting::create([
            'key' => 'chunking.chunk_size',
            'value' => ['size' => 1000],
            'group' => 'chunking',
            'description' => '分块大小',
        ]);

        // 执行方法
        $result = $this->service->getGroupedSettings();

        // 验证结果结构
        $this->assertIsArray($result);
        $this->assertArrayHasKey('embedding', $result);
        $this->assertArrayHasKey('chunking', $result);

        // 验证embedding分组有2个配置
        $this->assertCount(2, $result['embedding']);

        // 验证chunking分组有1个配置
        $this->assertCount(1, $result['chunking']);

        // 验证配置项包含必要字段
        $embeddingSetting = $result['embedding'][0];
        $this->assertArrayHasKey('id', $embeddingSetting);
        $this->assertArrayHasKey('key', $embeddingSetting);
        $this->assertArrayHasKey('value', $embeddingSetting);
        $this->assertArrayHasKey('description', $embeddingSetting);
        $this->assertArrayHasKey('is_public', $embeddingSetting);
        $this->assertArrayHasKey('updated_at', $embeddingSetting);
    }

    /**
     * 测试空数据库返回空数组
     */
    public function test_get_grouped_settings_returns_empty_array_when_no_settings(): void
    {
        $result = $this->service->getGroupedSettings();

        $this->assertIsArray($result);
        $this->assertEmpty($result);
    }

    /**
     * 测试单个分组的配置
     */
    public function test_get_grouped_settings_with_single_group(): void
    {
        SystemSetting::create([
            'key' => 'system.name',
            'value' => ['name' => '知识库系统'],
            'group' => 'system',
            'description' => '系统名称',
        ]);

        $result = $this->service->getGroupedSettings();

        $this->assertCount(1, $result);
        $this->assertArrayHasKey('system', $result);
        $this->assertCount(1, $result['system']);
    }

    /**
     * 测试updateSettings方法批量更新配置
     */
    public function test_update_settings_updates_multiple_settings(): void
    {
        // 创建初始配置
        SystemSetting::create([
            'key' => 'embedding.model_name',
            'value' => ['model' => 'old-model'],
            'group' => 'embedding',
        ]);

        SystemSetting::create([
            'key' => 'chunking.chunk_size',
            'value' => ['size' => 500],
            'group' => 'chunking',
        ]);

        // 批量更新配置
        $this->service->updateSettings([
            'embedding.model_name' => ['model' => 'new-model'],
            'chunking.chunk_size' => ['size' => 1000],
        ]);

        // 验证配置已更新
        $embeddingSetting = SystemSetting::where('key', 'embedding.model_name')->first();
        $this->assertEquals(['model' => 'new-model'], $embeddingSetting->value);

        $chunkingSetting = SystemSetting::where('key', 'chunking.chunk_size')->first();
        $this->assertEquals(['size' => 1000], $chunkingSetting->value);
    }

    /**
     * 测试updateSettings方法创建不存在的配置
     */
    public function test_update_settings_creates_non_existing_settings(): void
    {
        // 更新不存在的配置
        $this->service->updateSettings([
            'new.setting' => ['value' => 'test'],
        ]);

        // 验证配置已创建
        $setting = SystemSetting::where('key', 'new.setting')->first();
        $this->assertNotNull($setting);
        $this->assertEquals(['value' => 'test'], $setting->value);
        $this->assertEquals('general', $setting->group); // 默认分组
    }

    /**
     * 测试updateSettings方法处理空数组
     */
    public function test_update_settings_handles_empty_array(): void
    {
        // 创建初始配置
        SystemSetting::create([
            'key' => 'test.setting',
            'value' => ['value' => 'original'],
            'group' => 'test',
        ]);

        // 更新空数组
        $this->service->updateSettings([]);

        // 验证原配置未改变
        $setting = SystemSetting::where('key', 'test.setting')->first();
        $this->assertEquals(['value' => 'original'], $setting->value);
    }

    /**
     * 测试updateSettings方法更新单个配置
     */
    public function test_update_settings_updates_single_setting(): void
    {
        // 创建初始配置
        SystemSetting::create([
            'key' => 'system.timeout',
            'value' => ['seconds' => 30],
            'group' => 'system',
        ]);

        // 更新单个配置
        $this->service->updateSettings([
            'system.timeout' => ['seconds' => 60],
        ]);

        // 验证配置已更新
        $setting = SystemSetting::where('key', 'system.timeout')->first();
        $this->assertEquals(['seconds' => 60], $setting->value);
    }
}
