using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Repositories.Interface;

namespace Siger.ApiConfig.Controller
{
    public class UserLevelController : BaseController
    {
        private readonly ISigerProjectLevelRepository _sigerProjectLevelPowerRepository;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSectionRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectLevelSectionMachineRepository _levelSectionMachineRepository;

        public UserLevelController(ISigerProjectLevelRepository sigerProjectLevelPowerRepository, ISigerProjectLevelSectionRepository sigerProjectLevelSectionRepository,
            ISigerProjectMachineRepository machineRepository, ISigerProjectLevelSectionMachineRepository levelSectionMachineRepository)
        {
            _sigerProjectLevelPowerRepository = sigerProjectLevelPowerRepository;
            _sigerProjectLevelSectionRepository = sigerProjectLevelSectionRepository;
            _machineRepository = machineRepository;
            _levelSectionMachineRepository = levelSectionMachineRepository;
        }

        [HttpGet]
        public ActionResult GetCurrentUserProjectLevel()
        {
            var result = _sigerProjectLevelPowerRepository
                .GetList(f => f.status == (int) RowState.Valid && f.projectid == ProjectId)
                .Select(f => new {f.id, f.title, f.levelid}).ToList();
            return new ObjectResult(result);
        }

        [HttpGet]
        public ActionResult GetCurrentUserProjectLevelExceptSection()
        {
            var lastLevel = _sigerProjectLevelPowerRepository.GetList(f =>
                f.status == (int) RowState.Valid && f.projectid == ProjectId).Max(m => m.id);

            var result = _sigerProjectLevelSectionRepository.GetList(f =>
                    f.status == (int) RowState.Valid && f.projectid == ProjectId && f.levelid != lastLevel)
                .ToList();

            var sections = new List<LevelSectionTree>();
            foreach (var sigerProjectLevel in result)
            {
                sections.Add(new LevelSectionTree
                {
                    id = sigerProjectLevel.id,
                    levelId = sigerProjectLevel.levelid,
                    name = sigerProjectLevel.title,
                    pid = sigerProjectLevel.parentid,
                    open = true
                });
            }

            var response = new ResponseLevelSectionChildren(ConvertToTree(sections));

            return new ObjectResult(response);
        }

        private IList<LevelSectionTree> ConvertToTree(IEnumerable<LevelSectionTree> models)
        {
            var section = new Dictionary<int, LevelSectionTree>();
            foreach (var item in models)
            {
                section.Add(item.id, item);
            }
            var result = new List<LevelSectionTree>();
            foreach (var item in section.Values)
            {
                if (item.pid == 0)
                {
                    result.Add(item);
                }
                else
                {
                    if (section.ContainsKey(item.pid))
                    {
                        section[item.pid].AddChilrden(item);
                    }
                }
            }
            return result;
        }

        [HttpGet]
        public ActionResult GetLevelById(int id)
        {
            var data = _sigerProjectLevelSectionRepository
                .GetList(f => f.status == RowState.Valid.GetHashCode() && f.levelid == id)
                .Select(f => new {f.id, f.title, f.levelid}).ToList();
            if (!data.Any())
            {
               // return new ObjectResult(ConfigEnum.UserLevelNull);
                throw new BadRequestException(ConfigEnum.UserLevelNull);
            }
            return new ObjectResult(data);
        }

        [HttpGet]
        public ActionResult GetLevelChildrenById(int id)
        {
            var result = _sigerProjectLevelPowerRepository
                .GetList(f => f.status == RowState.Valid.GetHashCode() && f.projectid == ProjectId)
                .OrderBy(f => f.levelid)
                .Select(f => new {f.id, f.title, f.levelid}).ToList();
            if (!result.Any())
            {
                throw new BadRequestException(ConfigEnum.UserLevelNull);
            }

            var lastid = result.Last().id;
            var list = _sigerProjectLevelSectionRepository.GetList(f => f.status == RowState.Valid.GetHashCode() 
                                                                        && f.parentid == id && f.projectid == ProjectId)
                .Select(f => new {f.id, f.title, f.levelid, isStation = f.levelid == lastid}).ToList();
            return new ObjectResult(list);
        }

        [HttpGet]
        public IActionResult ListMachineIdArr(int id)
        {
            var machineids = _sigerProjectLevelSectionRepository.GetLevelSectionMachineIds(id, ProjectId);

            return new ObjectResult(machineids);
        }

        [HttpGet]
        public ActionResult GetNCLevelChildrenById(int id)
        { 
            var result = _sigerProjectLevelPowerRepository
                .GetList(f => f.status == RowState.Valid.GetHashCode() && f.projectid == ProjectId)
                .OrderBy(f => f.levelid)
                .Select(f => new { f.id, f.title, f.levelid }).ToList();
            if (!result.Any())
            {
                throw new BadRequestException(ConfigEnum.UserLevelNull);
            }

            var lastid = result.Last().id;
            if (id > 0)
            {
                var section = _sigerProjectLevelSectionRepository.Get(t =>
                    t.id == id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                if (section == null)
                {
                    throw new BadRequestException(RequestEnum.SectionIsEmpty);
                }
            }

            var list = _sigerProjectLevelSectionRepository.GetList(f => f.status == RowState.Valid.GetHashCode()
                                                                        && f.parentid == id && f.projectid == ProjectId)
                .Select(f => new { f.id, f.title, f.levelid, isStation = f.levelid == lastid, f.parentid }).ToList();
            if (!list.Any())
            {
                return new ObjectResult(list);
            }
            var removeList = new List<int>();
            foreach (var sections in list)
            {
                var parentIds = new List<int> { sections.id };
                var i = 1;
                foreach (var level in result)
                {
                    if (sections.levelid <= level.id)
                    {
                        if (i == result.Count)
                        {
                            break;
                        }
                        var ids = parentIds;
                        parentIds = _sigerProjectLevelSectionRepository.GetList(t =>
                            ids.Contains(t.parentid) && t.projectid == ProjectId && t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                    }

                    i++;
                }

                var machineIds = _levelSectionMachineRepository.GetList(t =>
                    t.status == (int)RowState.Valid && parentIds.Contains(t.section_id)).Select(t => t.machine_id).ToList();
                var machines = _machineRepository.GetList(t =>
                    machineIds.Contains(t.id) && t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                    t.category == (int)MachineCategory.NC);
                if (!machines.Any())
                {
                    removeList.Add(sections.id);
                }
            }

            list = list.Where(t => !removeList.Contains(t.id)).ToList();
            return new ObjectResult(list);
        }

        [HttpGet]
        public IActionResult ListNCMachineIdArr(int id)
        {
            var machineids = _machineRepository.GetNCLevelSectionMachineIds(id, ProjectId);

            return new ObjectResult(machineids);
        }


        /// <summary>
        /// 根据section获取所有machineid
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult ListMachineIdArrEx(int id)
        {
            var machineids = _machineRepository.GetAttributionMachineIds(id, ProjectId);
            return new ObjectResult(machineids);
        }
    }
}