﻿using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Results;
using JetBrains.Annotations;
using Microsoft.Owin;
using Server.DAL.Abstract;
using Server.DAL.Entities;
using Server.WebApi.Infrastructure;

namespace Server.WebApi.Controllers
{
    [Authorize(Roles = nameof(UserRole.Admin))]
    public class SurveyStatisticsController : ApiController
    {
        private readonly IDbSurveyRepository _surveyRepository;
        private readonly IDbUsersRepository _usersRepository;


        public SurveyStatisticsController([NotNull] IDbSurveyRepository surveyRepository,
            [NotNull] IDbUsersRepository usersRepository)
        {
            _surveyRepository = surveyRepository;
            _usersRepository = usersRepository;
        }


        public async Task<object> GetUsersSurveyStats(int id, [FromUri] int userId)
        {
            IOwinContext owin = Request.GetOwinContext();
            int? selfId = owin.GetUserId();

            Survey survey = await _surveyRepository.Surveys
                .FirstOrDefaultAsync(x => x.SurveyId == id);

            if (survey.OwnerId != selfId)
            {
                return new StatusCodeResult(HttpStatusCode.Forbidden, this);
            }

            return survey.Answers
                .First(x => x.UserId == userId)
                .QuestionAnswers
                .GroupBy(x => x.Question.PageId)
                .Select(x => x.Select(SurveyStatsHelper.GetUserStats)
                    .ToList())
                .ToList();
        }

        public async Task<object> GetTextAnswers(int id, [FromUri] int page)
        {
            IOwinContext owin = Request.GetOwinContext();
            int? selfId = owin.GetUserId();

            Question question = await _surveyRepository.PageQuestions
                .FirstOrDefaultAsync(x => x.QuestionId == id);

            if (question.Page.Survey.OwnerId != selfId)
            {
                return new StatusCodeResult(HttpStatusCode.Forbidden, this);
            }

            IEnumerable<QuestionAnswer> surveyAnswers = _surveyRepository.QuestionAnswers
                .Where(z => z.QuestionId == question.QuestionId);

            return SurveyStatsHelper.GetTextQuestionAnswers(question, surveyAnswers, page);
        }

        public async Task<object> GetSurveyStats(int id)
        {
            IOwinContext owin = Request.GetOwinContext();
            int? selfId = owin.GetUserId();

            Survey survey = await _surveyRepository.Surveys
                .FirstOrDefaultAsync(x => x.SurveyId == id);

            if (survey.OwnerId != selfId)
            {
                return new StatusCodeResult(HttpStatusCode.Forbidden, this);
            }

            List<List<object>> surveyStatistics = survey.Pages
                .OrderBy(x => x.Order)
                .Select(x => x.Questions
                    .OrderBy(y => y.Order)
                    .Select(y => SurveyStatsHelper.GetSurveyStats(survey, y))
                    .ToList())
                .ToList();

            string[] pageNames = survey.Pages
                .OrderBy(x => x.Order)
                .Select(x => x.Name)
                .ToArray();

            return new
                {
                    stats = surveyStatistics,
                    name = survey.Name,
                    pages = survey.Pages.Count,
                    pageNames,
                    questions = survey.Pages.Sum(x => x.Questions.Count)
                };
        }

        public async Task<object> GetUserNames(string name)
        {
            return await _usersRepository.Users
                .Where(x => x.Name.StartsWith(name))
                .Take(10)
                .Select(x => new
                    {
                        label = x.Name,
                        value = x.UserId
                    })
                .ToListAsync();
        }
    }
}