using System;
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.Repository;
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 DashboardSetController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IDashboardProjectConfigRepository _dashboardProjectConfigRepository;
        private readonly IDashboardPageRepository _dashboardPageRepository;
        private readonly IDashboardPagePatialRepository _dashboardPagePatialRepository;
        private readonly IDashboardPagePatialConditionRepository _dashboardPagePatialConditionRepository;

        public DashboardSetController(IUnitOfWork unitOfWork, IDashboardProjectConfigRepository dashboardProjectConfigRepository, 
            IDashboardPageRepository dashboardPageRepository, IDashboardPagePatialRepository dashboardPagePatialRepository,
            IDashboardPagePatialConditionRepository dashboardPagePatialConditionRepository)
        {
            _unitOfWork = unitOfWork;
            _dashboardProjectConfigRepository = dashboardProjectConfigRepository;
            _dashboardPageRepository = dashboardPageRepository;
            _dashboardPagePatialRepository = dashboardPagePatialRepository;
            _dashboardPagePatialConditionRepository = dashboardPagePatialConditionRepository;
        }

        [HttpGet]
        public IActionResult GetDashboardPages(string name, int page = PageIndex, int pagesize = PageSize)
        {
            var data = _dashboardPageRepository.GetPagedDashPagedCollection(name, page, pagesize);
            return new PagedObjectResult(data.Data, data.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult AddDashboardPage([FromBody]RequestAddDashboardPage request)
        {
            if (request.pages == null || !request.pages.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            var isTitleExist = _dashboardPageRepository.Get(q => q.page_title == request.title && q.status == (int) RowState.Valid);
            if (isTitleExist != null)
            {
                throw new BadRequestException(RequestEnum.TitleHasExist);
            }
            var isCodeExist = _dashboardPageRepository.Get(q => q.page_code == request.code && q.status == (int)RowState.Valid);
            if (isCodeExist != null)
            {
                throw new BadRequestException(RequestEnum.CodeHasExist);
            }

            var page = new siger_project_dashboard_page
            {
                page_title = request.title,
                page_code = request.code,
                img_url = request.image,
                page_description = request.code,
                status = (int)RowState.Valid
            };
            _dashboardPageRepository.Insert(page);

            var pages = request.pages.ToList();
            for (var i = 0; i < pages.Count; i++)
            {
                var requestPage = pages[i];
                var index = i + 1;

                var pagePatial = new siger_project_dashboard_page_patial
                {
                    page_code = request.code,
                    page_patial_code = request.code + index,
                    x = requestPage.x.ToInt(),
                    y = requestPage.y.ToInt(),
                    w = requestPage.w.ToInt(),
                    h = requestPage.h.ToInt(),
                    status = (int)RowState.Valid
                };
                _dashboardPagePatialRepository.Insert(pagePatial);

                var condition = new siger_project_dashboard_page_patial_condition
                {
                    page_patial_code = request.code + index,
                    page_patial_condition_code = request.code + index + "_1",
                    type = requestPage.type,
                    des = requestPage.descrption,
                    status = (int)RowState.Valid
                };
                _dashboardPagePatialConditionRepository.Insert(condition);
            }

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

        [HttpGet]
        public IActionResult GetDashboardPage(int id)
        {
            return new ObjectResult(_dashboardPageRepository.GetDashPaged(id));
        }

        [HttpPost]
        public IActionResult UpdateDashboardPage([FromBody] RequestUpdateDashboardPage request)
        {
            return new ObjectResult(CommonEnum.Succefull);
        }

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

            entity.status = (int) RowState.Invalid;
            _dashboardPageRepository.Update(entity);

            var pagePatials = _dashboardPagePatialRepository.GetList(q =>
                q.page_code == entity.page_code && q.status == (int) RowState.Valid);
            foreach (var pagePatial in pagePatials.ToList())
            {
                _dashboardPagePatialRepository.Delete(pagePatial);

                var conditions = _dashboardPagePatialConditionRepository.GetList(q =>
                    q.page_patial_code == pagePatial.page_patial_code && q.status == (int) RowState.Valid);
                foreach (var condition in conditions.ToList())
                {
                    _dashboardPagePatialConditionRepository.Delete(condition);
                }
            }

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

        [HttpPost]
        public IActionResult SetProjectDashboardPages([FromBody]RequestSetProjectDashboardPage request)
        {
            var entities = _dashboardProjectConfigRepository.GetList(q => q.project_id == request.projectId).ToList();
            foreach (var config in entities)
            {
                _dashboardProjectConfigRepository.Delete(config);
            }

            var ids = request.page_ids.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
            foreach (var id in ids)
            {
                var entity = new siger_project_dashboard_project_config
                {
                    project_id = request.projectId,
                    dashboard_page_id = id.ToInt(),
                    status = (int) RowState.Valid
                };
                _dashboardProjectConfigRepository.Insert(entity);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetProjectDashboardPages(int projectId)
        {
            var pageIds = _dashboardProjectConfigRepository.GetList(q => q.status == (int)RowState.Valid && q.project_id == projectId)
                .Select(m => m.dashboard_page_id).ToList();

            var pages = _dashboardPageRepository.GetList(q => q.status == (int) RowState.Valid);
            var responses = new List<siger_project_dashboard_page>();
            if (pageIds.Any())
            {
                foreach (var page in pages)
                {
                    if (pageIds.Contains(page.id))
                    {
                        responses.Add(page);
                    }
                }
            }

            return new ObjectResult(responses);
        }

        [HttpGet]
        public IActionResult GetAllDashboardPages()
        {
            var pages = _dashboardPageRepository.GetList(q => q.status == (int) RowState.Valid).ToList()
                .Select(m => new ResponseIdTitle
                {
                    id = m.id,
                    title = m.page_description
                });
            return new ObjectResult(pages);
        }
    }
}