using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Repository.Response;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Linq.Expressions;
using Siger.Middlelayer.Common.Extensions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.CncRepository.Response;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;

namespace Siger.Middlelayer.CncRepository.Repositories
{
    internal class SigerProjectClockRecordRepository: CncRepositoryBase<siger_project_clock_record>, ISigerProjectClockRecord
    {
        private ApiCncDbContext _context;
        public SigerProjectClockRecordRepository(ApiCncDbContext context) : base(context)
        {
            _context = context;
        }
        /// <summary>
        /// total
        /// </summary>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="section"></param>
        /// <param name="shift"></param>
        /// <param name="user_id"></param>
        /// <param name="projectId"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        public IPagedCollectionResult<ResponseAchieveTotal> GetAchieveMentTotal(DateTime starttime, DateTime endtime, int section, int shift, int user_id, int projectId, int page, int pagesize)
        {
            var query = from t in _context.siger_project_clock_record_ttl
                        join u in _context.siger_project_user on t.uid equals u.mid
                        join se in _context.siger_project_section on u.sectionid equals se.id
                        join g in _context.siger_project_usergroup on u.usergroupid.ToInt() equals g.id
                        select new ResponseAchieveTotal
                        {
                            busidate = t.busidate,
                            userId = t.uid,
                            work_code = u.work_code,
                            name = u.name,
                            shift = t.shift,
                            shiftId = t.shiftid,
                            sectionId = se.id,
                            section = se.title,
                            usergroup = g.title,
                            affecthour =t.producehour,
                            avemachine =t.machinesign,
                            workhour = t.workinghour,
                            workeffect = t.efficiency
                        };
            Expression<Func<ResponseAchieveTotal, bool>> funstime = f =>f.busidate>=starttime;
            Expression<Func<ResponseAchieveTotal, bool>> funetime = f =>f.busidate<=endtime.AddDays(1).AddMilliseconds(-1);
            Expression<Func<ResponseAchieveTotal, bool>> funsection = f => true;
            Expression<Func<ResponseAchieveTotal, bool>> funuser = f => true;
            Expression<Func<ResponseAchieveTotal, bool>> funshift = f => true;
            if (user_id != 0)
            {
                funuser = f => f.userId == user_id;
            }
            if (section != 0)
            {
                funuser = f => f.sectionId == section;
            }
            if(shift!=0)
            {
                funshift = f => f.shiftId == shift;
            }

            var predicate = funstime.And(funetime).And(funsection).And(funuser).And(funshift);
            var total = query.Where(predicate).Count();
            var result = query.Where(predicate).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking();
            return new PagedCollectionResult<ResponseAchieveTotal>(result, total);
    
        }

        public IEnumerable<ResponseClockDets> GetClockDetails(DateTime starttime, DateTime endtime, int shiftid, int user_id, int projectId)
        {
            var query = from c in _context.siger_project_clock_record
                        join att in _context.siger_project_machine_attribution on c.machine_id equals att.machine
                        join l in _context.siger_project_level_section on att.station equals l.id
                        join lp in _context.siger_project_level_section on l.parentid equals lp.id
                        where c.projectid == projectId
                        select new ResponseClockDets
                        {
                            uid = c.uid,
                            shift = c.shiftid,
                            location = $"{lp.title}-{l.title}",
                            machine = c.machine_id,
                            startime=c.starttime,
                            endtime=c.endtime,
                            clockin = c.starttime.ToString(),
                            clockout =c.endtime==DateTime.MinValue?"": c.endtime.ToString(),
                            wrokhours = c.workinghour
                        };
            Expression<Func<ResponseClockDets, bool>> funstationline = f => true;
            Expression<Func<ResponseClockDets, bool>> funstarttime = f => true;
            Expression<Func<ResponseClockDets, bool>> funendtime = f => true;
            Expression<Func<ResponseClockDets, bool>> funsection = f => true;
            Expression<Func<ResponseClockDets, bool>> funshift = f => true;
            Expression<Func<ResponseClockDets, bool>> funusers = f => true;

            funstarttime = f => f.startime >= starttime;
            funendtime = f => f.startime <= endtime;
            if (shiftid != 0)
            {
                funshift = f => f.shift == shiftid;
            }
            if (user_id != 0)
            {
                funusers = f => f.uid == user_id;
            }
            var predicate = funstationline.And(funstarttime).And(funendtime).And(funshift).And(funusers);
            return query.Where(predicate);
        }

        public IEnumerable<ReponseRecord> GetClockRecordPopup(int userId, int projectId)
        {
            var query = from a in _context.siger_project_clock_record
                        join b in _context.siger_project_machine_attribution on a.machine_id equals b.machine
                        join c in _context.siger_project_level_section on b.station equals c.id
                        where a.status == (int)RowState.Valid && a.projectid == projectId && a.uid == userId
                        select new ReponseRecord
                        {
                            machinesolution = c.title,
                            starttime = a.starttime,
                            endtime = a.endtime,
                            workinghour = a.workinghour
                        };
            return query.ToList();
        }

        public IPagedCollectionResult<ReponseRecord> GetPagedRecord(string stationline, string starttime, string endtime, int section, int shift, int users, int page, int pagesize,int pid)
        {
            Expression<Func<ReponseRecord, bool>> funstationline = f => true;
            Expression<Func<ReponseRecord, bool>> funstarttime = f => true;
            Expression<Func<ReponseRecord, bool>> funendtime = f => true;
            Expression<Func<ReponseRecord, bool>> funsection = f => true;
            Expression<Func<ReponseRecord, bool>> funshift = f => true;
            Expression<Func<ReponseRecord, bool>> funusers = f => true;
            var query = from a in _context.siger_project_clock_record
                        join u in _context.siger_project_user on a.uid equals u.mid
                        join d in _context.siger_project_section on u.sectionid equals d.id
                        join s in _context.siger_project_usergroup on u.usergroupid.ToInt() equals s.id
                        join h in _context.siger_project_level_section on a.station equals h.id
                        join lp in _context.siger_project_level_section on h.parentid equals lp.id
                        select new ReponseRecord
                        {
                            machinesolution =$"{lp.title}-{h.title}",
                            work_code = u.work_code,
                            name = u.mid,
                            named=u.name,
                            section = u.sectionid,
                            station=a.station,
                            sectioned =d !=null?d.title:"",
                            usergroup = s!=null?s.title:"",
                            shift = a.shift,
                            shiftid = a.shiftid,
                            starttime = a.starttime,
                            endtime =a.endtime,
                            workinghour = a.workinghour,
                            clockin=a.starttime.ToString(),
                            clockout= a.endtime != DateTime.MinValue ? a.endtime.ToString() : "",
                        };
            if (!string.IsNullOrEmpty(starttime))
            {
                funstarttime = f => f.starttime >= starttime.ToDateTime();
            }
            if (!string.IsNullOrEmpty(endtime))
            {
                funendtime = f => f.starttime <= endtime.ToDateTime().AddDays(1).AddMilliseconds(-1);
            }
            if (section!=0)
            {
                funsection = f => f.section == section;
            }
            if (shift!=0)
            {
                funshift = f => f.shiftid == shift;
            }
            if (users != 0)
            {
                funusers = f => f.name == users;
            }

            var predicate = funstationline.And(funstarttime).And(funendtime).And(funsection).And(funshift).And(funusers);
            var total = query.Where(predicate).Count();
            var data = query.Where(predicate).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();

            return new PagedCollectionResult<ReponseRecord>(data, total);
        }

    
    }
}
