<?php

namespace Tests\Feature;

use App\Models\Terminal;
use App\Models\TerminalPrompt;
use App\Models\User;
use App\Services\PromptTemplateService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PromptTemplateTest extends TestCase
{
    use RefreshDatabase;

    protected PromptTemplateService $service;
    protected User $user;
    protected Terminal $terminal;

    protected function setUp(): void
    {
        parent::setUp();
        
        $this->service = app(PromptTemplateService::class);
        
        // 创建测试用户
        $this->user = User::factory()->create([
            'name' => '测试用户',
        ]);
        
        // 创建测试终端
        $this->terminal = Terminal::factory()->create([
            'name' => '测试终端',
            'code' => 'TEST-001',
            'station_id' => 1001,
        ]);
        
        $this->actingAs($this->user);
    }

    /** @test */
    public function it_can_get_all_templates()
    {
        $templates = $this->service->getTemplates();
        
        $this->assertIsArray($templates);
        $this->assertNotEmpty($templates);
        $this->assertArrayHasKey('id', $templates[0]);
        $this->assertArrayHasKey('name', $templates[0]);
        $this->assertArrayHasKey('content', $templates[0]);
    }

    /** @test */
    public function it_can_get_template_by_id()
    {
        $template = $this->service->getTemplate('general_assistant');
        
        $this->assertNotNull($template);
        $this->assertEquals('general_assistant', $template['id']);
        $this->assertArrayHasKey('content', $template);
    }

    /** @test */
    public function it_returns_null_for_invalid_template_id()
    {
        $template = $this->service->getTemplate('non_existent_template');
        
        $this->assertNull($template);
    }

    /** @test */
    public function it_can_apply_template_to_terminal()
    {
        $content = $this->service->applyTemplate($this->terminal, 'general_assistant');
        
        $this->assertIsString($content);
        $this->assertNotEmpty($content);
        $this->assertStringContainsString('{user}', $content);
        $this->assertStringContainsString('{station}', $content);
    }

    /** @test */
    public function it_throws_exception_for_invalid_template()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('模板不存在');
        
        $this->service->applyTemplate($this->terminal, 'invalid_template');
    }

    /** @test */
    public function it_can_replace_variables_in_template()
    {
        $template = '你好，{user}！当前时间是 {time}，你在 {station}。';
        
        $result = $this->service->replaceVariables($template, $this->terminal);
        
        $this->assertStringContainsString('测试用户', $result);
        $this->assertStringContainsString('工作站 1001', $result);
        $this->assertStringNotContainsString('{user}', $result);
        $this->assertStringNotContainsString('{station}', $result);
    }

    /** @test */
    public function it_can_get_variable_values()
    {
        $variables = $this->service->getVariableValues($this->terminal);
        
        $this->assertIsArray($variables);
        $this->assertArrayHasKey('user', $variables);
        $this->assertArrayHasKey('terminal_name', $variables);
        $this->assertArrayHasKey('station', $variables);
        $this->assertArrayHasKey('time', $variables);
        
        $this->assertEquals('测试用户', $variables['user']);
        $this->assertEquals('测试终端', $variables['terminal_name']);
        $this->assertEquals('TEST-001', $variables['terminal_code']);
    }

    /** @test */
    public function it_handles_array_variables_correctly()
    {
        // 创建知识库关联
        $kb1 = \App\Models\KnowledgeBase::factory()->create(['name' => '知识库1']);
        $kb2 = \App\Models\KnowledgeBase::factory()->create(['name' => '知识库2']);
        
        $this->terminal->knowledgeBases()->attach([
            $kb1->id => ['priority' => 1],
            $kb2->id => ['priority' => 2],
        ]);
        
        $template = '可用知识库：{knowledge_bases}';
        $result = $this->service->replaceVariables($template, $this->terminal);
        
        $this->assertStringContainsString('知识库1', $result);
        $this->assertStringContainsString('知识库2', $result);
    }

    /** @test */
    public function it_can_preview_template()
    {
        $template = '你好，{user}！终端：{terminal_name}';
        
        $preview = $this->service->preview($template, $this->terminal);
        
        $this->assertStringContainsString('测试用户', $preview);
        $this->assertStringContainsString('测试终端', $preview);
        $this->assertStringNotContainsString('{user}', $preview);
    }

    /** @test */
    public function it_can_validate_variables()
    {
        $validTemplate = '你好，{user}！时间：{time}';
        $invalidVariables = $this->service->validateVariables($validTemplate);
        
        $this->assertEmpty($invalidVariables);
    }

    /** @test */
    public function it_detects_invalid_variables()
    {
        $invalidTemplate = '你好，{user}！无效变量：{invalid_var}，另一个：{another_invalid}';
        $invalidVariables = $this->service->validateVariables($invalidTemplate);
        
        $this->assertNotEmpty($invalidVariables);
        $this->assertContains('invalid_var', $invalidVariables);
        $this->assertContains('another_invalid', $invalidVariables);
    }

    /** @test */
    public function it_determines_shift_correctly()
    {
        // 使用反射访问protected方法
        $reflection = new \ReflectionClass($this->service);
        $method = $reflection->getMethod('getCurrentShift');
        $method->setAccessible(true);
        
        // 测试早班 (8:00-16:00)
        $morningTime = now()->setTime(10, 0);
        $this->assertEquals('早班', $method->invoke($this->service, $morningTime));
        
        // 测试中班 (16:00-24:00)
        $afternoonTime = now()->setTime(18, 0);
        $this->assertEquals('中班', $method->invoke($this->service, $afternoonTime));
        
        // 测试夜班 (0:00-8:00)
        $nightTime = now()->setTime(2, 0);
        $this->assertEquals('夜班', $method->invoke($this->service, $nightTime));
    }

    /** @test */
    public function terminal_can_save_prompt_template()
    {
        $promptData = [
            'prompt_template' => '这是一个测试提示词模板，包含变量 {user} 和 {station}',
            'variables' => ['user', 'station'],
        ];
        
        $prompt = $this->terminal->prompt()->create($promptData);
        
        $this->assertInstanceOf(TerminalPrompt::class, $prompt);
        $this->assertEquals($promptData['prompt_template'], $prompt->prompt_template);
        $this->assertEquals($promptData['variables'], $prompt->variables);
    }

    /** @test */
    public function terminal_prompt_relationship_works()
    {
        TerminalPrompt::factory()->create([
            'terminal_id' => $this->terminal->id,
            'prompt_template' => '测试模板',
        ]);
        
        $this->terminal->refresh();
        
        $this->assertNotNull($this->terminal->prompt);
        $this->assertEquals('测试模板', $this->terminal->prompt->prompt_template);
    }

    /** @test */
    public function config_files_are_properly_structured()
    {
        // 测试变量配置
        $variables = config('prompt_variables.variables');
        $this->assertIsArray($variables);
        $this->assertNotEmpty($variables);
        
        foreach ($variables as $variable) {
            $this->assertArrayHasKey('name', $variable);
            $this->assertArrayHasKey('label', $variable);
            $this->assertArrayHasKey('description', $variable);
            $this->assertArrayHasKey('example', $variable);
            $this->assertArrayHasKey('type', $variable);
            $this->assertArrayHasKey('category', $variable);
        }
        
        // 测试模板配置
        $templates = config('prompt_templates.templates');
        $this->assertIsArray($templates);
        $this->assertNotEmpty($templates);
        
        foreach ($templates as $template) {
            $this->assertArrayHasKey('id', $template);
            $this->assertArrayHasKey('name', $template);
            $this->assertArrayHasKey('description', $template);
            $this->assertArrayHasKey('category', $template);
            $this->assertArrayHasKey('content', $template);
        }
    }

    /** @test */
    public function all_template_variables_are_valid()
    {
        $templates = config('prompt_templates.templates');
        
        foreach ($templates as $template) {
            $invalidVars = $this->service->validateVariables($template['content']);
            
            $this->assertEmpty(
                $invalidVars,
                "模板 '{$template['name']}' 包含无效变量: " . implode(', ', $invalidVars)
            );
        }
    }
}
