<?php

use App\Models\SopTemplate;
use App\Models\User;
use App\Services\SopTemplateService;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function () {
    $this->user = User::factory()->create();
    $this->actingAs($this->user);
    $this->service = new SopTemplateService();
});

test('可以导出模板为 JSON', function () {
    $template = SopTemplate::factory()->create([
        'name' => '测试模板',
        'version' => '1.0.0',
    ]);

    $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'content' => '内容',
        'sort_order' => 1,
    ]);

    $json = $this->service->exportToJson($template);
    $data = json_decode($json, true);

    expect($data)->toHaveKey('template')
        ->and($data)->toHaveKey('steps')
        ->and($data['template']['name'])->toBe('测试模板')
        ->and($data['steps'])->toHaveCount(1);
});

test('导出的 JSON 包含步骤信息', function () {
    $template = SopTemplate::factory()->create();

    $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'content' => '<p>这是内容</p>',
        'sort_order' => 1,
        'is_required' => true,
    ]);

    $json = $this->service->exportToJson($template);
    $data = json_decode($json, true);

    expect($data['steps'][0])->toHaveKey('step_number')
        ->and($data['steps'][0])->toHaveKey('title')
        ->and($data['steps'][0])->toHaveKey('content')
        ->and($data['steps'][0]['title'])->toBe('第一步');
});

test('可以从 JSON 导入模板', function () {
    $jsonData = [
        'template' => [
            'name' => '导入的模板',
            'description' => '这是描述',
            'category' => '测试分类',
            'version' => '1.0.0',
        ],
        'steps' => [
            [
                'step_number' => 1,
                'title' => '第一步',
                'content' => '内容',
                'sort_order' => 1,
                'is_required' => true,
            ],
        ],
    ];

    $json = json_encode($jsonData);
    $template = $this->service->importFromJson($json);

    expect($template)->toBeInstanceOf(SopTemplate::class)
        ->and($template->name)->toBe('导入的模板')
        ->and($template->status)->toBe('draft')
        ->and($template->steps)->toHaveCount(1);
});

test('导入时会创建步骤', function () {
    $jsonData = [
        'template' => [
            'name' => '测试模板',
            'version' => '1.0.0',
        ],
        'steps' => [
            [
                'step_number' => 1,
                'title' => '第一步',
                'sort_order' => 1,
            ],
            [
                'step_number' => 2,
                'title' => '第二步',
                'sort_order' => 2,
            ],
        ],
    ];

    $json = json_encode($jsonData);
    $template = $this->service->importFromJson($json);

    expect($template->steps)->toHaveCount(2)
        ->and($template->steps->first()->title)->toBe('第一步')
        ->and($template->steps->last()->title)->toBe('第二步');
});

test('导入无效 JSON 会抛出异常', function () {
    $invalidJson = 'invalid json';

    $this->service->importFromJson($invalidJson);
})->throws(\Illuminate\Validation\ValidationException::class);

test('导入缺少必需字段会抛出异常', function () {
    $jsonData = [
        'template' => [
            'name' => '测试模板',
            // 缺少 version
        ],
        'steps' => [],
    ];

    $json = json_encode($jsonData);

    $this->service->importFromJson($json);
})->throws(\Illuminate\Validation\ValidationException::class);

test('可以发布模板', function () {
    $template = SopTemplate::factory()->create([
        'status' => 'draft',
    ]);

    $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'sort_order' => 1,
    ]);

    $this->service->publish($template, '首次发布');

    expect($template->fresh()->status)->toBe('published')
        ->and($template->fresh()->published_at)->not->toBeNull()
        ->and($template->versions)->toHaveCount(1);
});

test('发布时会创建版本快照', function () {
    $template = SopTemplate::factory()->create([
        'status' => 'draft',
        'version' => '1.0.0',
    ]);

    $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'sort_order' => 1,
    ]);

    $this->service->publish($template, '测试发布');

    $version = $template->versions->first();

    expect($version)->not->toBeNull()
        ->and($version->version)->toBe('1.0.0')
        ->and($version->change_log)->toBe('测试发布')
        ->and($version->content_snapshot)->toHaveKey('template')
        ->and($version->content_snapshot)->toHaveKey('steps');
});

test('可以归档模板', function () {
    $template = SopTemplate::factory()->create([
        'status' => 'published',
    ]);

    $this->service->archive($template);

    expect($template->fresh()->status)->toBe('archived');
});

test('可以复制模板', function () {
    $template = SopTemplate::factory()->create([
        'name' => '原始模板',
    ]);

    $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'sort_order' => 1,
    ]);

    $newTemplate = $this->service->duplicate($template, '复制的模板');

    expect($newTemplate->name)->toBe('复制的模板')
        ->and($newTemplate->status)->toBe('draft')
        ->and($newTemplate->steps)->toHaveCount(1)
        ->and($newTemplate->id)->not->toBe($template->id);
});

test('复制模板时会复制所有步骤', function () {
    $template = SopTemplate::factory()->create();

    $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'sort_order' => 1,
    ]);

    $template->steps()->create([
        'step_number' => 2,
        'title' => '第二步',
        'sort_order' => 2,
    ]);

    $newTemplate = $this->service->duplicate($template, '复制的模板');

    expect($newTemplate->steps)->toHaveCount(2)
        ->and($newTemplate->steps->first()->title)->toBe('第一步')
        ->and($newTemplate->steps->last()->title)->toBe('第二步');
});

test('复制模板时会复制交互任务', function () {
    $template = SopTemplate::factory()->create();

    $step = $template->steps()->create([
        'step_number' => 1,
        'title' => '第一步',
        'sort_order' => 1,
    ]);

    $step->interactiveTasks()->create([
        'task_type' => 'confirm',
        'task_config' => ['message' => '确认？'],
        'is_required' => true,
    ]);

    $newTemplate = $this->service->duplicate($template, '复制的模板');
    $newStep = $newTemplate->steps->first();

    expect($newStep->interactiveTasks)->toHaveCount(1)
        ->and($newStep->interactiveTasks->first()->task_type)->toBe('confirm');
});
