using Infrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NetTaste;
using OpenAuth.App;
using OpenAuth.App.Config;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.App.Response;
using OpenAuth.Repository.Domain;
using System.Threading.Tasks;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.BaseApp.WFTask;

namespace OpenAuth.WebApi.Controllers
{
    /// <summary>
    /// 流程实例
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class WFProcessController : ControllerBase
    {
        WFSchemeInfoApp schemeInfoApp;
        WFProcessApp processApp;
        WFTaskApp taskApp;
        IAuth auth;

        public WFProcessController(
            WFSchemeInfoApp schemeInfoApp,
            WFProcessApp processApp,
            WFTaskApp taskApp,
            IAuth auth
            )
        {
            this.schemeInfoApp = schemeInfoApp;
            this.processApp = processApp;
            this.taskApp = taskApp;
            this.auth = auth;
        }

        #region 查询

        #region 流程实例
        /// <summary>
        /// 获取流程信息
        /// workflow/process/{id}
        /// </summary>
        /// <param name="id">任务id</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<WFTaskDto>> Get(string id)
        {
            var res = new WFTaskDto();
            res.Process = await processApp.GetEntity(id);
            res.Scheme = await schemeInfoApp.GetSchemeEntity(res.Process.SchemeId);
            res.Logs = await taskApp.GetLogList(id);
            res.Tasks = await taskApp.GetUnFinishTaskList(id);
            return new Response<WFTaskDto>
            {
                Result = res,
                Message = "success"
            };
        }

        /// <summary>
        /// 获取流程信息 适配 BPMN
        /// workflow/process/{id} 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<BPMNWFTaskDto>> GetBPMN(string id)
        {
            var res = new BPMNWFTaskDto();
            res.FlowViewer = new FlowUnit();
            var process = await processApp.GetEntity(id);
            res.Process = process;
            var scheme = await schemeInfoApp.GetSchemeEntity(process.SchemeId);
            res.Scheme = scheme;
            res.FlowContent = scheme.FlowContent;

            res.Logs = await taskApp.GetLogList(id);

            var unfinishTasks = await taskApp.GetUnFinishTaskList(id);
            res.Tasks = unfinishTasks;
            res.FlowViewer.UnfinishedTaskSet = unfinishTasks.Select(a => a.UnitId).ToList();

            List<string> unfids = new List<string>();
            if (unfinishTasks.Count() > 0)
            {
                unfids = unfinishTasks.Select(r => r.Id).ToList();
            }
            var finishTasks = await taskApp.GetFinishTaskList(id, unfids);
            res.FlowViewer.FinishedTaskSet = finishTasks.Select(a => a.UnitId).ToList();
            return new Response<BPMNWFTaskDto>
            {
                Result = res,
                Message = "success"
            };
        }
        #endregion

        #region 草稿实例
        /// <summary>
        /// 草稿实例
        /// workflow/process/draft/{id}
        /// </summary>
        /// <param name="id">草稿id</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<WFTaskDto>> GetDraft(string id)
        {
            var res = new WFTaskDto();
            res.Process = await processApp.GetEntity(id);
            if(res.Process != null)
            {
                res.Scheme = await schemeInfoApp.GetSchemeEntity(res.Process.SchemeId);
            }
           

            return new Response<WFTaskDto>
            {
                Result = res,
                Message = "success"
            };
        }
        #endregion

        #region 流程实例分页
        /// <summary>
        /// 获取流程列表
        /// workflow/process/page
        /// </summary>
        /// <param name="PageReq">分页参数</param>
        /// <param name="searchParams">查询参数</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<PageInfo<List<WFProcess>>>> LoadPage([FromQuery] PageReq pageReq, [FromQuery] WFProcessSearchDto searchParams)
        {
            var pageInfo = await processApp.GetPageList(pageReq, searchParams);

            return new Response<PageInfo<List<WFProcess>>>
            {
                Result = pageInfo,
                Message = "success"
            };
        }
        #endregion

        #region 我的流程
        /// <summary>
        /// 我的流程分页
        /// workflow/process/mypage
        /// </summary>
        /// <param name="PageReq">分页参数</param>
        /// <param name="searchParams">查询参数</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<PageInfo<List<WFProcess>>>> LoadMyPage([FromQuery] PageReq pageReq, [FromQuery] WFProcessSearchDto searchParams)
        {
            var pageInfo = await processApp.GetMyPageList(pageReq, searchParams, 1);
            return new Response<PageInfo<List<WFProcess>>>
            {
                Result = pageInfo,
                Message = "success"
            };
        }
        #endregion

        #region 我的草稿分页
        /// <summary>
        /// 我的草稿分页
        /// "workflow/process/mydraftpage
        /// </summary>
        /// <param name="PageReq">分页参数</param>
        /// <param name="searchParams">查询参数</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<PageInfo<List<WFProcess>>>> LoadMyDraftPage([FromQuery] PageReq pageReq, [FromQuery] WFProcessSearchDto searchParams)
        {
            var pageInfo = await processApp.GetMyPageList(pageReq, searchParams, 2);
            return new Response<PageInfo<List<WFProcess>>>
            {
                Result = pageInfo,
                Message = "success"
            };
        }
        #endregion

        #region 获取下一节点审核人
        /// <summary>
        /// 获取下一节点审核人
        /// workflow/process/nextusers
        /// </summary>
        /// <param name="code">流程模板编码</param>
        /// <param name="processId">流程进程主键</param>
        /// <param name="nodeId">流程节点Id</param>
        /// <param name="operationCode">流程操作代码</param>
        /// <param name="userId">创建人</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<Dictionary<string, List<WFUserInfo>>>> LoadNextAuditors(string code, string processId, string nodeId, string operationCode, string userId)
        {
            var data = await processApp.GetNextAuditors(code, processId, nodeId, operationCode, userId);
            return new Response<Dictionary<string, List<WFUserInfo>>>
            {
                Result = data
            };
        }
        #endregion

        #endregion

        #region 保存草稿
        /// <summary>
        /// 保存草稿
        /// workflow/process/draft
        /// </summary>
        /// <param name="dto">提交参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> SaveDraft(WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.SaveDraft(dto.ProcessId, dto.SchemeCode, dto.UserId, dto.InstanceInfo, dto.ParentProcessId, dto.ParentNodeId, dto.ParentTaskId, dto.IsChild, dto.Title);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        /// <summary>
        /// 保存草稿
        /// workflow/process/draft
        /// </summary>
        /// <param name="dto">提交参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> SaveDraftWithUser(WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.SaveDraftWithUser(dto.ProcessId, dto.SchemeCode, dto.UserId, dto.InstanceInfo, dto.ParentProcessId, dto.ParentNodeId, dto.ParentTaskId, dto.IsChild, dto.Title);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 删除草稿
        /// <summary>
        /// 删除草稿
        /// workflow/process/draft/{id}
        /// </summary>
        /// <param name="dto">提交参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> DeleteDraft(string id)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.DeleteDraft(id);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 创建流程
        /// <summary>
        /// 创建流程
        /// workflow/process/create
        /// </summary>
        /// <param name="dto">提交参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> Create(WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.Create(dto.ProcessId, dto.SchemeCode, dto.UserId, dto.NextUsers, dto.InstanceInfo, dto.Title);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }
            return result;
        }
        /// <summary>
        /// 创建流程
        /// workflow/process/create
        /// </summary>
        /// <param name="dto">提交参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> CreateWithUser(WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.CreateWithUser(dto.ProcessId, dto.SchemeCode, dto.UserId, dto.NextUsers, dto.InstanceInfo, dto.Title);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }
            return result;
        }
        #endregion

        #region 重新创建流程
        /// <summary>
        /// 重新创建流程
        /// workflow/process/createAgain
        /// </summary>
        /// <param name="dto">提交参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> CreateAgain(WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.CreateAgain(dto.ProcessId, dto.Des);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }
            return result;
        }
        #endregion

        #region 撤销流程
        /// <summary>
        /// 撤销流程（只有在该流程未被处理的情况下）
        /// workflow/process/revoke/{id}
        /// </summary>
        /// <param name="id">流程进程主键</param>
        [HttpPost]
        public async Task<Response<bool>> Revoke(string id)
        {
            var result = new Response<bool>();
            try
            {
                result.Result = await processApp.RevokeFlow(id);
                result.Message = "success";
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;

        }
        #endregion

        #region 作废流程
        /// <summary>
        /// 作废流程
        /// workflow/process/{id}
        /// </summary>
        /// <param name="id">流程进程主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> Delete(string id)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.DeleteProcess(id);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 催办流程
        /// <summary>
        /// 催办流程
        /// workflow/process/urge/{id}
        /// </summary>
        /// <param name="id">流程进程主键</param>
        [HttpPost]
        public async Task<Response<bool>> Urge(string id)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.UrgeFlow(id);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        /// <summary>
        /// 督办流程
        /// </summary>
        /// <param name="id">流程id</param>
        /// <param name="supervise">1 督办 0 取消督办</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> Supervise(string id,int supervise)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.Supervise(id,supervise);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }

        #endregion

        #region 流程审核
        /// <summary>
        /// 流程审核-有问题
        /// workflow/process/audit/{id}
        /// </summary>
        /// <param name="id">任务id</param>
        [HttpPost]
        public async Task<Response<bool>> Audit(string id, WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                await processApp.AuditFlow(id, dto.Code, dto.Name, dto.Des, dto.NextUsers, dto.StampImg, dto.StampPassWord, dto.NextId);
                result.Result = true;
                result.Message = "success";
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 流程撤回
        /// <summary>
        /// 流程撤回
        /// workflow/process/Retract/{id}
        /// </summary>
        /// <param name="id">任务id</param>
        [HttpPost]
        public async Task<Response<bool>> Retract(string id, WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                await processApp.RetractFlow(id, dto.Code, dto.Name, dto.Des, dto.NextUsers, dto.StampImg, dto.StampPassWord, dto.NextId);
                result.Result = true;
                result.Message = "success";
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 流程批量审核
        /// <summary>
        /// 流程批量审核-有问题
        /// workflow/process/audits/{code}
        /// </summary>
        /// <param name="id">任务id</param>
        [HttpPost]
        public async Task<Response<bool>> Audits(string code, List<string> taskList)
        {
            await processApp.AuditFlows(code, taskList);
            return null;
        }
        #endregion

        #region 撤销审核
        /// <summary>
        /// 撤销审核
        /// workflow/process/audit/revoke/{id}
        /// </summary>
        /// <param name="id">流程实例主键</param>
        /// <param name="taskId">流程任务主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> RevokeAudit(string id, string taskId)
        {

            var result = new Response<bool>();
            try
            {
                result = await processApp.RevokeAudit(id, taskId);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 加签
        /// <summary>
        /// 加签
        /// workflow/process/sign/{id}
        /// </summary>
        /// <param name="id">任务id</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> Sign(string id, WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.SignFlow(id, dto.ToUserId, dto.Des);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 加签审核
        /// <summary>
        /// 加签审核
        /// workflow/process/signaudit/{id}
        /// </summary>
        /// <param name="id">任务id</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> SignAudit(string id, WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.SignAudit(id, dto.Code, dto.Name, dto.Des);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 确认阅读
        /// <summary>
        /// 确认阅读
        /// workflow/process/read/{id}
        /// </summary>
        /// <param name="id">流程任务主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> ReadFlow(string id)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.ReadFlow(id);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 转移审核人
        /// <summary>
        /// 转移审核人
        /// workflow/process/transfer/{id}
        /// </summary>
        /// <param name="id">流程任务主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> TransferUser(string id, WFProcessDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.TransferUser(id, dto.ToUserId, dto.Des);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion

        #region 指派流程审核人
        /// <summary>
        /// 指派流程审核人
        /// workflow/process/point/{id}
        /// </summary>
        /// <param name="id">流程任务主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> PointUser(string id, WFProcessPointDto dto)
        {
            var result = new Response<bool>();
            try
            {
                result = await processApp.PointUser(id, dto.List);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.InnerException?.Message ?? ex.Message;
            }

            return result;
        }
        #endregion
    }
}
