using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using AutoMapper;
using Qusion.Cms.Classifications;
using Qusion.Cms.Classifications.Core;
using Qusion.Cms.Web.Http;
using Qusion.WebApp.Areas.Qusion.Filters;
using Qusion.WebApp.Areas.Qusion.Models.Classifications;
using Qusion.WebApp.Areas.Qusion.Models.Pages;
using Qusion.WebApp.Areas.Qusion.Models.Validation;
using Qusion.Framework.Configuration;
using Qusion.WebApp.Areas.Qusion.Helpers;

namespace Qusion.WebApp.Areas.Qusion.Controllers.Api
{
  [Authorize]
    public class LabelController : ApiController
    {
        private readonly LabelService _labelService;

        public LabelController(LabelService labelService)
        {
            _labelService = labelService;
        }

        [HttpGet]
        public PageResult<LabelListModel> Query([FromUri] LabelQueryInput input)
        {
           LabelQuery query = Mapper.Map(input, LabelQuery.Default) ?? LabelQuery.Default;
                IEnumerable<Label> labels = _labelService.Search(query);
                var a = labels.ToList().Where(x => x.Name != null);
                IList<LabelListModel> model = Mapper.Map<IList<Label>, IList<LabelListModel>>(a.ToList());

                return new PageResult<LabelListModel>
                {
                    Items = model,
                    Count = query.Paging.TotalCount
                };
            
        }

        /// <summary>
        ///   Gets list of top pages.
        /// </summary>
        /// <returns> </returns>
        [HttpGet]
        public PageResult<LabelListModel> Top(string alias, Guid? parentID = null)
        {
              IList<Label> labels;
                if (parentID.HasValue)
                {
                    var label = _labelService.GetById(parentID.Value);
                    labels = label != null ? label.Children : new List<Label>();
                }
                else
                {
                    var tree = _labelService.GetTopLabels(alias);
                    labels = _labelService.SortByOrdinal(tree).ToList();
                }
                var a = labels.ToList().Where(x => x.Name != null);
                var model = Mapper.Map<IList<Label>, IList<LabelListModel>>(a.ToList());

                return new PageResult<LabelListModel>
                {
                    Items = model,
                    Count = labels.Count
                };
            
        }

        [HttpGet]
        public HttpResponseMessage Get(Guid id)
        {
            Label label = _labelService.GetById(id);

                return label != null
                           ? Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Label, LabelModel>(label))
                           : Request.CreateResponse(HttpStatusCode.NotFound);
            
        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public LabelModel Create(LabelCreateInput label)
        {
            
                var newLabel = new Label { };
                Mapper.Map(label, newLabel);
                _labelService.Save(newLabel);
                return Mapper.Map<Label, LabelModel>(newLabel);

        }

        [HttpGet]
        public LabelModel GetEdit(Guid id)
        {
            Label label = _labelService.GetByIdForEditing(id);
            return Mapper.Map<Label, LabelModel>(label);
        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage Edit(LabelEditInput label)
        {
           
                var newLabel = _labelService.GetById(label.ID);
                if (newLabel == null)
                    return Request.CreateResponse(HttpStatusCode.NotFound);
                Mapper.Map(label, newLabel);
                _labelService.Save(newLabel);
                return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Label, LabelModel>(newLabel));

        }

        [HttpPost]
        public HttpResponseMessage Reorder(LabelReorderListModel model)
        {
            ReorderLabel(model.Labels, null);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        private void ReorderLabel(IEnumerable<LabelReorderModel> labels, Label parent)
        {
            var index = 1;
            foreach (var label in labels)
            {
                var current = _labelService.GetById(new Guid(label.ID));
                current.Parent = null;
                current.Ordinal = index++;
                _labelService.Save(current);
                if (parent != null)
                {
                    current.Parent = parent;
                    _labelService.Save(parent);
                }
                if (label.Children.Count > 0)
                {
                    ReorderLabel(label.Children, current);
                }
            }
        }

        [HttpGet]
        public HttpResponseMessage Delete(Guid id)
        {
            var errors = new Dictionary<string, string[]>();


            Label label = _labelService.GetById(id);

            if (label == null)
                return Request.CreateResponse(HttpStatusCode.NotFound);

            if (label.Children.Count > 0)
                errors.Add("removeChildError", new[] { "classifications.child_label_first" });

            if (errors.Count == 0)
            {
                try
                {
                    _labelService.Delete(label);
                    return Request.CreateResponse(HttpStatusCode.OK);
                }
                catch (Exception e)
                {
                    errors.Add("removeError", new[] { "classifications.not_possible_delete" });
                }
            }
            return Request.CreateResponse(HttpStatusCode.OK, new { Errors = errors });
        }


    }
}