using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Redis;
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 ProjectController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectRepository _projectRepository;
        private readonly ISigerUserRepository _userRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly ISigerProjectTypeRepository _projectTypeRepository;
        private readonly ISigerUserPowerRepository _powerRepository;
        private readonly IAccSqlRepository _sqlRepository;
        public ProjectController(IUnitOfWork unitOfWork, ISigerProjectRepository projectRepository, ISigerUserRepository userRepository,
            ISigerProjectUserRepository projectUserRepository, ISigerProjectTypeRepository projectTypeRepository,
            ISigerUserPowerRepository powerRepository, IAccSqlRepository sqlRepository)
        {
            _unitOfWork = unitOfWork;
            _projectRepository = projectRepository;
            _userRepository = userRepository;
            _projectUserRepository = projectUserRepository;
            _projectTypeRepository = projectTypeRepository;
            _powerRepository = powerRepository;
            _sqlRepository = sqlRepository;
        }

        [HttpGet]
        public IActionResult GetLists(string title, string mid, string companyid, string dutymid,
            string salesmid, string typeid, int page = 1, int pagesize = PageSize)
        {
            var response = new List<ResponseGetProject>();

            var projects =
                _projectRepository.GetPagedCollectionResult(title, mid, companyid, dutymid, salesmid, typeid, page,
                    pagesize);
            foreach (var project in projects.Data)
            {
                response.Add(Mapper<Project, ResponseGetProject>.Map(project));
            }

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

        [HttpGet]
        public IActionResult GetProjectLists()
        {
            var response = new List<ResponseGetProjectTitle>();
            var projects = _projectRepository.GetList(q => q.status == (int)RowState.Valid);
            foreach (var project in projects)
            {
                response.Add(Mapper<siger_project, ResponseGetProjectTitle>.Map(project));
            }

            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult AddProjectAndUser([FromBody] RequestAddProject request)
        {
            if (string.IsNullOrEmpty(request.password))
            {
                throw new BadRequestException(RequestEnum.PasswordIsEmpty);
            }
            var projectEntity = _projectRepository.Get(q => q.companyid == request.companyid
                                                            && q.title == request.title && q.status == (int)RowState.Valid);
            if (projectEntity != null)
            {
                throw new BadRequestException(RequestEnum.ProjectIsExist);
            }
            //当前代码前端赋值projectid，后端使用pid值永远为0，后续功能迭代处理， edit by peter 2020.12.21
            //projectEntity = _projectRepository.Get(q => q.id == request.pid && q.status == (int)RowState.Valid);
            //if (projectEntity != null)
            //{
            //    throw new BadRequestException(RequestEnum.IdHasExist);
            //}
            var userEntity = _userRepository.Get(q => q.mobile == request.mobile && q.status == (int)RowState.Valid);
            if (userEntity != null)
            {
                throw new BadRequestException(RequestEnum.UserIsExist);
            }

            var projectType = _projectTypeRepository.Get(request.typeid.ToInt());
            if (projectType == null || projectType.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);
            }

            var user = new siger_user
            {
                password = MD5Helper.Get32MD5(request.password),
                mobile = request.mobile,
                realname = request.realname,
                roleid = projectType.id,
                type = (int)UserType.Admin
            };
            _userRepository.Insert(user);
            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.SystemExcetion);
            }

            userEntity = _userRepository.Get(q => q.mobile == request.mobile && q.status == (int)RowState.Valid);
            var project = new siger_project
            {
                id = request.pid,
                title = request.title,
                typeid = request.typeid.ToInt(),
                description = request.description ?? "",
                companyid = request.companyid,
                salesmid = request.salesmid.ToInt(),
                initialquotation = request.initialquotation.ToInt(),
                finaloffer = request.finaloffer.ToInt(),
                dutymid = userEntity.id,
                mid = UserId,
                ip = ServerIpAddress,
                modular = request.modular,
                dashboard_ids = request.dashboard_ids,
                createtime = UnixTimeHelper.GetNow(),
            };
            _projectRepository.Insert(project);
            if (_unitOfWork.Commit() <= 0)
            {
                _userRepository.Delete(userEntity.id);
                _unitOfWork.Commit();
                return new ObjectResult(CommonEnum.SystemExcetion);
            }
            else
            {
                //todo:create dbConnect
                InitDbConfig config = new InitDbConfig();
                var cid = int.Parse(request.companyid);
                config.InitDb(cid, project.id);
                config.InitTable(cid, project.id);
                _sqlRepository.InitQmsData(project.id);//初始化qms模块表数据
                _sqlRepository.InitTpmData(project.id);//初始化tpm模块表数据
            }


            var projectEn = _projectRepository.Get(q => q.companyid == request.companyid
                                                            && q.title == request.title && q.status == (int)RowState.Valid);
            var puser = new siger_project_user
            {
                mid = userEntity.id,
                projectid = projectEn.id,
                name = request.realname,
                create_time = UnixTimeHelper.GetNow()
            };
            _projectUserRepository.Insert(puser);
            if (_unitOfWork.Commit() <= 0)
            {
                _projectRepository.Delete(projectEn.id);
                _userRepository.Delete(userEntity.id);
                _unitOfWork.Commit();
                throw new BadRequestException(CommonEnum.SystemExcetion);
            }

            //var sql = RedisCache.Client.Get("DBCreateSql");
            //if (!string.IsNullOrWhiteSpace(sql))
            //{
            //    var pid = projectEn.id;
            //    var cid = project.companyid.ToInt();

            //    var projectRepository = new ProjectRepository(cid, pid);
            //    if (!projectRepository.InitDataBase($"{cid}_{pid}"))
            //    {
            //        throw new BadRequestException(RequestEnum.CreateDbFailed);
            //    }
            //    if (!projectRepository.InitTables(sql))
            //    {
            //        throw new BadRequestException(RequestEnum.CreateTablesFailed);
            //    }
            //}

            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpGet]
        public IActionResult GetProjectItem(int id)
        {
            var project = _projectRepository.GetProject(id);
            if (project == null)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            return new ObjectResult(project);
        }

        [HttpPost]
        public IActionResult EditProject([FromBody] RequestUpdateProject request)
        {
            if (request.is_password.ToInt() == 0)
            {
                if (string.IsNullOrWhiteSpace(request.password))
                {
                    throw new BadRequestException(RequestEnum.PasswordIsEmpty);
                }
            }
            var project = _projectRepository.Get(request.id);
            if (project == null || project.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            var user = _userRepository.Get(request.dutymid);
            if (user == null || user.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserNotFound);
            }

            var projectUser = _projectUserRepository.Get(q => q.mid == request.dutymid);
            if (projectUser == null || projectUser.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectUserNotFound);
            }
            var userEntity = _userRepository.Get(q => q.mobile == request.mobile && q.id != user.id && q.status == (int)RowState.Valid);
            if (userEntity != null)
            {
                throw new BadRequestException(RequestEnum.MobileHasExist);
            }

            var projectEntity = _projectRepository.Get(q => q.companyid == request.companyid
                                                            && q.title == request.title && q.id != project.id && q.status == (int)RowState.Valid);
            if (projectEntity != null)
            {
                throw new BadRequestException(RequestEnum.ProjectIsExist);
            }
            var projectType = _projectTypeRepository.Get(request.typeid.ToInt());
            if (projectType == null || projectType.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);
            }
            project.title = request.title;
            project.typeid = request.typeid.ToInt();
            project.description = request.description;
            project.companyid = request.companyid;
            project.salesmid = request.salesmid.ToInt();
            project.initialquotation = request.initialquotation.ToInt();
            project.finaloffer = request.finaloffer.ToInt();
            project.createtime = UnixTimeHelper.GetNow();
            project.ip = ServerIpAddress;
            project.modular = request.modular;
            project.dashboard_ids = request.dashboard_ids;
            _projectRepository.Update(project);

            user.mobile = request.mobile;
            user.realname = request.realname;
            user.roleid = projectType.id;
            if (request.is_password.ToInt() != 1)
            {
                user.password = MD5Helper.Get32MD5(request.password);
            }
            _userRepository.Update(user);

            projectUser.name = request.realname;
            _projectUserRepository.Update(projectUser);

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

        [HttpPost]
        public IActionResult DeleteProject(int id)
        {
            var project = _projectRepository.Get(id);
            if (project == null || project.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            project.status = (int)RowState.Invalid;
            _projectRepository.Update(project);
            var users = _projectUserRepository.GetList(f => f.projectid == id);
            foreach(var user in users)
            {
                user.status = (int)RowState.Invalid;
                _projectUserRepository.Update(user);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetProjectName()
        {
            var project = _projectRepository.Get(ProjectId);
            if (project == null || project.status != (int)RowState.Valid)
            {
                return new ObjectResult(string.Empty);
            }

            return new ObjectResult(new ResponseProjectName
            {
                Cid = project.companyid,
                Pid = project.id,
                Description = project.description,
            });
        }

        [HttpGet]
        public IActionResult GetModuleByName(string module)
        {
            var project = _projectRepository.Get(ProjectId);
            if (project == null)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }
            if (!string.IsNullOrWhiteSpace(project.modular) && project.modular.Contains(module.ToLower()))
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            return new ObjectResult(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetAppModules()
        {
            var project = _projectRepository.Get(ProjectId);
            if (project == null)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }
            var responses = new List<string>();

            var parentPower = _powerRepository.Get(q => q.status == (int)RowState.Valid && q.type == (int)PowerType.App);
            if (parentPower == null)
            {
                return new ObjectResult(responses);
            }

            var powerModel = _userRepository.GetModulePowers(UserId, ProjectId, parentPower.id.ToString()).Where(q => q.type == (int)PowerType.App).ToList();
            foreach (var power in powerModel.Where(q => q.parent == "0"))
            {
                responses.Add(power.value);
            }

            return new ObjectResult(responses);
        }

        [HttpGet]
        public IActionResult GetModules()
        {
            var project = _projectRepository.Get(ProjectId);
            if (project == null)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            var modules = project.modular;
            if (!string.IsNullOrWhiteSpace(modules))
            {
                return new ObjectResult(modules.Split(',').ToList());
            }

            return new ObjectResult(new List<string>());
        }

        [HttpGet]
        public IActionResult GetAllDashboards()
        {
            return new ObjectResult(_projectRepository.GetAllDashboards());
        }

        /// <summary>
        /// 查询项目 人员
        /// </summary>
        /// <param name="type"> 0：项目负责人 1, 项目销售</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetUser(int type)
        {
            var data = _projectRepository.GetProjectUser(type).Distinct().ToList();
            return new ObjectResult(data);
        }
    }
}