using Hotline.FlowEngine.Workflows;
using Hotline.Share.Enums.FlowEngine;
using SqlSugar;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.FlowEngine.Definitions;

public class WorkflowDefinition : CreationEntity
{
    /// <summary>
    /// 模板名称
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 模板编码
    /// </summary>
    public string Code { get; set; }

    /// <summary>
    /// 草稿版本号 == 0
    /// </summary>
    public int Version { get; set; }

    [SugarColumn(IsNullable = true)]
    public string? Description { get; set; }

    [SugarColumn(ColumnDataType = "json", IsJson = true)]
    public List<StepDefine> Steps { get; set; } = new();

    [SugarColumn(ColumnDataType = "text")]
    public string? ExternalData { get; set; }

    public EDefinitionStatus Status { get; set; }

    /// <summary>
    /// 流程类型
    /// </summary>
    public EFlowType FlowType { get; set; }

    /// <summary>
    /// 是否显示主办对象
    /// </summary>
    public bool IsMainHandlerShow { get; set; }

    #region Method

    public StepDefine FindStartStepDefine() =>
        Steps.First(d => d.StepType is EStepType.Start);

    public StepDefine FindEndStepDefine() =>
        Steps.First(d => d.StepType is EStepType.End);

    public StepDefine FindSendStepDefine() =>
        Steps.First(d => d.BusinessType is EBusinessType.Send);

    public List<StepDefine> FindStepDefines(IEnumerable<string> stepCodes) =>
        Steps.Where(d => stepCodes.Contains(d.Code)).ToList();

    public StepDefine? FindStepDefine(string code)
    {
        if (!Steps.Any())
            throw new UserFriendlyException($"流程未配置节点，DefineCode: {Code}", "流程配置错误");
        return Steps.FirstOrDefault(d => d.Code == code);
    }

    public StepDefine? FindStepDefineByTag(Func<StepDefine, bool> filter)
    {
        if (filter is null) return default;
        return Steps.FirstOrDefault(filter);
    }

    #endregion
}