using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
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.Entities;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;

namespace Siger.ApiConfig.Controller
{
    public class ParameterController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectParameterRepository _parameterRepository;
        private readonly ISigerProjectParameterExtendRepository _extendRepository;
        public ParameterController(IUnitOfWork unitOfWork, ISigerProjectParameterRepository parameterRepository, ISigerProjectParameterExtendRepository extendRepository)
        {
            _unitOfWork = unitOfWork;
            _parameterRepository = parameterRepository;
            _extendRepository = extendRepository;
        }

        [HttpGet]
        public IActionResult GetPagedList(string name, string category, int page = 1, int pagesize = 10)
        {
            Expression<Func<siger_project_parameter, bool>> categoryExpression = q => q.status == (int)RowState.Valid && q.project_id == ProjectId && q.category == category;
            Expression<Func<siger_project_parameter, bool>> nameExpression = q => true;
            if (!string.IsNullOrWhiteSpace(name))
            {
                nameExpression = q => q.name.Contains(name);
            }
            var expression = categoryExpression.And(nameExpression);

            var response = new List<ResponseGetParameterList>();
            var query = _parameterRepository.GetPagedList(page, pagesize, expression, "name");
            var extends = _extendRepository.GetList(q =>
                query.Data.Select(m => m.id).Contains(q.parameter_id) && q.project_id == ProjectId &&
                q.status == (int) RowState.Valid);
            foreach (var para in query.Data)
            {
                var data = Mapper<siger_project_parameter, ResponseGetParameterList>.Map(para);
                if (data.type == 2)
                {
                    var extend = extends.Where(q => q.parameter_id == para.id);
                    if (extend.Any())
                    {
                        data.code = string.Join(',', extend.ToList().Select(m => m.value));
                    }
                }
                response.Add(data);
            }
            return new PagedObjectResult(response, query.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult Add([FromBody] RequestAddParameter request)
        {
            var isExist = _parameterRepository.GetList(q =>
                q.module == request.module && q.name == request.name && q.project_id == ProjectId
                && q.status == (int) RowState.Valid);
            if (isExist.Any())
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            if (request.type.ToInt() == 2) //下拉框
            {
                if (request.selectValue == null || !request.selectValue.Any())
                {
                    throw new BadRequestException(RequestEnum.ParameterError);
                }
            }

            var result = _parameterRepository.AddParameter(request.name, request.module, request.type, request.unit,
                request.category, request.code, request.selectValue, ProjectId, request.description);

            if (result)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetEntity(int id)
        {
            var entity = _parameterRepository.Get(q => q.id == id && q.status == (int)RowState.Valid);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var response = Mapper<siger_project_parameter, ResponseGetParameter>.Map(entity);
            if (response.type == 2) //下拉框
            {
                var extends = _extendRepository.GetList(q =>
                    q.parameter_id == entity.id && q.project_id == ProjectId && q.status == (int) RowState.Valid).ToList();
                foreach (var extend in extends)
                {
                    response.selectValue.Add(new RequestKeyValue
                    {
                        key = extend.key,
                        value = extend.value
                    });
                }
            }

            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult Edit([FromBody] RequestEditParameter request)
        {
            var isExist = _parameterRepository.GetList(q =>
                q.module == request.module && q.name == request.name && q.project_id == ProjectId
                && q.status == (int)RowState.Valid && q.id != request.id);
            if (isExist.Any())
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            var entity = _parameterRepository.Get(q => q.id == request.id && q.status == (int)RowState.Valid);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            if (request.type.ToInt() == 2) //下拉框
            {
                if (request.selectValue == null || !request.selectValue.Any())
                {
                    throw new BadRequestException(RequestEnum.ParameterError);
                }
            }

            entity.name = request.name;
            entity.category = request.category;
            entity.code = request.code.ToStr();
            entity.module = request.module;
            entity.unit = request.unit.ToStr();
            entity.description = request.description.ToStr();
            _parameterRepository.Update(entity);

            //修改下拉框
            if (entity.type == 2)
            {
                var extends = _extendRepository.GetList(q => q.parameter_id == entity.id && q.project_id == ProjectId && q.status == (int)RowState.Valid).ToList();
                foreach (var extend in extends)
                {
                    _extendRepository.Delete(extend);
                }
                foreach (var keyValue in request.selectValue)
                {
                    var extend = new siger_project_parameter_extend
                    {
                        project_id = ProjectId,
                        parameter_id = entity.id,
                        key = keyValue.key,
                        value = keyValue.value
                    };
                    _extendRepository.Insert(extend);
                }
            }

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

        /// <summary>
        /// 删除参数
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Delete(string id)
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }
            var ids = id.Split(',', StringSplitOptions.RemoveEmptyEntries);
            if (!ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }
            var entities = _parameterRepository.GetList(q => ids.Select(t => t.ToInt()).Contains(q.id) && q.status == (int)RowState.Valid &&
                q.project_id == ProjectId);
            if (!entities.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            foreach (var entity in entities)
            {
                entity.status = (int)RowState.Invalid;
                _parameterRepository.Update(entity);
            }

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

        [HttpGet]
        public IActionResult GetParamters(string category ,string search, string module)
        {
            var response = new List<ResponseGetParameterList>();
            var query = _parameterRepository.GetList(q => q.category == category && q.project_id == ProjectId && q.status == (int)RowState.Valid);
            if (!string.IsNullOrEmpty(module))
            {
                query = query.Where(q => q.module == module || q.module == $"{module}s");
            }
            var queryList = query.ToList();
            var extends = _extendRepository.GetList(q =>
                queryList.Select(m => m.id).Contains(q.parameter_id) && q.project_id == ProjectId &&
                q.status == (int)RowState.Valid).ToList();
            
            foreach (var para in queryList)
            {
                var data = Mapper<siger_project_parameter, ResponseGetParameterList>.Map(para);
                if (data.type == 2)
                {
                    var extend = extends.Where(q => q.parameter_id == para.id);
                    if (extend.Any())
                    {
                        data.code = string.Join(',', extend.ToList().Select(m => m.value));
                    }
                }
                response.Add(data);
            }

            if (!string.IsNullOrWhiteSpace(search))
            {
                response = response
                    .Where(t => t.unit.Contains(search) || t.code.Contains(search) || t.name.Contains(search)).ToList();
            }
            return new ObjectResult(response);
        }
    }
}