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;
using ShiftInfo = Siger.Middlelayer.Repository.Data.ShiftInfo;

namespace Siger.ApiConfig.Controller
{
    public class ProjectShiftController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectShiftRepository _projectShiftRepository;
        public ProjectShiftController(IUnitOfWork unitOfWork, ISigerProjectShiftRepository projectShiftRepository)
        {
            _unitOfWork = unitOfWork;
            _projectShiftRepository = projectShiftRepository;
        }

        [HttpGet]
        public IActionResult ShiftList(string id, int page = 1, int pagesize = PageSize)
        {
            var reponse = new List<ResponseGetShift>();
            var list = _projectShiftRepository.GetShifts(id.ToInt(), ProjectId, page, pagesize);

            foreach (var shift in list.Data)
            {
                var responseShift = Mapper<Shift, ResponseGetShift>.Map(shift);
                responseShift.start_time = UnixTimeHelper.GetTimeByUnix(shift.start_time.ToInt());
                responseShift.end_time = UnixTimeHelper.GetTimeByUnix(shift.end_time.ToInt());
                responseShift.create_time = UnixTimeHelper.ConvertStringDateTime(shift.create_time)
                    .ToString(ParameterConstant.DateTimeFormat);

                reponse.Add(responseShift);
            }
            return new PagedObjectResult(reponse, list.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult GetShiftInfo(int id)
        {
            var entity = _projectShiftRepository.GetShiftInfo(id);
            if (entity == null)
            {
                throw new BadRequestException(RequestEnum.ShiftNotFound);
            }

            var response = Mapper<ShiftInfo, ResponseGetShiftInfo>.Map(entity);

            response.startTime = UnixTimeHelper.GetTimeByUnix(entity.start_time);
            response.endTime = UnixTimeHelper.GetTimeByUnix(entity.end_time);

            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetAllShiftLists()
        {
            var titles = new List<ResponseIdTitle>();
            var list = _projectShiftRepository
                .GetList(q => q.status == (int)RowState.Valid && q.projectid == ProjectId)
                .Distinct();
            foreach (var shift in list)
            {
                titles.Add(new ResponseIdTitle { id = shift.id, title = shift.title });
            }
            return new ObjectResult(titles);
        }

        [HttpGet]
        public IActionResult GetShiftListsBySectionid(int id)
        {
            var response = new List<ResponseGetShiftListsBySectionid>();

            var shifts = _projectShiftRepository.GetList(q => q.sectionid == id && q.projectid == ProjectId && q.status == (int)RowState.Valid);

            foreach (var sigerProjectShift in shifts)
            {
                response.Add(Mapper<siger_project_shift, ResponseGetShiftListsBySectionid>.Map(sigerProjectShift));
            }

            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult AddShift([FromBody] ResponseAddShift request)
        {
            var startTime = UnixTimeHelper.GetUnixTime(request.start_time);
            var endTime = UnixTimeHelper.GetUnixTime(request.end_time);
            var isExist = _projectShiftRepository.IsExist(q =>
                q.title == request.title && q.projectid == ProjectId
                                         && q.sectionid == request.sectionid.ToInt()
                                         && q.status == (int)RowState.Valid
                                         && q.start_time == startTime
                                         && q.end_time == endTime);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.TitleHasExist);
            }
            var shift = new siger_project_shift();
            shift.projectid = ProjectId;
            shift.sectionid = request.sectionid.ToInt();
            shift.title = request.title;
            shift.description = request.description;
            shift.start_time = startTime;
            shift.end_time = endTime;
            shift.create_time = UnixTimeHelper.GetNow();
            shift.create_mid = UserId;
            _projectShiftRepository.Insert(shift);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult EditShift([FromBody] ResponseUpdateShift request)
        {
            var shift = _projectShiftRepository.Get(request.id);
            if (shift == null || shift.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ShiftNotFound);
            }
            var isExist = _projectShiftRepository.IsExist(q => q.title == request.title
                                                               && q.projectid == ProjectId
                                                               && q.sectionid == request.sectionid.ToInt()
                                                               && q.status == (int)RowState.Valid
                                                               && q.start_time == request.start_time.ToInt()
                                                               && q.end_time == request.end_time.ToInt()
                                                               && q.id != shift.id);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.TitleHasExist);
            }
            shift.title = request.title;
            shift.description = request.description;
            shift.sectionid = request.sectionid.ToInt();
            shift.start_time = UnixTimeHelper.GetUnixTime(request.start_time);
            shift.end_time = UnixTimeHelper.GetUnixTime(request.end_time);

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

        [HttpPost]
        public IActionResult DeleteShift(int id)
        {
            var entity = _projectShiftRepository.Get(id);
            if (entity == null || entity.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ShiftNotFound);
            }

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

        [HttpGet]
        public IActionResult GetSectionShiftBySectionId(int sectionid)
        {
            var response = new List<ResponseGetSectionShiftBySectionId>();
            var shifts = _projectShiftRepository.GetList(q => q.status == (int)RowState.Valid && q.sectionid == sectionid);
            foreach (var shift in shifts)
            {
                response.Add(new ResponseGetSectionShiftBySectionId
                {
                    id = shift.id,
                    sectionid = shift.sectionid,
                    start_time = shift.start_time,
                    end_time = shift.end_time,
                    title = $"{shift.title}&nbsp;&nbsp;&nbsp;&nbsp;{UnixTimeHelper.GetTimeByUnix(shift.start_time)}--{UnixTimeHelper.GetTimeByUnix(shift.end_time)}"
                });
            }
            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetSectionShiftUserLists(int sectionid, int shiftid, int departmentid)
        {
            var list = _projectShiftRepository.GetSectionShiftUserLists(sectionid, shiftid, departmentid, ProjectId);

            return new ObjectResult(list);
        }


        [HttpGet]
        public IActionResult GetAllFrequency()
        {
            var response = new List<ResponseGetAllType>();
            var shifts = _projectShiftRepository.GetList(q => q.status == (int)RowState.Valid && q.projectid == ProjectId);
            foreach (var shift in shifts)
            {
                response.Add(new ResponseGetAllType
                {
                    id = shift.id,
                    title = shift.title + "：" + UnixTimeHelper.GetTimeByUnix(shift.start_time) + "--" + UnixTimeHelper.GetTimeByUnix(shift.end_time)
                });
            }
            return new ObjectResult(response);
        }
    }
}