using Edu.Common.API;
using Edu.Common.Enum.User;
using Edu.Common.Plugin;
using Edu.Model.CacheModel;
using Edu.Model.Entity.User;
using Edu.Model.Public;
using Edu.Model.ViewModel.User;
using Edu.Repository.User;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VT.FW.DB;

namespace Edu.Module.User
{
    /// <summary>
    /// 考勤处理类
    /// </summary>
    public class AttendanceModule
    {
        private Rb_attendanceRepository respository = new Rb_attendanceRepository();
        private Rb_attendance_wayRepository AWrespository = new Rb_attendance_wayRepository();
        private Rb_workdaysetingRepository WDrespository = new Rb_workdaysetingRepository();
        private Rb_technicaldatesRepository TDrespository = new Rb_technicaldatesRepository();
        private Rb_Workflow_AskforleaveRepository AskforleaveRepository = new Rb_Workflow_AskforleaveRepository();
        private Rb_technicaldatesRepository technicaldatesRepository = new Rb_technicaldatesRepository();
        private Rb_workdaysetingRepository workdaysetingRepository = new Rb_workdaysetingRepository();
        private Rb_attendance_recordRepository RecordRepository = new Rb_attendance_recordRepository();
        private Rb_dictvalueRepository dictvalueRepository = new Rb_dictvalueRepository();
        
        /// <summary>
        /// 部门
        /// </summary>
        private readonly RB_DepartmentRepository departmentRepository = new RB_DepartmentRepository();
        /// <summary>
        /// 账号
        /// </summary>
        private readonly RB_AccountRepository accountRepository = new RB_AccountRepository();


        /// <summary>
        /// 获取公司所有数据
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="dmodel"></param>
        /// <param name="count"></param>
        /// <param name="groupId"></param>
        /// <returns></returns>
        public List<RB_Attendance_Extend> GetPageList(int pageIndex, int pageSize, RB_Attendance_Extend dmodel, out long count, int groupId)
        {
            var pageList = respository.GetPageListNew(pageIndex, pageSize, dmodel, out count, groupId);
            return pageList;
        }

        /// <summary>
        /// 根据id获取数据
        /// </summary>
        /// <param name="attendanceId"></param>
        /// <returns></returns>
        public RB_Attendance_Extend Get(int attendanceId)
        {
            //获取 需要同时获取  特殊日期表  工作日表  考勤方式表数据
            var amodel = respository.GetEntity<RB_Attendance_Extend>(attendanceId);

            var AWmodel = respository.GetAWList(attendanceId, 1);
            var AWWifimodel = respository.GetAWList(attendanceId, 2);
            var TDmodel = respository.GetTDList(attendanceId, 1);

            //2019-09-23 Add by :W 某一个部门或者人可以打卡，查询所属部门或者人
            if (TDmodel != null && TDmodel.Any())
            {
                //查询部门信息
                string deptIds = string.Join(",", TDmodel.Where(x => x.RB_Department_Id > 0).Select(x => x.RB_Department_Id));
                if (!string.IsNullOrWhiteSpace(deptIds))
                {
                    var deptList = departmentRepository.GetDepartmentListRepository(new RB_Department_ViewModel() { QDeptIds = deptIds });
                    TDmodel.Where(x => x.RB_Department_Id > 0).ToList().ForEach(x => x.DepartmentName = deptList.FirstOrDefault(y => y.DeptId == x.RB_Department_Id)?.DeptName);
                }
                string employeeIds = string.Join(",", TDmodel.Where(x => x.EmployeeId > 0).Select(x => x.EmployeeId));
                if (!string.IsNullOrWhiteSpace(employeeIds))
                {
                    var employeeList = accountRepository.GetEmployeeListRepository(new Employee_ViewModel() { QIds = employeeIds });
                    TDmodel.Where(x => x.EmployeeId > 0).ToList().ForEach(x => x.EmployeeName = employeeList.FirstOrDefault(y => y.Id == x.EmployeeId)?.EmployeeName);
                }
            }

            var NotTDmodel = respository.GetTDList(attendanceId, 2);
            var WDmodel = respository.GetWDList(attendanceId);
            string[] workDayList = new string[] { "周一", "周二", "周三", "周四", "周五", "周六", "周日" };
            List<RB_WorkdaySeting_Extend> wdsList = new List<RB_WorkdaySeting_Extend>();
            if (WDmodel.Count != 8)
            {//数据库里没得一周的数据
                foreach (string wdstr in workDayList)
                {
                    var wdList = WDmodel.Where(x => x.Workday == wdstr).ToList();
                    RB_WorkdaySeting_Extend wdsmodel = new RB_WorkdaySeting_Extend();
                    if (wdList.Count <= 0)
                    {
                        wdsmodel = new RB_WorkdaySeting_Extend()
                        {
                            AttendanceId = attendanceId,
                            Workday = wdstr,
                            BeOnDutyTime = "",
                            OffDutyTime = "",
                            IsCheck = 0
                        };
                    }
                    else
                    {
                        var model = wdList[0];
                        wdsmodel = new RB_WorkdaySeting_Extend()
                        {
                            AttendanceId = model.AttendanceId,
                            Workday = model.Workday,
                            BeOnDutyTime = model.BeOnDutyTime,
                            OffDutyTime = model.OffDutyTime,
                            IsCheck = 1
                        };
                    }
                    wdsList.Add(wdsmodel);
                }
            }
            if (amodel != null)
            {
                amodel.WdList = wdsList;
                amodel.TdList = TDmodel;
                amodel.AwList = AWmodel;
                amodel.NottdList = NotTDmodel;
                amodel.AwWifiList = AWWifimodel;
            }
            return amodel;
        }

        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="aid"></param>
        /// <param name="groupId"></param>
        /// <param name="BranchId"></param>
        /// <returns></returns>
        public bool ValidateName(int aid, int groupId, int BranchId)
        {
            return respository.ValidateName(aid, groupId, BranchId);
        }

        /// <summary>
        /// 新增修改
        /// </summary>
        /// <param name="attendanceId"></param>
        /// <param name="Status"></param>
        /// <param name="BranchId"></param>
        /// <param name="WorkDayList"></param>
        /// <param name="ClockDateList"></param>
        /// <param name="NotClockDateList"></param>
        /// <param name="AddressWayList"></param>
        /// <param name="WifiWayList"></param>
        /// <param name="eid"></param>
        /// <param name="groupId"></param>
        /// <returns></returns>
        public bool Set(int attendanceId, int Status, int BranchId, List<RB_WorkdaySeting_Extend> WorkDayList, List<RB_Technicaldates_Extend> ClockDateList, List<RB_Technicaldates_Extend> NotClockDateList, List<RB_Attendance_Way_Extend> AddressWayList, List<RB_Attendance_Way_Extend> WifiWayList, int eid, int groupId)
        {
            var trans = respository.DbTransaction;
            try
            {
                if (attendanceId > 0)//修改
                {
                    #region 修改
                    RB_Attendance amodel = respository.GetEntity(attendanceId);
                    amodel.Status = Status;
                    amodel.UpdateBy = eid;
                    amodel.UpdateTime = DateTime.Now;
                    bool flag = respository.Update(amodel, trans);
                    if (flag)
                    {
                        //删除全部的工作日数据
                        respository.DelAllList(attendanceId, trans);
                        foreach (var item in WorkDayList)
                        {//获取单条工作日数据
                            RB_WorkdaySeting_Extend wmodel = new RB_WorkdaySeting_Extend
                            {
                                AttendanceId = attendanceId,
                                Workday = item.Workday,
                                BeOnDutyTime = item.BeOnDutyTime,
                                OffDutyTime = item.OffDutyTime
                            };
                            WDrespository.Insert(wmodel, trans);
                        }
                        foreach (var item in ClockDateList)
                        {//获取特殊日期 需打卡
                            RB_Technicaldates tdmodel = new RB_Technicaldates
                            {
                                AttendanceId = attendanceId,
                                Date = Convert.ToDateTime(item.Date),
                                BeOnDutyTime = item.BeOnDutyTime,
                                OffDutyTime = item.OffDutyTime,
                                Type = 1,
                                RB_Department_Id = item.RB_Department_Id,//2019-09-23 Add By:W  可设置某一个部门或者人打卡
                                EmployeeId = item.EmployeeId //2019-09-23 Add By:W
                            };
                            TDrespository.Insert(tdmodel, trans);
                        }
                        foreach (var item in NotClockDateList)
                        {//获取特殊日期 无需打卡
                            RB_Technicaldates tdmodel = new RB_Technicaldates
                            {
                                AttendanceId = attendanceId,
                                Date = Convert.ToDateTime(item.Date),
                                Type = 2,
                                RB_Department_Id = item.RB_Department_Id,//2019-09-23 Add By:W
                                EmployeeId = item.EmployeeId//2019-09-23 Add By:W
                            };
                            TDrespository.Insert(tdmodel, trans);
                        }
                        foreach (var item in AddressWayList)
                        {//1.根据办公地点考勤（可添加多个考勤地点）
                            RB_Attendance_Way wdmodel = new RB_Attendance_Way
                            {
                                Attendance_Id = attendanceId,
                                Type = 1,
                                Name = item.Name,
                                Address = item.Address,
                                TargetAddress = item.TargetAddress,
                                Scope = item.Scope ?? 0
                            };
                            AWrespository.Insert(wdmodel, trans);
                        }
                        foreach (var item in WifiWayList)
                        {//2.根据WiFi考勤
                            RB_Attendance_Way wdmodel = new RB_Attendance_Way
                            {
                                Attendance_Id = attendanceId,
                                Type = 2,
                                Name = item.Name,
                                TargetAddress = item.TargetAddress
                            };
                            AWrespository.Insert(wdmodel, trans);
                        }
                    }
                    #endregion
                }
                else
                {//新增
                    #region 新增
                    RB_Attendance_Extend amodel = new RB_Attendance_Extend
                    {
                        RB_BranchId = BranchId,
                        RB_GroupId = groupId,
                        Status = Status,
                        CreateBy = eid,
                        CreateTime = DateTime.Now,
                        UpdateBy = eid,
                        UpdateTime = DateTime.Now
                    };
                    int aid = respository.Insert(amodel, trans);
                    if (aid > 0)
                    {
                        foreach (var item in WorkDayList)
                        {//获取单条工作日数据
                            RB_WorkdaySeting wmodel = new RB_WorkdaySeting
                            {
                                AttendanceId = aid,
                                Workday = item.Workday,
                                BeOnDutyTime = item.BeOnDutyTime,
                                OffDutyTime = item.OffDutyTime
                            };
                            WDrespository.Insert(wmodel, trans);
                        }
                        foreach (var item in ClockDateList)
                        {//获取特殊日期 需打卡
                            RB_Technicaldates tdmodel = new RB_Technicaldates
                            {
                                AttendanceId = aid,
                                Date = Convert.ToDateTime(item.Date),
                                BeOnDutyTime = item.BeOnDutyTime,
                                OffDutyTime = item.OffDutyTime,
                                Type = 1,
                                RB_Department_Id = item.RB_Department_Id,//2019-09-23 Add By:W  可设置某一个部门或者人打卡
                                EmployeeId = item.EmployeeId //2019-09-23 Add By:W
                            };
                            TDrespository.Insert(tdmodel, trans);
                        }
                        foreach (var item in NotClockDateList)
                        {//获取特殊日期 无需打卡
                            RB_Technicaldates tdmodel = new RB_Technicaldates
                            {
                                AttendanceId = aid,
                                Date = Convert.ToDateTime(item.Date),
                                Type = 2,
                                RB_Department_Id = item.RB_Department_Id,//2019-09-23 Add By:W  可设置某一个部门或者人打卡
                                EmployeeId = item.EmployeeId //2019-09-23 Add By:W
                            };
                            TDrespository.Insert(tdmodel, trans);
                        }
                        foreach (var item in AddressWayList)
                        {//1.根据办公地点考勤（可添加多个考勤地点）
                            RB_Attendance_Way wdmodel = new RB_Attendance_Way
                            {
                                Attendance_Id = aid,
                                Type = 1,
                                Name = item.Name,
                                Address = item.Address,
                                TargetAddress = item.TargetAddress,
                                Scope = item.Scope ?? 0
                            };
                            AWrespository.Insert(wdmodel, trans);
                        }
                        foreach (var item in WifiWayList)
                        {//2.根据WiFi考勤
                            RB_Attendance_Way wdmodel = new RB_Attendance_Way
                            {
                                Attendance_Id = aid,
                                Type = 2,
                                Name = item.Name,
                                TargetAddress = item.TargetAddress
                            };
                            AWrespository.Insert(wdmodel, trans);
                        }
                    }
                    #endregion
                }
                respository.DBSession.Commit();
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "AttendanceModule_Set");
                respository.DBSession.Rollback("AttendanceModule_Set");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 获取每日打卡记录
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="bid"></param>
        /// <param name="DepartmentId"></param>
        /// <param name="RB_Group_id"></param>
        /// <returns></returns>
        public List<RB_Attendance_Record_Extend> GetEveryDayAttendanceRecordList(int pageIndex, int pageSize, out long count, string StartTime, string EndTime, int eid, int bid, int DepartmentId, int RB_Group_id)
        {
            return respository.GetEveryDayAttendanceRecordList(pageIndex, pageSize, out count, StartTime, EndTime, eid, bid, DepartmentId, RB_Group_id);
        }
        /// <summary>
        /// 获取原始记录
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="bid"></param>
        /// <param name="DepartmentId"></param>
        /// <param name="RB_Group_id"></param>
        /// <returns></returns>
        public List<RB_Attendance_Record_Extend> GetOriginalRecordList(int pageIndex, int pageSize, out long count, string StartTime, string EndTime, int eid, int bid, int DepartmentId, int RB_Group_id)
        {
            return respository.GetOriginalRecordList(pageIndex, pageSize, out count, StartTime, EndTime, eid, bid, DepartmentId, RB_Group_id);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="bid"></param>
        /// <param name="DepartmentId"></param>
        /// <param name="EmIdStr"></param>
        /// <param name="RB_Group_id"></param>
        /// <param name="IsLeader"></param>
        /// <returns></returns>
        public List<RB_Attendance_Record_Extend> GetClockTimeRecordList(string StartTime, string EndTime, int eid, int bid, int DepartmentId, string EmIdStr, int RB_Group_id, int IsLeader = 1)
        {
            return respository.GetClockTimeRecordList(StartTime, EndTime, eid, bid, DepartmentId, EmIdStr, RB_Group_id, IsLeader);
        }
        /// <summary>
        /// 月度统计请假时长详情
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="AskLeaveType"></param>
        /// <returns></returns>
        public List<Rb_Workflow_Askforleave_Extend> GetAskLeaveInfo(string StartTime, string EndTime, int eid, int AskLeaveType)
        {
            return AskforleaveRepository.GetAskLeaveInfo(StartTime, EndTime, eid, AskLeaveType);
        }

        /// <summary>
        /// 获取打卡时间内的所有用户
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <param name="eid"></param>
        /// <param name="bid"></param>
        /// <param name="DepartmentId"></param>
        /// <param name="RB_Group_id"></param>
        /// <returns></returns>
        public List<RB_Employee_Extend> GetClockTimeEmployeeList(string StartTime, string EndTime, int pageIndex, int pageSize, out long count, int eid, int bid, int DepartmentId, int RB_Group_id)
        {
            return respository.GetClockTimeEmployeeList(StartTime, EndTime, pageIndex, pageSize, out count, eid, bid, DepartmentId, RB_Group_id);
        }

        /// <summary>
        /// 获取每月统计
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="bid"></param>
        /// <param name="DepartmentId"></param>
        /// <param name="RB_Group_id"></param>
        /// <returns></returns>
        public List<RB_Attendance_Record_Extend> GetMonthRecordList(int pageIndex, int pageSize, out long count, string StartTime, string EndTime, int eid, int bid, int DepartmentId, int RB_Group_id)
        {
            return respository.GetMonthRecordList(pageIndex, pageSize, out count, StartTime, EndTime, eid, bid, DepartmentId, RB_Group_id);
        }

        /// <summary>
        /// 四川和平专用  统计每月打卡
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="bid"></param>
        /// <param name="DepartmentId"></param>
        /// <param name="RB_Group_id"></param>
        /// <returns></returns>
        public List<RB_Attendance_Record_Extend> GetMonthRecordListForHPZY(int pageIndex, int pageSize, out long count, string StartTime, string EndTime, int eid, int bid, int DepartmentId, int RB_Group_id)
        {
            var list = dictvalueRepository.GetList(new RB_Dictvalue_Extend() { RB_Group_id = RB_Group_id, DictKey = "SK_BeLateSet_Level" });
            var model = list.FirstOrDefault();
            string Time = model?.Content;
            if (string.IsNullOrWhiteSpace(Time))
            {
                Time = "10";
            }
            return respository.GetMonthRecordListForHPZY(pageIndex, pageSize, out count, StartTime, EndTime, eid, bid, DepartmentId, RB_Group_id, Time);
        }

        /// <summary>
        /// 获取每月统计 单个状态数据
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="eid"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public List<RB_Attendance_Record_Extend> GetRecordForStatusList(string StartTime, string EndTime, int eid, int status)
        {
            return respository.GetRecordForStatusList(StartTime, EndTime, eid, status);
        }

        /// <summary>
        /// 获取该员工所在公司是否开启考勤
        /// </summary>
        /// <param name="groupId"></param>
        /// <param name="branchId"></param>
        /// <returns></returns>
        public int IsAttendanceForBranch(int groupId, int branchId)
        {
            return respository.IsAttendanceForBranch(groupId, branchId);
        }

        /// <summary>
        /// 根据考勤id获取考勤方式
        /// </summary>
        /// <param name="aid"></param>
        /// <returns></returns>
        public List<RB_Attendance_Way_Extend> GetAttendanceWay(int aid)
        {
            return respository.GetAttendanceWay(aid);
        }
        /// <summary>
        /// 获取当前记录的上下班时间
        /// </summary>
        /// <param name="empId"></param>
        /// <param name="currentDate"></param>
        /// <returns></returns>
        public string GetBeOnOffTime(int empId, DateTime currentDate)
        {
            string BeOnOffTime = "";
            //获取特殊日期
            List<RB_Technicaldates_Extend> technicalList = technicaldatesRepository.GetSpecialDateList(empId);
            //正常打卡日期
            List<RB_WorkdaySeting_Extend> workDayList = workdaysetingRepository.GetWorkDayList(empId);
            RB_Technicaldates_Extend technical = technicalList.Where(t => t.Date.Date == currentDate.Date).FirstOrDefault();
            if (technical != null)//特殊日期
            {
                #region 特殊日期
                //当天上班时间
                DateTime onDateTime = Convert.ToDateTime($"{technical.Date.Year}-{technical.Date.Month}-{technical.Date.Day}  {Convert.ToDateTime(technical.BeOnDutyTime).Hour}: {Convert.ToDateTime(technical.BeOnDutyTime).Minute}: {Convert.ToDateTime(technical.BeOnDutyTime).Second}");
                //当天下班时间
                DateTime offDateTime = Convert.ToDateTime($"{technical.Date.Year}-{technical.Date.Month}-{technical.Date.Day}  {Convert.ToDateTime(technical.OffDutyTime).Hour}: {Convert.ToDateTime(technical.OffDutyTime).Minute}: {Convert.ToDateTime(technical.OffDutyTime).Second}");
                #endregion
                BeOnOffTime = "{\"BeOnTime\":\"" + onDateTime.ToString("HH:mm") + "\",\"OffTime\":\"" + offDateTime.ToString("HH:mm") + "\"}";
            }
            else
            {
                RB_WorkdaySeting_Extend workDay = workDayList.Where(t => t.Workday == StringHelper.GetWeek(currentDate.Date)).FirstOrDefault();
                if (workDay != null)
                {
                    #region 正常日期
                    //当天上班时间
                    DateTime onDateTime = Convert.ToDateTime($"{currentDate.Date.Year}-{currentDate.Date.Month}-{currentDate.Date.Day}  {Convert.ToDateTime(workDay.BeOnDutyTime).Hour}: {Convert.ToDateTime(workDay.BeOnDutyTime).Minute}: {Convert.ToDateTime(workDay.BeOnDutyTime).Second}");
                    //当天下班时间
                    DateTime offDateTime = Convert.ToDateTime($"{currentDate.Date.Year}-{currentDate.Date.Month}-{currentDate.Date.Day}  {Convert.ToDateTime(workDay.OffDutyTime).Hour}: {Convert.ToDateTime(workDay.OffDutyTime).Minute}: {Convert.ToDateTime(workDay.OffDutyTime).Second}");
                    #endregion
                    BeOnOffTime = "{\"BeOnTime\":\"" + onDateTime.ToString("HH:mm") + "\",\"OffTime\":\"" + offDateTime.ToString("HH:mm") + "\"}";
                }
            }
            return BeOnOffTime;
        }
        /// <summary>
        /// 更正缺卡
        /// </summary>
        /// <param name="RecordId"></param>
        /// <param name="OnAndOffDuty"></param>
        /// <param name="RecordStatus"></param>
        /// <param name="BeLateTime"></param>
        /// <param name="DKTime"></param>
        /// <param name="SBTime"></param>
        /// <returns></returns>
        public bool SetDayRecord(int RecordId, int OnAndOffDuty, int RecordStatus, string BeLateTime, string DKTime, string SBTime)
        {
            var model = RecordRepository.GetEntity(RecordId);
            if (OnAndOffDuty == 1)//上班
            {
                if (model.BeOnStatus != AttendanceEnum.QK)
                {
                    return false;
                }
                if (RecordStatus == 1)//正常
                {
                    model.BeOnStatus = AttendanceEnum.ZC;
                    model.BeOnAddress = "管理员改为正常";
                }
                else
                {//迟到
                    model.BeOnStatus = AttendanceEnum.CD;
                    model.BeLateTime = Convert.ToInt32(BeLateTime);
                    model.BeOnAddress = "管理员改为迟到";
                }
                model.BeOnDutyTime = Convert.ToDateTime(DKTime + " " + SBTime).AddMinutes(Convert.ToDouble(BeLateTime));
                model.BeOnTime = SBTime;
            }
            else
            {//下班
                if (model.OffStatus != AttendanceEnum.QK)
                {
                    return false;
                }
                if (RecordStatus == 1)//正常
                {
                    model.OffStatus = AttendanceEnum.ZC;
                    model.OffDutyTime = Convert.ToDateTime(DKTime + " " + SBTime).AddMinutes(Convert.ToDouble(BeLateTime));
                    model.OffTime = SBTime;
                    model.OffAddress = "管理员改为正常";
                }
            }
            return RecordRepository.Update(model);
        }

    }
}
