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

namespace Siger.Middlelayer.TpmRepository.Repositories
{
    internal class ProjectOutsourcedMaintenanceRepository : TpmRepositoryBase<ProjectOutsourcedMaintenanceEntity>, IProjectOutsourcedMaintenanceRepository
    {
        private readonly ApiTpmDbContext _context;
        public ProjectOutsourcedMaintenanceRepository(ApiTpmDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseProjectOutsourcedMaintenance> GetPagedList(RequestProjectOutsourcedMaintenance req)
        {
            var ret = new List<ResponseProjectOutsourcedMaintenance>();
            var pid = req.projectId;
            var query = _context.ProjectOutsourcedMaintenanceEntities.Where(f => f.ProjectId == pid && f.status != 0);
            Expression<Func<ProjectOutsourcedMaintenanceEntity, bool>> conditionRepairTime = q => true;
            if (!string.IsNullOrEmpty(req.repairstart) && !string.IsNullOrEmpty(req.repairend))
            {
                var start = req.repairstart.ToInt();
                var end = req.repairend.ToInt();
                conditionRepairTime = f => f.RepairTime >= start && f.RepairTime <= end;
            }
            Expression<Func<ProjectOutsourcedMaintenanceEntity, bool>> conditionEditTime = q => true;
            if (!string.IsNullOrEmpty(req.editstart) && !string.IsNullOrEmpty(req.editend))
            {
                var start = req.editstart.ToInt();
                var end = req.editend.ToInt();
                conditionEditTime = f => f.EditTime >= start && f.EditTime <= end;
            }
            Expression<Func<ProjectOutsourcedMaintenanceEntity, bool>> conditionState = q => true;
            if (!string.IsNullOrEmpty(req.state))
            {
                var states = req.state.Split(',');
                conditionState = f => states.Contains(f.State.ToStr());
            }
            Expression<Func<ProjectOutsourcedMaintenanceEntity, bool>> conditionMachine = q => true;
            if (!string.IsNullOrEmpty(req.machine))
            {
                var machines = req.machine.Split(',');
                conditionMachine = f => machines.Contains(f.MachineId.ToStr());
            }
            Expression<Func<ProjectOutsourcedMaintenanceEntity, bool>> conditionSection = q => true;
            if (!string.IsNullOrEmpty(req.section))
            {
                var mids = GetMachineIdsBySection(req.section.ToInt(), pid);
                conditionSection = f => mids.Contains(f.MachineId);
            }
            Expression<Func<ProjectOutsourcedMaintenanceEntity, bool>> conditionProcess = q => true;
            if (!string.IsNullOrEmpty(req.processId)||!string.IsNullOrEmpty(req.mid))
            {
                var processIds = req.processId.Split(',');
                conditionProcess = f => processIds.Contains(f.ProcessId.ToStr());
            }
            var predicates = conditionRepairTime.And(conditionEditTime).And(conditionState).And(conditionMachine).And(conditionSection).And(conditionProcess);
            var totalCount = query.Count(predicates);
            List<ProjectOutsourcedMaintenanceEntity> entities;
            if (req.toExcel.ToInt() == 1)
            {
                entities = query.Where(predicates).AsNoTracking().ToList();
            }
            else
            {
                entities = query.Where(predicates).Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).AsNoTracking().ToList();
            }
            var userList = _context.siger_project_user.Where(f => f.projectid == pid && f.status != 0).AsNoTracking().ToList();
            var machineList = _context.siger_project_machine.Where(f => f.projectid == pid && f.status != 0).AsNoTracking().ToList();
            var sectionList = _context.siger_project_level_section.Where(f => f.projectid == pid && f.status != 0).AsNoTracking().ToList();
            var machineAttrList = _context.siger_project_machine_attribution.Where(f => f.projectid == pid && f.status != 0 && f.attribution == 1).AsNoTracking().ToList();
            foreach (var item in entities)
            {
                var model = Mapper<ProjectOutsourcedMaintenanceEntity, ResponseProjectOutsourcedMaintenance>.Map(item);
                model.CreatorName = userList.FirstOrDefault(f => f.mid == model.Creator)?.name ?? "";
                model.EditorName = userList.FirstOrDefault(f => f.mid == model.Editor)?.name ?? "";
                model.MachineName = machineList.FirstOrDefault(f => f.id == model.MachineId)?.title ?? "";
                model.Section = machineAttrList.FirstOrDefault(f => f.machine == model.MachineId)?.station ?? 0;
                model.SectionName = string.Join("-", GetAllParentLevelSections(model.Section, sectionList).OrderBy(o=>o.id).Select(s => s.title));
                ret.Add(model);
            }
            return new PagedCollectionResult<ResponseProjectOutsourcedMaintenance>(ret, totalCount);
        }
    }
}
