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

namespace Siger.Middlelayer.CncRepository.Repositories
{
    internal abstract class CncRepositoryBase<TEntity> : RepositoryBase<TEntity> where TEntity : CncEntityBase
    {
        private readonly ApiCncDbContext _context;
        protected CncRepositoryBase(ApiCncDbContext context) : base(context)
        {
            _context = context;
        }

        public IEnumerable<int> GetLevelSectionIds(int id, int projectid)
        {
            var list = new List<int>();
            var query = GetSonLevelSections(id, projectid);

            list.Add(id);
            foreach (var section in query.ToList())
            {
                list.Add(section.id);
            }

            return list;
        }

        public IEnumerable<string> GetLevelSectionTitles(int id, int projectid)
        {
            var list = new List<string>();

            var query = GetParentLevelSections(id, projectid);

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

            return list;
        }

        public IEnumerable<siger_project_level_section> GetParentLevelSections(int id, int projectid)
        {
            var query = from c in _context.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> GetLevelSectionMachineIds(int id, int projectid)
        {
            var list = new List<int>();
            var query = GetSonLevelSections(id, projectid);

            list.Add(id);
            foreach (var section in query.ToList())
            {
                list.Add(section.id);
            }

            var querylist = from q in _context.siger_project_machine_attribution
                join m in _context.siger_project_machine on q.machine equals m.id into ma
                from m in ma.DefaultIfEmpty()
                where list.Contains(q.station) && q.status == (int)RowState.Valid &&
                      m.status == (int)RowState.Valid && q.attribution == 1
                      && m.projectid == projectid && m.category == (int)MachineCategory.NC
                      orderby m.sorting
                select q.machine;

            return querylist.ToList();
        }

        protected IEnumerable<siger_project_level_section> GetSonLevelSections(int parentId, int projectid)
        {
            var query = from c in _context.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).ToList()));
        }
    }
}
