using System;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.CncRepository.Request;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Repositories.Interface;

namespace Siger.ApiCNC.Controllers
{
    public class MachineStatusTimeSettingController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMachineStatusTimeSettingRepository _settingRepository;
        private readonly ISigerProjectMachineTypeRepository _machineTypeRepository;
        public MachineStatusTimeSettingController(IUnitOfWork unitOfWork, IMachineStatusTimeSettingRepository settingRepository,
            ISigerProjectMachineTypeRepository machineTypeRepository)
        {
            _unitOfWork = unitOfWork;
            _settingRepository = settingRepository;
            _machineTypeRepository = machineTypeRepository;
        }

        [HttpGet]
        public IActionResult GetTimeSettingList(string parentTypeId, string childTypeId, int page = 1, int pagesize = 10)
        {
            var parentId = parentTypeId.ToInt();
            var childId = childTypeId.ToInt();
            Expression<Func<siger_project_machine_status_timesetting, bool>> defaultExpression = q => q.projectId == ProjectId && q.status == (int)RowState.Valid;
            Expression<Func<siger_project_machine_status_timesetting, bool>> fTypeExpression = q => true;
            Expression<Func<siger_project_machine_status_timesetting, bool>> cTypeExpression = q => true;
            if (parentId != 0)
            {
                fTypeExpression = q => q.parentTypeId == parentId;
            }
            if (childId != 0)
            {
                cTypeExpression = q => q.childTypeId == childId;
            }

            var expression = defaultExpression.And(fTypeExpression).And(cTypeExpression);

            var query = _settingRepository.GetPagedList(page, pagesize, expression);
            return new PagedObjectResult(query.Data, query.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult AddTimeSetting([FromBody] RequestAddTimeSetting request)
        {
            var ftype = request.parentTypeId.ToInt();
            var ctype = request.childTypeId.ToInt();

            var entity = _settingRepository.Get(q => q.projectId == ProjectId  &&
                q.childTypeId == ctype && q.parentTypeId == ftype && q.status == (int)RowState.Valid);
            if (entity != null)
            {
                throw new BadRequestException(CncEnum.TimeSettingHasExist, request);
            }

            var ptype = _machineTypeRepository.GetMachineType(ftype);
            if (ptype == null)
            {
                throw new BadRequestException(RequestEnum.MachineTypeNotFound);
            }
            var cType = _machineTypeRepository.GetMachineType(ctype);
            if (cType == null)
            {
                throw new BadRequestException(RequestEnum.MachineTypeNotFound);
            }
            var mode = new siger_project_machine_status_timesetting
            {
                childTypeId = ctype,
                parentTypeId = ftype,
                projectId = ProjectId,
                add_time = UnixTimeHelper.GetNow(),
                childTypeName = cType.title,
                parentTypeName = ptype.title,
                free = request.free,
                fault = request.fault,
                debugging = request.debugging
            };
            _settingRepository.Insert(mode);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetTimeSetting(int id)
        {
            var mode = _settingRepository.Get(id);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            return new ObjectResult(mode);
        }

        [HttpPost]
        public IActionResult EditTimeSetting([FromBody]RequestEditTimeSetting request)
        {
            var mode = _settingRepository.Get(request.id);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            mode.free = request.free;
            mode.fault = request.fault;
            mode.debugging = request.debugging;
            mode.edit_time = UnixTimeHelper.GetNow();
            _settingRepository.Update(mode);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteTimeSetting(int id)
        {
            var mode = _settingRepository.Get(id);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

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

        [HttpPost]
        public IActionResult DeleteTimeSettings(string ids)
        {
            if (string.IsNullOrWhiteSpace(ids))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            foreach (var id in ids.Split(','))
            {
                var mode = _settingRepository.Get(id.ToInt());
                if (mode == null || mode.status != (int) RowState.Valid)
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }

                mode.status = (int) RowState.Invalid;
                _settingRepository.Update(mode);
            }

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