using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Result;
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;

namespace Siger.ApiConfig.Controller
{
    public class ProjectUserGroupController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectUserGroupRepository _projectUserGroupRepository;
        private readonly ISigerUserRoleRepository _sigerUserRoleRepository;
        public ProjectUserGroupController(IUnitOfWork unitOfWork, ISigerProjectUserGroupRepository projectUserGroupRepository,
            ISigerUserRoleRepository sigerUserRoleRepository)
        {
            _unitOfWork = unitOfWork;
            _sigerUserRoleRepository = sigerUserRoleRepository;
            _projectUserGroupRepository = projectUserGroupRepository;
        }

        [HttpGet]
        public IActionResult SelectUserGroupItem(int id)
        {
            var data = _projectUserGroupRepository.GetUserGroupItem(id, ProjectId);
            if (data == null)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }

            var item = Mapper<UserGroupItem, ResponseGetUserGroupItem>.Map(data);
            item.create_time = UnixTimeHelper.ConvertStringDateTime(data.create_time.ToString())
                .ToString(ParameterConstant.DateTimeFormat);
            item.time = UnixTimeHelper.ConvertStringDateTime(data.time.ToString())
                .ToString(ParameterConstant.DateTimeFormat);
            item.fatherUserGroupTitle = string.IsNullOrEmpty(item.fatherUserGroupTitle)
                ? "<em class=\"text-muted\">已经是父级</em>"
                : item.fatherUserGroupTitle;

            return new ObjectResult(item);
        }

        [HttpGet]
        public IActionResult SelectUserGroupItem2(int id, int page = 1, int pagesize = PageSize)
        {
            var response = new List<ResponseGetUserGroupItem>();
            var list = _projectUserGroupRepository.GetUserGroupItems(id, ProjectId, page, pagesize);
            foreach (var userGroupItem in list.Data)
            {
                var item = Mapper<UserGroupItem, ResponseGetUserGroupItem>.Map(userGroupItem);
                item.create_time = UnixTimeHelper.ConvertStringDateTime(userGroupItem.create_time.ToString())
                    .ToString(ParameterConstant.DateTimeFormat);
                item.time = UnixTimeHelper.ConvertStringDateTime(userGroupItem.time.ToString())
                    .ToString(ParameterConstant.DateTimeFormat);
                item.fatherUserGroupTitle = string.IsNullOrEmpty(item.fatherUserGroupTitle)
                    ? "<em class=\"text-muted\">已经是父级</em>"
                    : item.fatherUserGroupTitle;

                response.Add(item);
            }

            return new PagedObjectResult(response, list.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult AddUserGroup([FromBody] RequestAddUserGroup request)
        {
            if (request.sectionid == 0)
            {
                throw new BadRequestException(RequestEnum.SectionIsEmpty);
            }
            var isExist = _projectUserGroupRepository.IsExist(q => q.title == request.title && q.sectionid == request.sectionid 
                                                                                            && q.projectid == ProjectId && q.status == (int)RowState.Valid);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }

            var name = request.title + "_" + ProjectId;
            var roleId = _sigerUserRoleRepository.AddUserRole(name, 2);

            var group = new siger_project_usergroup();
            group.sectionid = request.sectionid;
            group.create_mid = UserId;
            group.description = request.description;
            group.title = request.title;
            group.parentid = request.parentid.ToInt();
            group.projectid = ProjectId;
            group.role_id = roleId;
            group.time = UnixTimeHelper.GetNow();
            group.create_ip = ServerIpAddress;
            _projectUserGroupRepository.Insert(group);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult Update([FromBody] RequestUpdateUserGroup request)
        {
            var group = _projectUserGroupRepository.Get(request.id);
            if (group == null || group.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }
            var isExist = _projectUserGroupRepository.IsExist(q => q.title == request.title && q.projectid == ProjectId 
                                                                                           && q.id != group.id && q.status == (int)RowState.Valid);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.SectionHasExist);
            }
            group.sectionid = request.sectionid;
            group.description = request.description;
            group.title = request.title;
            group.parentid = request.parentid.ToInt();
            group.create_mid = UserId;
            _projectUserGroupRepository.Update(group);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult Delete(int id)
        {
            var section = _projectUserGroupRepository.Get(q => q.id == id && q.status == (int)RowState.Valid);
            if (section == null)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }

            section.status = (int)RowState.Invalid;
            _projectUserGroupRepository.Update(section);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetAllUserGroups()
        {
            var groups = _projectUserGroupRepository.GetList(q => q.projectid == ProjectId && q.status == (int) RowState.Valid)
                .Select(m => new
                {
                    m.id,
                    m.title
                }).ToList();

            return new ObjectResult(groups);
        }

        [HttpGet]
        public IActionResult GetParentUserGroups()
        {
            var groups = _projectUserGroupRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid&& q.parentid==0)
                .Select(m => new
                {
                    m.id,
                    m.title
                }).ToList();

            return new ObjectResult(groups);
        }

        [HttpGet]
        public IActionResult ListSectionUsergroup()
        {
            var result = new UserGroupSectionResult();
            var groups = _projectUserGroupRepository.GetGroupSectionInfos(ProjectId);
            var sectionIds = groups.Select(m => m.sectionID).Distinct();
            foreach (var sectionId in sectionIds)
            {
                var section = groups.FirstOrDefault(m => m.sectionID == sectionId);
                if (section == null)
                {
                    continue;
                }

                var userGroupSection = new UserGroupSection
                {
                    id = sectionId,
                    title = section.sectionTitle
                };

                var group = groups.Where(q => q.sectionID == sectionId);
                foreach (var userGroupSectionInfo in group)
                {
                    userGroupSection.children.Add(new UserGroupSectionChildrenInfo
                    {
                        groupID = userGroupSectionInfo.groupID,
                        groupTitle = userGroupSectionInfo.groupTitle
                    });
                }

                result.data.Add(userGroupSection);
            }

            return result;
        }
    }
}