using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Entities;

namespace Siger.Middlelayer.ToolRepository.Repositories
{
    internal abstract class ApiToolRepositoryBase<TEntity> : RepositoryBase<TEntity> where TEntity : EntityBase
    {
        private readonly ApiToolDbContext _toolDbContext;
        protected ApiToolRepositoryBase(ApiToolDbContext context) : base(context)
        {
            _toolDbContext = context;
        }

        public IEnumerable<int> GetSonLevelSectionIds(int sectionId, int projectid)
        {
            var list = new List<int> {sectionId};
            var sectionList = _toolDbContext.siger_project_level_section.Where(f => f.projectid == projectid && f.status != 0).AsNoTracking().ToList();
            var query = GetSonLevelSections(sectionId, sectionList);
            foreach (var section in query.ToList())
            {
                list.Add(section.id);
            }
            return list;
        }

        private IEnumerable<siger_project_level_section> GetSonLevelSections(int parentId, int projectid)
        {
            var query = from c in _toolDbContext.siger_project_level_section
                where c.parentid == parentId && c.projectid == projectid && c.status == (int)RowState.Valid
                select c;

            return query.ToList().Concat(query.ToList().SelectMany(t => GetSonLevelSections(t.id, projectid)));
        }

        private IEnumerable<siger_project_level_section> GetSonLevelSections(int parentId, List<siger_project_level_section> sectionList)
        {
            var query = sectionList.Where(f => f.parentid == parentId);
            return query.ToList().Concat(query.ToList().SelectMany(t => GetSonLevelSections(t.id, sectionList)));
        }


        public IEnumerable<int> GetParentLevelSectionIds(int sectionId, int projectid)
        {
            var list = new List<int> { sectionId };
            var query = GetParentLevelSections(sectionId, projectid);

            foreach (var section in query.ToList().OrderBy(q => q.id))
            {
                list.Add(section.id);
            }

            return list;
        }

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

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

        public IEnumerable<int> GetMachineIds(int sectionId, int projectId)
        {
            var sectionIds = GetSonLevelSectionIds(sectionId, projectId);

            var querylist = from q in _toolDbContext.siger_project_machine_attribution
                join m in _toolDbContext.siger_project_machine on q.machine equals m.id
                where sectionIds.Contains(q.station) && q.status == (int)RowState.Valid && m.status == (int)RowState.Valid
                      && m.projectid == projectId && m.category == (int)MachineCategory.NC
                select m.id;

            return querylist.Distinct().ToList();
        }
    }
}
