using Hotline.Share.Enums.FlowEngine;
using SqlSugar;
using XF.Domain.Entities;

namespace Hotline.FlowEngine.Workflows;

[SugarIndex("index_step_workflowId", nameof(WorkflowStep.WorkflowId), OrderByType.Desc)]
[SugarIndex("index_step_externalId", nameof(WorkflowStep.ExternalId), OrderByType.Desc)]
public class WorkflowStep : StepBasicEntity
{
   [Navigate(NavigateType.OneToOne, nameof(Id),
        nameof(Workflows.WorkflowTrace.StepId))]
    public WorkflowTrace WorkflowTrace { get; set; }
    
    #region Method

    /// <summary>
    /// 是否处于会签流程中(不包含顶层发起会签节点)
    /// </summary>
    public bool IsInCountersign() => CountersignPosition != ECountersignPosition.None;

    /// <summary>
    /// 会签结束
    /// </summary>
    public void CountersignEnd() => IsStartedCountersignEnd = true;

    public bool IsCenter() => BusinessType is EBusinessType.Seat or EBusinessType.Send;

    public bool IsOrg() => BusinessType is EBusinessType.Department;

    /// <summary>
    /// 重置节点,只清除办理痕迹（退回场景/依据会签开始节点复制会签汇总节点，将上一级节点重置等待重新办理）
    /// </summary>
    public void Reset()
    {
        HandleTime = null;

        AcceptorId = null;
        AcceptorName = null;
        AcceptorOrgId = null;
        AcceptorOrgName = null;
        AcceptorOrgAreaCode = null;
        AcceptorOrgAreaName = null;
        AcceptTime = null;
        HandleMode = null;

        IsStartCountersign = false;

        NextSteps.ForEach(d => d.Selected = false);
    }

    /// <summary>
    /// 重置办理参数
    /// </summary>
    public void ResetParameters()
    {
        NextHandlers = new();
        NextMainHandler = null;
        NextStepCode = null;
        BackToCountersignEnd = false;
        IsSms = false;
        Opinion = null;
        FileJson = new();
        IsStartCountersign = false;
    }

    ///// <summary>
    ///// 发起会签节点发起的会签是否全都办理完成
    ///// </summary>
    ///// <returns></returns>
    //public bool StartedCountersignHasAllHandled()
    //{
    //    //if (!HasStartedCountersign())
    //    //    throw new UserFriendlyException("该节点未发起会签");
    //    //outer属于特殊会签
    //    return CountersignSteps.All(d => d.Completed);
    //}

    /// <summary>
    /// 动态实例化节点是否应该终止
    /// </summary>
    /// <returns></returns>
    public bool DynamicShouldTerminal() => !string.IsNullOrEmpty(NextStepCode) && TerminalDynamicMark == NextStepCode;

    /// <summary>
    /// 是否是顶级会签汇总节点
    /// </summary>
    public bool IsTopCountersignEndStep(string? topCountersignStepId)
    {
        // if (string.IsNullOrEmpty(topCountersignStepId))
        //     throw new UserFriendlyException($"无效顶级会签节点编号，wfId: {WorkflowId}");
        return IsCountersignEndStep 
               && !string.IsNullOrEmpty(topCountersignStepId)
               && CountersignStartStepId == topCountersignStepId;
    }

    //public WorkflowStepHandler?
    //    FindActualHandler(ICollection<string> roles, string? userId = null, string? orgId = null) =>
    //    StepHandlers.FirstOrDefault(d => d.IsHandler(roles, userId, orgId));

    //public WorkflowStepHandler? GetActualHandler() =>
    //    StepHandlers.FirstOrDefault(d => d.IsActualHandler);

    public bool IsCanHandle(string userId, string orgId, string[] roleIds)
    {
        if(Status is EWorkflowStepStatus.Handled) return false;
        return FlowAssignType switch
        {
            EFlowAssignType.Org => !string.IsNullOrEmpty(HandlerOrgId) && HandlerOrgId == orgId,
            EFlowAssignType.User => !string.IsNullOrEmpty(HandlerId) && HandlerId == userId,
            EFlowAssignType.Role => !string.IsNullOrEmpty(RoleId) && roleIds.Contains(RoleId),
            EFlowAssignType.OrgAndRole => !string.IsNullOrEmpty(HandlerOrgId) && HandlerOrgId == orgId && !string.IsNullOrEmpty(RoleId) && roleIds.Contains(RoleId),
			_ => throw new ArgumentOutOfRangeException()
        };
    }
    #endregion
}

/*
获取开始节点下一步待选节点：
  是否属于多次实例化配置（dynamic动态实例化配置：结合办理人动态生成待办节点）
    t:无需检查是否到结束标识，所以按配置的重复实例化策略结合当前操作人生成待办节点，如：生成x级部门办理，下一接口再选具体部门
    f:开始节点配置的下一节点集合

获取开始节点所选下一步节点的具体参数：
  是否属于多次实例化配置
    t:所选x级部门返回对应办理对象集合(具体部门)
    f:按模板配置返回办理对象集合

获取待办节点下一步待选节点：
  是否属于多次实例化配置（无需检查definetion,直接找到当前待办节点获取参数（需要的参数冗余至待办节点上））
    t:检查是否到结束标识（检查当前办理节点的办理对象与结束标识(orglevel:int)是否一致）
      t:返回配置的下一节点(看作单次实例化，当前节点已办完)//definitionId,stepCodes，按配置走
      f:按配置的重复实例化策略结合当前操作人，生成如：{x:X级部门办理},{0:中心办理},最高级最多只能到中心，按动态策略走,动态策略枚举
  是否处于会签中
    t:按会签策略的下一级 + 上一级（isCSEnd会签汇总节点标记）,并对上一级选项打上标记，如：{x:X级部门办理},{0:中心办理},按动态策略走，动态策略枚举
    f:按照definition(按配置走)
  返回当前节点的配置下一步

获取下一步的具体参数：
  检查模式
    按动态策略：依据当前操作人、动态类型枚举 查询对应待选部门
    按配置策略：原有实现方案

start:
  check配置是否允许当前用户发起

next: (nextStepCode/x, userId[]/orgId[],dto.other)
  check该不该当前用户办(handlers，all不需要check)
  办理当前节点
  创建后面节点
    是否动态实例化
      t:检查是否到结束标识(参数orgId==mark?)
        t:(参数时stepcode)按配置创建
        f:(参数是x级部门)按动态实例化策略创建
    是否处于会签中
      t: 是否返回上一级汇总 (isCSEnd)
        t:  1.update上一级的会签完成情况[]
            2.如果会签全完成，创建新的待办汇总节点(IsCountersignSummaryStep = true)?更新发起节点状态？thk
      f: 创建新的下一步节点
 */