using System.Collections.Generic;
using System.Linq;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Utility.ExcelImport;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.Repository.Repositories
{
    internal class SigerProjectLevelRepository:ApiConfigRepositoryBase<siger_project_level>,ISigerProjectLevelRepository
    {
        private readonly ApiConfigDbContext _context;
        public SigerProjectLevelRepository(ApiConfigDbContext context) : base(context)
        {
            _context = context;
        }

        public IEnumerable<IdTitle> GetProjectListsWithout()
        {
            var list = new List<IdTitle>();
            var projects = _context.siger_project.Where(q => q.status == (int) RowState.Valid);

            var levels = _context.siger_project_level.Where(q => q.status == (int) RowState.Valid);

            foreach (var sigerProject in projects)
            {
                var level = levels.FirstOrDefault(q => q.projectid == sigerProject.id);
                if (level == null)
                {
                    if (!list.Select(q => q.id).Contains(sigerProject.id))
                    {
                        list.Add(new IdTitle { id = sigerProject.id, title = sigerProject.title });
                    }
                }
            }

            return list;
        }

        public bool CanDelete(int projectid)
        {
            var query = from q in _context.siger_project_level
                join se in _context.siger_project_level_section on q.id equals se.levelid into sec
                from se in sec.DefaultIfEmpty()
                where q.status == (int) RowState.Valid && se.status == (int) RowState.Valid
                                                       && q.projectid == projectid
                select q.id;
            return !query.Any();
        }

        public int InsertAndGetId(string title, int parentid, int levelid, int projectid)
        {
            var level = new siger_project_level
            {
                projectid = projectid,
                levelid = levelid,
                parentid = parentid,
                title = title
            };

            _context.siger_project_level.Add(level);
            if (_context.SaveChanges() > 0)
            {
                return level.id;
            }
            return 0;
        }

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

            var query = GetSonLevels(id, projectid);

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

            return list;
        }

        private int AddSection(string title, int levelId, int projectid, int parentId, int lastLevelId)
        {
            //最后一层名称可以重复
            if (levelId != lastLevelId)
            {
                var exist = _context.siger_project_level_section.FirstOrDefault(q =>
                    q.title == title && q.levelid == levelId && q.projectid == projectid && q.status == (int)RowState.Valid);
                if (exist != null)
                {
                    return exist.id;
                }
            }

            var section = new siger_project_level_section
            {
                projectid = projectid,
                title = title,
                status = (int)RowState.Valid,
                levelid = levelId,
                parentid = parentId,
                dutymid = 0,
            };
            _context.siger_project_level_section.Add(section);
            _context.SaveChanges();

            return section.id;
        }

        public CommonImportResult ImportSections(IEnumerable<LevelSectionEntity> sections, int projectid)
        {
            var errors = new List<string>();
            var rowIndex = 1;
            var projectLevelIds = GetSonLevels(0, projectid).Select(m => m.id).Distinct().OrderBy(q => q).ToList();
            var lastLevelId = projectLevelIds.Max();
            var insertResult = 0;
            foreach (var sectionEntity in sections)
            {
                rowIndex++;
                //check levels
                if (projectLevelIds.Count != sectionEntity.Levels.Count)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.LevelNotFound}");
                }
                var exist = sections.Where(q => string.Join(",", q.Levels) == string.Join(",", sectionEntity.Levels)).Count();
                if(exist > 1)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.RepeatBoxListCodeExsit}");
                }
                else
                {
                    var parentId = 0;
                    for (var i = 0; i < projectLevelIds.Count; i++)
                    {
                        var exitsObj = _context.siger_project_level_section.FirstOrDefault(f => f.projectid == projectid && f.title == sectionEntity.Levels[i] && f.levelid== projectLevelIds[i] && f.parentid==parentId);
                        if (exitsObj == null)
                        {
                            parentId = AddSection(sectionEntity.Levels[i], projectLevelIds[i], projectid, parentId, lastLevelId);
                            insertResult += 1;
                        }
                        else
                        {
                            parentId = exitsObj.id;
                            if (i==projectLevelIds.Count-1)
                            {
                                errors.Add($"{rowIndex},{(int)RequestEnum.LevelExist}");
                            }
                        }
                    }
                }
            }

            //if (insertResult==0)
            //{
            //    errors.Add("未插入任何数据");
            //}
            if (errors.Any())
            {
                return new CommonImportResult(0, string.Join(";", errors));
            }

            return new CommonImportResult(1, "1");
        }

        private IEnumerable<siger_project_level> GetSonLevels(int parentid, int projectid)
        {
            var query = from c in _context.siger_project_level
                where c.parentid == parentid && c.projectid == projectid && c.status == (int)RowState.Valid
                select c;

            return query.OrderBy(q => q.levelid).ToList().Concat(query.ToList().SelectMany(t => GetSonLevels(t.id, projectid)));
        }
    }
}
