using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Data;
using wispro.sp.entity;
using wispro.sp.share;
using System.Linq;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using wispro.sp.entity.workflowDefine;
using Microsoft.EntityFrameworkCore;

namespace wispro.sp.api.Controllers
{
    [Authorize]
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class StaffController : ControllerBase
    {
        private static List<Staff> CacheList = new List<Staff>();
        spDbContext Context;

        public StaffController(spDbContext context)
        {
            Context = context;
        }
        

        public List<Staff> GetAll()
        {
            return Context.Staffs.ToList<Staff>();
        }

        private List<Staff> GetStaffList(dynamic dynamic,UserField userField)
        {
            try
            {
                Staff temUser = null;

                switch (userField.UserConditionType)
                {
                    case UserConditionType.Staff:

                        //UserField user = new UserField();
                        //user.UserConditionType = UserConditionType.UserDepartmentPosition;
                        //user.Department = "120";
                        //user.Positon = "6";

                        //System.Diagnostics.Debug.WriteLine(System.Text.Json.JsonSerializer.Serialize(user));
                        

                        switch (userField.UserType)
                        {
                            case UserType.BindObjectProperty:
                                
                                if (dynamic == null)
                                {
                                    return null;
                                }
                                else
                                {
                                    var retObj = share.Utility.ObjectHelper.GetPropertyValue(userField.UserValue, dynamic);

                                    if (retObj is Staff)
                                    {
                                        return new List<Staff>() { (Staff)retObj };
                                    }
                                    else
                                    {
                                        if (retObj is List<Staff>)
                                        {
                                            return (List<Staff>)retObj;
                                        }
                                    }
                                }
                                break;
                            case UserType.DoActionUser:
                                break;
                            case UserType.LoginUser:
                                temUser = Context.Staffs.FirstOrDefault(s => s.Name == User.Identity.Name);
                                return new List<Staff>() { temUser };
                                break;
                            case UserType.Staff:
                                temUser = Context.Staffs.FirstOrDefault(s => s.Id == int.Parse(userField.UserValue.ToString()));
                                if (temUser != null)
                                {
                                    return new List<Staff>() { temUser };
                                }
                                break;
                        }

                        break;
                    case UserConditionType.Department:
                        var retList = Context.DepartmentPositions.Where(d => d.departmentId == int.Parse(userField.Department)).Select(p => p.Staff).ToList();
                        return retList.Where(s=>s.IsOnJob ).ToList();
                        break;
                    case UserConditionType.Position:
                        var query = Context.Staffs.Where(s=>true);
                        var queryList = from u in query
                                        where ((from dp in Context.DepartmentPositions.Where(d => d.PositionId == int.Parse(userField.Positon)) select dp.StaffId).Contains(u.Id))
                                        select u;
                        return queryList.ToList();
                        break;
                    case UserConditionType.UserDepartment:

                        break;
                    case UserConditionType.UserDepartmentPosition:
                        break;
                    case UserConditionType.DepartmentPosition:
                        var retList1 = Context.DepartmentPositions.Where(d => 
                            d.departmentId == int.Parse(userField.Department) &&
                            d.PositionId  == int.Parse(userField.Positon)
                            )
                            .Select(p => p.Staff).ToList();
                        return retList1;
                        break;

                }

                return new List<Staff>();
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

        public List<Staff> GetReviewers(int itemId, int appealTypeId)
        {

            try
            {
                var item = Context.PerformanceItems
                    .Include(p=>p.Reviewer)
                    .Include(p=>p.ItemStaffs).ThenInclude(p=>p.DoPerson)
                    .Include(p=>p.PreOastaff)
                    .Include(p=>p.Customer)
                    .FirstOrDefault(p => p.Id == itemId);

                var apType = Context.AppealTypes.FirstOrDefault(p => p.Id == appealTypeId);

                UserField user = new UserField();

                if (String.IsNullOrEmpty(apType.ReviewerExpress))
                {
                    return Context.Staffs.ToList();
                }
                else
                {
                    List<UserField> lstUserField = new List<UserField>();
                    
                    if (apType.ReviewerExpress.StartsWith("p."))
                    {
                        UserField userField = new UserField();
                        userField.UserConditionType = UserConditionType.Staff;
                        userField.UserType = UserType.BindObjectProperty;
                        userField.UserValue = apType.ReviewerExpress.Replace("p.", "").Trim();
                        lstUserField.Add(userField);
                    }
                    else
                    {
                        lstUserField = System.Text.Json.JsonSerializer.Deserialize<List<UserField>>(apType.ReviewerExpress);
                        //UserField userField = System.Text.Json.JsonSerializer.Deserialize<UserField>(apType.ReviewerExpress);
                    }

                    List<Staff> retStaffs = new List<Staff>();
                    foreach(UserField uf in lstUserField)
                    {
                        var temStaffs = GetStaffList(item, uf);

                        if(temStaffs != null)
                        {
                            foreach(var staff in temStaffs)
                            {
                                if(retStaffs.FirstOrDefault(s=>s.Id == staff.Id) == null) {
                                    retStaffs.Add(staff);
                                }
                            }
                        }
                    }
                    return retStaffs;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Staff GetUser(int Id)
        {
            return Context.Staffs.FirstOrDefault(p=>p.Id == Id);
        }

        public Staff GetByName(string Name)
        {
            return Context.Staffs.FirstOrDefault(p => p.Name  == Name);
        }
        public ListApiResponse<Staff> Query(int pageIndex,int pageSize)
        {
            ListApiResponse<Staff> ret = new ListApiResponse<Staff>();
            ret.TotalCount = Context.Staffs.Count<Staff>();

            List<Staff> retList = Context.Staffs.Skip<Staff>((pageIndex - 1) * pageSize).Take(pageSize).ToList<Staff>();
            
            ret.Results = retList;

            return ret;
        }

        public ListApiResponse<Staff> QueryInDepartment(int deptId,int pageIndex,int pageSize)
        {
            ListApiResponse<Staff> ret = new ListApiResponse<Staff>();
            var dept = Context.Departments.FirstOrDefault<Department>(d=>d.Id == deptId);
            string strancestors = $"{dept.ancestors},{deptId}";

            if (dept != null)
            {
                var retList = Context.Staffs.Where<Staff>(s => 
                    s.Positions.Where<DepartmentPosition>(dp => dp.department.ancestors.StartsWith(strancestors) || dp.department.Id  == deptId).Count() > 0 );
                ret.TotalCount = retList.Count();
                ret.Results = retList.Skip<Staff>((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            }
            else
            {
                ret.Results = new List<Staff>();
            }

            return ret;
        }

        public ApiSaveResponse UpdateUser(SaveUserObject saveUser)
        {
            ApiSaveResponse ret = new ApiSaveResponse();

            Staff editObject = null;
            if (saveUser.staff.Id == 0)
            {
                editObject = Context.Staffs.FirstOrDefault(p=>p.Name == saveUser.staff.Name);
            }
            else
            {
                editObject = Context.Staffs.FirstOrDefault(p => p.Id  == saveUser.staff.Id);
            }

            if(editObject == null)
            {
                ret.Success = false;
                ret.ErrorMessage = "用户不存在";
            }
            else
            {
                using (var t = Context.Database.BeginTransaction())
                {
                    try
                    {
                        if(saveUser.staff.Account != null && editObject.Account != saveUser.staff.Account)
                            editObject.Account = saveUser.staff.Account;

                        if (saveUser.staff.Department != null && editObject.Department != saveUser.staff.Department)
                            editObject.Department = saveUser.staff.Department;

                        if (saveUser.staff.EntyDate != null && editObject.EntyDate != saveUser.staff.EntyDate)
                            editObject.EntyDate = saveUser.staff.EntyDate;

                        editObject.IsCalPerformsnce = saveUser.staff.IsCalPerformsnce;
                        editObject.IsOnJob = saveUser.staff.IsOnJob;
                        editObject.IsGradeAssess = saveUser.staff.IsGradeAssess;

                        if (saveUser.staff.Mail != null && editObject.Mail != saveUser.staff.Mail)
                            editObject.Mail = saveUser.staff.Mail;

                        if (saveUser.staff.Memo != null && editObject.Memo != saveUser.staff.Memo)
                            editObject.Memo = saveUser.staff.Memo;

                        if (saveUser.staff.Mobile != null && editObject.Mobile != saveUser.staff.Mobile)
                            editObject.Mobile = saveUser.staff.Mobile;

                        if (saveUser.staff.Name != null && editObject.Name != saveUser.staff.Name)
                            editObject.Name = saveUser.staff.Name;

                        if (saveUser.staff.Password != null && saveUser.staff.Id >0)
                            editObject.Password = utility.MD5Utility.GetMD5(saveUser.staff.Password);

                        if (saveUser.staff.Sex != null && editObject.Sex != saveUser.staff.Sex)
                            editObject.Sex = saveUser.staff.Sex;

                        if (saveUser.staff.StaffGradeId != null && editObject.StaffGradeId != saveUser.staff.StaffGradeId)
                            editObject.StaffGradeId = saveUser.staff.StaffGradeId;

                        if (saveUser.staff.Status != null && editObject.Status != saveUser.staff.Status)
                            editObject.Status = saveUser.staff.Status;

                        if (saveUser.staff.Tel != null && editObject.Tel != saveUser.staff.Tel)
                            editObject.Tel = saveUser.staff.Tel;

                        if (saveUser.staff.WorkPlace != null && editObject.WorkPlace != saveUser.staff.WorkPlace)
                            editObject.WorkPlace = saveUser.staff.WorkPlace;

                        if(saveUser.staff.RegularDate != null && editObject.RegularDate != saveUser.staff.RegularDate)
                            editObject.RegularDate = saveUser.staff.RegularDate;

                        Context.SaveChanges();

                        var temDP = Context.DepartmentPositions
                            .Where<DepartmentPosition>(d =>
                                d.departmentId == saveUser.deptId &&
                                d.StaffId == editObject.Id).ToList<DepartmentPosition>();

                        foreach (var depPosition in temDP)
                        {
                            Context.DepartmentPositions.Remove(depPosition);
                        }
                        Context.SaveChanges();

                        DepartmentPosition dp = new DepartmentPosition();
                        dp.departmentId = saveUser.deptId;
                        dp.PositionId = saveUser.positionId;
                        dp.StaffId = editObject.Id;
                        Context.DepartmentPositions.Add(dp);
                        Context.SaveChanges();

                        t.Commit();
                    }
                    catch(Exception ex)
                    {
                        ret.Success = false;
                        ret.ErrorMessage = ex.Message;
                        
                    }
                }

            }
            return ret;

        }
        
        public ApiSaveResponse SaveUser(SaveUserObject saveUser)
        {
            ApiSaveResponse ret = new ApiSaveResponse();
            using (var t = Context.Database.BeginTransaction())
            {
                try
                {

                    Staff staff = saveUser.staff;

                    if (staff.Id == 0)
                    {

                        Staff temStaff = Context.Staffs.Where<Staff>(x => x.Name == staff.Name).FirstOrDefault();

                        if (temStaff != null)
                        {
                            ret.Success = false;
                            ret.ErrorMessage = $"用户【{staff.Name}】已存在！";
                        }
                        else
                        {
                            

                            if(string.IsNullOrEmpty(staff.Account) || string.IsNullOrEmpty(staff.Password))
                            {
                                ret.Success = false;
                                ret.ErrorMessage = $"用户名或密码没有设定";

                                return ret;
                            }
                            else
                            {
                                staff.Password = utility.MD5Utility.GetMD5(staff.Password);
                            }

                            Context.Staffs.Add(staff);
                            Context.SaveChanges();

                            DepartmentPosition dp = new DepartmentPosition();
                            dp.departmentId = saveUser.deptId;
                            dp.PositionId = saveUser.positionId;
                            dp.StaffId = staff.Id;
                            Context.DepartmentPositions.Add(dp);

                            Context.SaveChanges();
                        }
                    }
                    else
                    {
                        Staff editObject = Context.Staffs.Where<Staff>(x => x.Id == staff.Id).FirstOrDefault();

                        if (editObject != null)
                        {
                            //editObject.Account = staff.Account;
                            editObject.Department = staff.Department;
                            editObject.EntyDate = staff.EntyDate;
                            editObject.IsCalPerformsnce = staff.IsCalPerformsnce;
                            editObject.IsOnJob = staff.IsOnJob;
                            editObject.IsGradeAssess = staff.IsGradeAssess;
                            editObject.Mail = staff.Mail;
                            editObject.Memo = staff.Memo;
                            editObject.Mobile = staff.Mobile;
                            editObject.Name = staff.Name;
                            //editObject.Password = utility.MD5Utility.GetMD5(staff.Password); 
                            editObject.Sex = staff.Sex;
                            editObject.StaffGradeId = staff.StaffGradeId;
                            editObject.Status = staff.Status;
                            editObject.Tel = staff.Tel;
                            editObject.WorkPlace = staff.WorkPlace;
                            editObject.RegularDate =staff.RegularDate;
                            Context.SaveChanges();

                            if (saveUser.deptId > 0)
                            {
                                var temDP = Context.DepartmentPositions
                                    .Where<DepartmentPosition>(d =>
                                        d.departmentId == saveUser.deptId &&
                                        d.StaffId == editObject.Id).ToList<DepartmentPosition>();

                                foreach (var depPosition in temDP)
                                {
                                    Context.DepartmentPositions.Remove(depPosition);
                                }
                                Context.SaveChanges();

                                DepartmentPosition dp = new DepartmentPosition();
                                dp.departmentId = saveUser.deptId;
                                dp.PositionId = saveUser.positionId;
                                dp.StaffId = editObject.Id;
                                Context.DepartmentPositions.Add(dp);
                                Context.SaveChanges();
                            }

                        }
                        else
                        {
                            ret.Success = false;
                            ret.ErrorMessage = $"编号为【{staff.Id}】的用户不存在！";
                        }

                    }

                    
                    t.Commit();
                    ret.Success = true;

                }
                catch (Exception ex)
                {
                    t.Rollback();
                    ret.Success = false;
                    ret.ErrorMessage = ex.Message;
                }
            }

            return ret;
        }

        [HttpPost]
        public ApiSaveResponse Save(Staff staff)
        {
            ApiSaveResponse ret = new ApiSaveResponse();
            try
            {
                if (staff.Id == 0)
                {
                    
                    Staff temStaff = Context.Staffs.Where<Staff>(x => x.Name == staff.Name).FirstOrDefault();

                    if (temStaff != null)
                    {
                        if (staff.Account != null && staff.Account != temStaff.Account)
                            temStaff.Account = staff.Account;

                        if (staff.Department != null && staff.Department != temStaff.Department)
                            temStaff.Department = staff.Department;

                        if (staff.EntyDate != null && staff.EntyDate != temStaff.EntyDate)
                            temStaff.EntyDate = staff.EntyDate;

                        if (staff.IsCalPerformsnce != temStaff.IsCalPerformsnce)
                            temStaff.IsCalPerformsnce = staff.IsCalPerformsnce;

                        if (staff.IsGradeAssess != temStaff.IsGradeAssess)
                            temStaff.IsGradeAssess = staff.IsGradeAssess;

                        if (staff.IsOnJob != temStaff.IsOnJob)
                            temStaff.IsOnJob = staff.IsOnJob;

                        if (staff.Mail != null && staff.Mail != temStaff.Mail)
                        {
                            temStaff.Mail = staff.Mail;
                        }

                        if (staff.Memo != null && staff.Memo != temStaff.Memo)
                            temStaff.Memo = staff.Memo;

                        if (staff.Memo != null && staff.Memo != temStaff.Memo)
                            temStaff.Mobile = staff.Mobile;

                        if (staff.Sex != null && staff.Sex != temStaff.Sex)
                            temStaff.Sex = staff.Sex;

                        if (staff.StaffGradeId != null && staff.StaffGradeId != temStaff.StaffGradeId)
                            temStaff.StaffGradeId = staff.StaffGradeId;

                        if (staff.Status != null && staff.Status != temStaff.Status)
                            temStaff.Status = staff.Status;

                        if (staff.Tel != null && staff.Tel != temStaff.Tel)
                            temStaff.Tel = staff.Tel;

                        if (staff.WorkPlace != null && staff.WorkPlace != temStaff.WorkPlace)
                            temStaff.WorkPlace = staff.WorkPlace;

                        if(staff.RegularDate != null && staff.RegularDate != temStaff.RegularDate)
                        {
                            temStaff.RegularDate = staff.RegularDate;
                        }

                        Context.SaveChanges();

                        //ret.Success = false;
                        //ret.ErrorMessage = $"用户【{staff.Name}】已存在！";
                    }
                    else
                    {
                        Context.Staffs.Add(staff);
                    }
                }
                else
                {
                    Staff editObject = Context.Staffs.Where<Staff>(x => x.Id == staff.Id).FirstOrDefault();

                    if (editObject != null)
                    {
                        if (staff.Account != null && staff.Account != editObject.Account)
                            editObject.Account = staff.Account;

                        if (staff.Department != null && staff.Department != editObject.Department)
                            editObject.Department = staff.Department;

                        if (staff.EntyDate != null && staff.EntyDate != editObject.EntyDate)
                            editObject.EntyDate = staff.EntyDate;

                        if (staff.IsCalPerformsnce != editObject.IsCalPerformsnce)
                            editObject.IsCalPerformsnce = staff.IsCalPerformsnce;

                        if (staff.IsGradeAssess != editObject.IsGradeAssess)
                            editObject.IsGradeAssess = staff.IsGradeAssess;

                        if (staff.IsOnJob != editObject.IsOnJob)
                            editObject.IsOnJob = staff.IsOnJob;

                        if (staff.Mail != null && staff.Mail != editObject.Mail)
                        {
                            editObject.Mail = staff.Mail;
                        }

                        if (staff.Memo != null && staff.Memo != editObject.Memo)
                            editObject.Memo = staff.Memo;

                        if (staff.Memo != null && staff.Memo != editObject.Memo)
                            editObject.Mobile = staff.Mobile;

                        if (staff.Sex != null && staff.Sex != editObject.Sex)
                            editObject.Sex = staff.Sex;

                        if (staff.StaffGradeId != null && staff.StaffGradeId != editObject.StaffGradeId)
                            editObject.StaffGradeId = staff.StaffGradeId;

                        if (staff.Status != null && staff.Status != editObject.Status)
                            editObject.Status = staff.Status;

                        if (staff.Tel != null && staff.Tel != editObject.Tel)
                            editObject.Tel = staff.Tel;

                        if (staff.WorkPlace != null && staff.WorkPlace != editObject.WorkPlace)
                            editObject.WorkPlace = staff.WorkPlace;

                        if(staff.RegularDate != null && staff.RegularDate != editObject.RegularDate)
                        {
                            editObject.RegularDate = staff.RegularDate;
                        }
                    }
                    else
                    {
                        ret.Success = false;
                        ret.ErrorMessage = $"编号为【{staff.Id}】的用户不存在！";
                    }
                    
                }

                Context.SaveChanges();

                ret.Success = true;
            }
            catch (Exception ex)
            {
                ret.Success = false;
                ret.ErrorMessage = ex.Message;
            }

            return ret;
        }
    }
}
