using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.TlmRepository.Entities;
using Siger.Middlelayer.TlmRepository.Repositories.Interface;
using Siger.Middlelayer.TlmRepository.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.TlmRepository;
using Siger.Middlelayer.TlmRepository.Response;
using NPOI.SS.Formula.Functions;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Repository.Extensions;

namespace Siger.MiddlelayerTlmRepository.Repositories
{
    public class ProjectToollifeExpectionRepository : RepositoryBase<ProjectToollifeExpectionEntity>, IProjectToollifeExpectionRepository
    {
        private readonly ApiTlmDbContext _context;
        public ProjectToollifeExpectionRepository(ApiTlmDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseGetToollifeExpection> GetPagedList(RequestProjectToollifeExpection req)
        {
            Expression<Func<ProjectToollifeExpectionEntity, bool>> conditionCommon = q => q.Status == (int)RowState.Valid && q.Projectid == req.ProjectId;
            Expression<Func<ProjectToollifeExpectionEntity, bool>> conditionOrderNumber = q => true;
            Expression<Func<ProjectToollifeExpectionEntity, bool>> conditionMachine = q => true;
            Expression<Func<ProjectToollifeExpectionEntity, bool>> conditionMid = q => true;
            Expression<Func<ProjectToollifeExpectionEntity, bool>> conditionToolNumber = q => true;
            Expression<Func<ProjectToollifeExpectionEntity, bool>> conditionTime = q => true;
            if (!string.IsNullOrEmpty(req.order_number))
            {
                conditionOrderNumber = q => q.OrderNumber.StartsWith(req.order_number);
            }
            if (!string.IsNullOrEmpty(req.tool_number))
            {
                conditionToolNumber = q => q.ToolNumber.StartsWith(req.tool_number);
            }
            if (req.start > 0 && req.end > 0)
            {
                conditionTime = q => q.Datetime >= req.start && q.Datetime <= req.end;
            }
            if (req.machineid != 0)
            {
                conditionMachine = q => q.MachineId == req.machineid;
            }
            if (req.mid != 0)
            {
                conditionMid = q => q.MachineId == req.mid;
            }
            var predicates = conditionCommon
                .And(conditionOrderNumber)
                .And(conditionMachine)
                .And(conditionMid)
                .And(conditionToolNumber)
                .And(conditionTime);

            var totalCount = _context.ProjectToollifeExpectionEntities.Count(predicates);
            var ret = new List<ResponseGetToollifeExpection>();
            List<ProjectToollifeExpectionEntity> entities;
            if (req.Page != 0)
            {
                entities = _context.ProjectToollifeExpectionEntities.Where(predicates).OrderByDescending(o => o.Id).Skip((req.Page - 1) * req.PageSize).Take(req.PageSize).AsNoTracking().ToList();
            }
            else
            {
                entities = _context.ProjectToollifeExpectionEntities.Where(predicates).OrderByDescending(o => o.Id).AsNoTracking().ToList();
            }
            var user = _context.siger_project_user.Where(q => q.status == (int)RowState.Valid && q.projectid == req.ProjectId).ToList();
            var attributionList = _context.siger_project_machine_attribution.Where(q => q.status == (int)RowState.Valid && q.projectid == req.ProjectId && q.attribution == 1).AsNoTracking().ToList();
            var toolList = _context.siger_project_toollife_tool.Where(q => q.status == (int)RowState.Valid && q.project_id == req.ProjectId).AsNoTracking().ToList();
            List<siger_project_level_section> sectionList = _context.siger_project_level_section.Where(q => q.status == (int)RowState.Valid && q.projectid == req.ProjectId).AsNoTracking().ToList();
            foreach (var item in entities)
            {
                var attr = attributionList.FirstOrDefault(f => f.machine == item.MachineId);
                var model = Mapper<ProjectToollifeExpectionEntity, ResponseGetToollifeExpection>.Map(item);
                model.SectionName = "";
                model.MachineName = "";
                model.ToolStandardLife = "";
                model.CreatorName = user.FirstOrDefault(f => f.mid == item.Creator)?.name ?? "";
                if (attr != null)
                {
                    model.SectionName = string.Join("-", GetParentLevelSections(attr.station, req.ProjectId, sectionList).Take(2).OrderBy(o => o.id).Select(s => s.title));
                    model.MachineName = attr?.name ?? "";
                    model.SectionId = attr?.station ?? 0;
                }
                if (item.Changer != 0)
                {
                    model.Section = _context.siger_project_user.FirstOrDefault(f => f.mid == item.Changer)?.sectionid ?? 0;
                }
                ret.Add(model);
            }
            return new PagedCollectionResult<ResponseGetToollifeExpection>(ret, totalCount);
        }

        private IEnumerable<siger_project_level_section> GetParentLevelSections(int id, int projectid, List<siger_project_level_section> section)
        {
            var query = from c in section
                        where c.id == id && c.status == (int)RowState.Valid
                        select c;

            return query.ToList().Concat(query.ToList().SelectMany(t => GetParentLevelSections(t.parentid, projectid, section))).OrderByDescending(o => o.id);
        }

        public string Generator(int pid)
        {
            var now = $"IN-{DateTime.Now.Date.ToString("yyyyMMdd")}-";
            var ret = "";
            var entities = _context.ProjectToollifeExpectionEntities.Where(q => q.Status == (int)RowState.Valid && q.Projectid == pid && q.OrderNumber.StartsWith(now)).ToList();
            if (entities.Any())
            {
                var model = entities.OrderByDescending(o => o.Id).FirstOrDefault()?.OrderNumber ?? "";
                if (!string.IsNullOrEmpty(model))
                {
                    ret = $"{now}{model.Split('-').Last().ToInt() + 1}";
                }
            }
            if (string.IsNullOrEmpty(ret))
            {
                ret = $"{now}{1}";
            }
            return ret;
        }
    }
}
