using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;
using ProjectLevel = Siger.Middlelayer.Repository.Data.ProjectLevel;

namespace Siger.ApiConfig.Controller
{
    public class ProjectOrganizationController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly ISigerProjectGroupRepository _projectGroupRepository;
        private readonly ISigerProjectUserGroupRepository _projectUserGroupRepository;
        private readonly ISigerProjectLevelRepository _projectLevelRepository;
        private readonly ISigerProjectSectionRepository _projectSectionRepository;
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;

        public ProjectOrganizationController(IUnitOfWork unitOfWork,
            ISigerProjectGroupRepository projectGroupRepository,
            ISigerProjectUserGroupRepository projectUserGroupRepository,
            ISigerProjectLevelRepository projectLevelRepository,
            ISigerProjectSectionRepository projectSectionRepository,
            ISigerProjectUserRepository userRepository, ISigerProjectLevelSectionRepository levelSectionRepository)
        {
            _unitOfWork = unitOfWork;
            _userRepository = userRepository;
            _projectGroupRepository = projectGroupRepository;
            _projectUserGroupRepository = projectUserGroupRepository;
            _projectLevelRepository = projectLevelRepository;
            _projectSectionRepository = projectSectionRepository;
            _levelSectionRepository = levelSectionRepository;
        }

        [HttpGet]
        public IActionResult GetProjectUserTypeBtn()
        {
            var response = new List<ResponseProjectUserType>();
            var list = _projectSectionRepository.GetList(q =>
                q.status == (int) RowState.Valid && q.projectid == ProjectId);

            foreach (var sigerProjectSection in list)
            {
                response.Add(Mapper<siger_project_section, ResponseProjectUserType>.Map(sigerProjectSection));
            }
            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult AddSectionGroupUser([FromBody]RequestAddSectionGroupUser request)
        {
            var result = _projectUserGroupRepository.AddUser_Group(request.mid.Split(',').Select(t => t.ToInt()).Distinct().ToList(), request.groupid);

            if (result > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult DeleteSectionGroupUser(int groupid, int mid )
        {
            var result = _projectUserGroupRepository.DeleteUser_Group(mid, groupid);
            if (result > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult AddCurrentProjectLevelSection([FromBody] RequestAddProjectLevelSection request)
        {
            if (request.title == null || !request.title.Any())
            {
                throw new BadRequestException(RequestEnum.LevelNotFound);
            }

            var result = _levelSectionRepository.AddLevelSections(request.title.ToList(), ProjectId);
            if (result)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetCurrentProjectCustomLevelBtn()
        {
            var response = new List<ProjectLevel>();
            var levels = _projectLevelRepository
                .GetList(q => q.projectid == ProjectId && q.status == (int) RowState.Valid)
                .OrderBy(q => q.levelid);
            var index = 0;
            foreach (var sigerProjectLevel in levels)
            {
                var level = new ProjectLevel();
                level.id = sigerProjectLevel.id;
                level.name = sigerProjectLevel.title;
                level.level = sigerProjectLevel.parentid;
                level.sort = index;
                level.pLevel = index;
                level.levelid = sigerProjectLevel.levelid;
                level.parentid = sigerProjectLevel.parentid;
                response.Add(level);
                index++;
            }
            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetProjectUserTreeBySectionId(int id)
        {         
            var list = _projectUserGroupRepository.GetProjectUserTreeBySectionId(id, ProjectId);

            return new ObjectResult(list);
        }

        [HttpGet]
        public IActionResult GetSectionGroupBySectionId(int id)
        {
            var response = new List<ResponseProjectGroup>();
            var list = _projectGroupRepository.GetList(q => q.departid == id && q.projectid == ProjectId && q.status == (int)RowState.Valid);

            foreach (var sigerProjectGroup in list)
            {
                var group = Mapper<siger_project_group, ResponseProjectGroup>.Map(sigerProjectGroup);
                group.title = group.name;
                response.Add(group);
            }
            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetSectionGroupUserLists(int departmentid, int groupid)
        {
            var userIds = _projectUserGroupRepository.GetUser_GroupsByGroupId(groupid).Select(m => m.mid);

            var userEntities = _userRepository.GetList(q => userIds.Contains(q.mid)
                && q.projectid == ProjectId && q.status == (int)RowState.Valid && q.sectionid == departmentid);

            var response = new List<ResponseGetLevelUser>();

            if (!userEntities.Any())
            {
                return new ObjectResult(response);
            }

            var users = _projectUserGroupRepository.GetUser_GroupsByGroupId(groupid);
            foreach (var user in users.ToList())
            {
                var userEntity = userEntities.FirstOrDefault(q => q.mid == user.mid);
                if (userEntity == null)
                {
                    continue;
                }
                var userGroup = _projectUserGroupRepository.Get(q => q.id.ToString() == userEntity.usergroupid && q.projectid == ProjectId && q.status == (int) RowState.Valid);
                if (userGroup != null)
                {
                    response.Add(new ResponseGetLevelUser
                    {
                        groupid = groupid,
                        mid = user.mid,
                        name = userEntity.name,
                        usergroupid = userEntity.usergroupid,
                        usergroupname = userGroup.title
                    });
                }
            }
            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult UpdateCurrentProjectCustomLevelById([FromBody]RequestUpdateCustomLevel request)
        {
            var entity = _levelSectionRepository.Get(q =>
                q.id == request.id && q.projectid == ProjectId && q.status == (int) RowState.Valid);

            if (entity != null)
            {
                entity.title = request.title;
                _levelSectionRepository.Update(entity);
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }
            throw new BadRequestException(RequestEnum.LevelNotFound);
        }
    }
}