using System.Text.Json;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Workflow.Domain.Entities;
using Workflow.Domain.Enums;
using Workflow.Domain.Exceptions;
using Workflow.Infrastructure.Persistence;

namespace Workflow.Application.Form.FormData.Commands;

public record SubmitFormDataCommand(
    Guid FormDefinitionId,
    Guid InstanceId,
    string DataJson
) : IRequest<Guid>;

public class SubmitFormDataCommandHandler(WorkflowDbContext db)
    : IRequestHandler<SubmitFormDataCommand, Guid>
{
    public async Task<Guid> Handle(SubmitFormDataCommand request, CancellationToken cancellationToken)
    {
        // 查询表单定义及其字段
        var formDefinition = await db.FormDefinitions
            .Include(f => f.Fields)
            .FirstOrDefaultAsync(f => f.Id == request.FormDefinitionId, cancellationToken)
            ?? throw new BusinessException($"表单定义 {request.FormDefinitionId} 不存在");

        // 解析提交的数据
        var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
            request.DataJson,
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true })
            ?? new Dictionary<string, JsonElement>();

        // 验证必填字段
        foreach (var field in formDefinition.Fields.Where(f => f.Required))
        {
            if (!data.ContainsKey(field.FieldKey))
            {
                throw new BusinessException($"必填字段 {field.FieldKey} 缺失");
            }
        }

        // 验证字段类型
        foreach (var field in formDefinition.Fields)
        {
            if (!data.TryGetValue(field.FieldKey, out var value))
            {
                continue;
            }

            if (field.FieldType == FieldType.Number)
            {
                if (value.ValueKind == JsonValueKind.String)
                {
                    var str = value.GetString();
                    if (!double.TryParse(str, out _))
                    {
                        throw new BusinessException($"字段 {field.FieldKey} 类型不匹配，期望数字");
                    }
                }
                else if (value.ValueKind != JsonValueKind.Number)
                {
                    throw new BusinessException($"字段 {field.FieldKey} 类型不匹配，期望数字");
                }
            }
        }

        var formData = new Domain.Entities.FormData
        {
            Id = Guid.NewGuid(),
            FormDefinitionId = request.FormDefinitionId,
            InstanceId = request.InstanceId,
            DataJson = request.DataJson,
        };

        db.FormData.Add(formData);
        await db.SaveChangesAsync(cancellationToken);

        return formData.Id;
    }
}
