using Infrastructure;
using Infrastructure.Extensions;
using OpenAuth.Repository.Domain;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenAuth.App
{
    public partial class WFProcessApp
    {
        #region 任务
        public async Task<IEnumerable<SysUserRelation>> GetUserIdList(string objectId)
        {
            return await client.Queryable<SysUserRelation>().Where(t => t.ObjectId == objectId).ToListAsync();
        }

        public async Task<IEnumerable<SysUser>> GetListByKeyValues(string[] keyValues)
        {
            return await client.Queryable<SysUser>().Where(t => keyValues.Contains(t.Id.ToString())).ToListAsync();
            //return await client.Queryable<SysUser>().Where(t => t.DeleteMark == 0 && keyValues.Contains(t.Id.ToString()));
        }

        public async Task CloseTask(string processId, string token, string taskId)
        {
            var expression = Expressionable.Create<WFTask>()
            .And(t => t.ProcessId == processId && t.Token == token)
            .AndIF(!string.IsNullOrEmpty(taskId), t => t.Id != taskId).ToExpression();




            await client.Updateable<WFTask>().SetColumns(a => new WFTask() { State = 4 })
                .Where(expression)
                .ExecuteCommandAsync();
        }

        public async Task CloseTaskLogCancel(string processId, string taskId)
        {
            await client.Updateable<WFTaskLog>()
                .SetColumns(a => new WFTaskLog { IsCancel = 0 })
                .Where(a => a.ProcessId == processId && a.TaskId == taskId).ExecuteCommandAsync();
        }

        public async Task CloseTaskLogCancel(string taskId)
        {
            await client.Updateable<WFTaskLog>()
                .SetColumns(a => new WFTaskLog { IsCancel = 0 })
                .Where(a => a.TaskId == taskId).ExecuteCommandAsync();
        }

        public async Task<int> GetTaskUserMaxNum(string processId, string unitId)
        {
            StringBuilder strSql = new StringBuilder();
            strSql.Append(" select conut(1) from  wf_task t where ProcessId = @processId AND UnitId =@unitId  AND (Type = 1 OR Type = 3 OR Type = 5) {LEARUN_SASSID}  group by Token order by conut(1) ");

            var pars = client.Ado.GetParameters(new { processId, unitId });
            var data = await client.Ado.GetDataTableAsync(strSql.ToString(), pars);

            if (data.Rows.Count > 0)
            {
                return (data.Rows[0][0]).ToInt();
            }
            else
            {
                return 0;
            }
        }

        public Task<List<WFTask>> GetLastFinishTaskList(string processId, string unitId)
        {
            return client.Queryable<WFTask>().Where(t => t.ProcessId == processId && t.UnitId == unitId && (t.Type == 1||t.Type==7) && t.IsLast == 1 && t.State == 3).ToListAsync();
        }

        public async Task<IEnumerable<WFTask>> GetLastTaskList(string processId, string unitId)
        {
            return await client.Queryable<WFTask>()
                .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.IsLast == 1 && (t.Type == 1 || t.Type == 3 || t.Type == 4 || t.Type == 5||t.Type==7))
                .OrderBy(t => t.Sort)
                .ToListAsync();
        }



        public async Task<WFTask> GetLastNotRejectTask(string processId, string unitId)
        {
            return await client.Queryable<WFTask>()
                .Where(t => t.ProcessId == processId
                && t.UnitId == unitId
                &&(t.IsReject != 1 ||t.IsReject==null)
                && (t.IsRetract!=1 ||t.IsRetract==null)
                && (t.Type == 1 || t.Type == 3 || t.Type == 5||t.Type==7))
                .OrderByDescending(t => t.CreateDate)
                .FirstAsync();
        }

        //public async Task CloseTask(string processId, string token, string taskId)
        //{

        //    await client.Updateable<WFTask>()
        //        .SetColumns(t => new WFTask() { State = 4 })
        //         .Where(t => t.ProcessId == processId && t.Token == token)
        //         .WhereIF(!string.IsNullOrEmpty(taskId), t => t.Id != taskId)
        //         .ExecuteCommandAsync();
        //}

        public async Task CloseTask(string processId, string unitId, int type, string taskId)
        {
            await client.Updateable<WFTask>()
                .SetColumns(t => new WFTask() { State = 4, UpdateTaskId = taskId })
                 .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == type)
                 .ExecuteCommandAsync();
        }

        public async Task Update(string processId, string unitId)
        {
            await client.Updateable<WFTask>()
               .SetColumns(t => new WFTask() { IsLast = 0 })
                .Where(t => t.ProcessId == processId && t.UnitId == unitId)
                .ExecuteCommandAsync();
        }

        public async Task Add(WFTask wfTaskEntity)
        {
            wfTaskEntity.CreateDate = DateTime.Now;
            wfTaskEntity.CreateUserId = _auth.GetUserId();
            wfTaskEntity.CreateUserName = _auth.GetUserName();
            wfTaskEntity.Id= string.IsNullOrEmpty(wfTaskEntity.Id)?Guid.NewGuid().ToString(): wfTaskEntity.Id;
            wfTaskEntity.IsLast = 1;
           var flag= await client.Insertable(wfTaskEntity).ExecuteCommandAsync();
            //if (flag!=0&&wfTaskEntity.TimeoutNotice!=null&&wfTaskEntity.TimeoutInterval!=0)
            //{
            //    DateTime outtime=(DateTime)wfTaskEntity.TimeoutNotice;
            //    DateTime overtime = outtime.AddHours((int)wfTaskEntity.TimeoutInterval);
            //    AddOpenJob(wfTaskEntity, outtime, overtime);
            //}
        }

        public async Task<IEnumerable<WFTask>> GetUnFinishTaskList(string processId)
        {
            return await client.Queryable<WFTask>().Where(t => t.ProcessId == processId && t.State == 1 && (t.Type == 1 || t.Type == 2 || t.Type == 3 || t.Type == 4 || t.Type == 5 || t.Type == 6||t.Type==7)).ToListAsync();
        }

        public async Task<IEnumerable<WFTask>> GetList(string processId, int type, string prevTaskId)
        {
            return await client.Queryable<WFTask>().Where(t => t.ProcessId == processId && t.Type == type && t.PrevTaskId == prevTaskId).ToListAsync();
        }

        public async Task<WFTask> GetTaskEntity(string keyValue)
        {
            return await client.Queryable<WFTask>()
                .Where(a => a.Id == keyValue).FirstAsync();
        }

        public async Task Delete(string processId, string prevTaskId)
        {
            await client.Deleteable<WFTask>().Where(t => t.ProcessId == processId && t.PrevTaskId == prevTaskId).ExecuteCommandAsync();
        }

        public async Task DeleteByFirstId(string id)
        {
            await client.Deleteable<WFTask>().Where(t => t.FirstId == id).ExecuteCommandAsync();
        }

        public async Task OpenTask(string processId, string unitId, int type, string taskId)
        {
            await client.Updateable<WFTask>().SetColumns(a => new WFTask { State = 1, UpdateTaskId = taskId })
                .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == type)
                .ExecuteCommandAsync();
        }
        #endregion

        #region 日志

        public async Task AddLog(WFTaskLog wfTaskLogEntity)
        {
            wfTaskLogEntity.CreateDate = DateTime.Now;
            wfTaskLogEntity.UserId = _auth.GetUserId();
            wfTaskLogEntity.UserName = _auth.GetUserNickName();
            wfTaskLogEntity.Id = Guid.NewGuid().ToString();
            await client.Insertable(wfTaskLogEntity).ExecuteCommandAsync();
        }
        public async Task<IEnumerable<WFTaskLog>> GetLogList(string processId, string unitId)
        {
            return await client.Queryable<WFTaskLog>()
                .Where(t => t.ProcessId == processId && t.UnitId == unitId)
                .OrderByDescending(t => t.CreateDate)
                .ToListAsync();
        }

        public async Task UpdateLog(string processId, string unitId)
        {
            var userId = _auth.GetUserId();

            await this.client.Updateable<WFTaskLog>()
                .SetColumns(t => new WFTaskLog { IsLast = 0 })
                .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.IsLast == 1 && t.UserId == userId)
                .ExecuteCommandAsync();
        }

        public async Task<WFTaskLog> GetLogEntity(string taskId)
        {
            return await client.Queryable<WFTaskLog>().Where(t => t.TaskId == taskId).FirstAsync();
        }

        public async Task DeleteLog(string processId, string taskId)
        {
            await client.Deleteable<WFTaskLog>().Where(t => t.ProcessId == processId && t.TaskId == taskId && t.IsLast == 1).ExecuteCommandAsync();
        }

        public async Task DeleteLogByTaskId(string taskId)
        {
            await client.Deleteable<WFTaskLog>().Where(t => t.TaskId == taskId).ExecuteCommandAsync();
        }

        public async Task Delete(string processId)
        {
            await client.Deleteable<WFTaskLog>().Where(t => t.ProcessId == processId).ExecuteCommandAsync();
        }
        #endregion

        public async Task<SysUser> GetUserInfo(string userId)
        {
            if (userId == "-1")
            {
                return new SysUser
                {
                    Account = Define.SYSTEM_USERNAME,
                    Name = "超级管理员",
                    Id = -1
                };
            }
            else
            {
                return await client.Queryable<SysUser>().FirstAsync(a => a.Id.ToString() == userId);
            }

        }
    }
}
