using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using Wierszowki.Core.Interfaces;
using Wierszowki.Core.Linq;
using Wierszowki.Models;

namespace Wierszowki.Controllers
{
    [Authorize]
    [HandleError]
    public class ReportController : Controller
    {
        private readonly IRepository<MagazineItem> _repository;

        private readonly WierszowkiDataContext _context;

        public ReportController()
        {
            _context = new WierszowkiDataContext();
            _repository = new LinqRepository<MagazineItem>();
        }

        public ReportController(IRepository<MagazineItem> repository, WierszowkiDataContext dataContext)
        {
            _repository = repository;
            _context = dataContext;
        }

        public ActionResult Index()
        {
            var viewData = new ReportViewData
                               {
                                   Authors = _context.GetAuthors().OrderBy(a => a.FullName).ToList()
                               };
            return View(viewData);
        }

        public ActionResult All(int year, int month, int user)
        {
            var items = _repository.Find(m => m.Date.Month == month && m.Date.Year == year && m.CreatedBy == user)
                                   .OrderByDescending(m => m.UpdatedOn).ToList();
            return View(items);
        }

        public ActionResult ToPrice()
        {
            var items = _repository.Find(m => m.Price <= 0).ToList();
            return View("All", items);
        }

        public ActionResult Show(int year, int month, int employment)
        {
            var magazineItems = _context.FindItemsByYearMonthAndEmploymentType(year, month, employment);
            return View(magazineItems);
        }

        public ActionResult AuthorCard(int year, int month, int author)
        {
            var magazineItems = _context.FindItemsByYearMonthAndAuthor(year, month, author);
            if (magazineItems.Count() <= 0)
                return RedirectToAction("AuthorCardNotFound", _context.Authors.SingleOrDefault(a => a.Id == author));
            
            var viewData = new AuthorCardViewData
                               {
                                   FullName = magazineItems[0].Author.FullName,
                                   Date = magazineItems[0].Date,
                                   MagazineItems = new Dictionary<string, List<MagazineItem>>()
                               };
            foreach (var magazineItem in magazineItems)
            {
                var key = magazineItem.Issue.Magazine.NickName;
                if (!viewData.MagazineItems.ContainsKey(key))
                {
                    viewData.MagazineItems[key] = new List<MagazineItem>();
                }
                viewData.MagazineItems[key].Add(magazineItem);
                viewData.Price += magazineItem.Price;
                viewData.Bonus += magazineItem.Bonus;
                viewData.Total += magazineItem.Price + magazineItem.Bonus;
            }
            return View(viewData);
        }

        public ActionResult AuthorCardNotFound(Author author)
        {
            return View(author);
        }

        public ActionResult Authors(int year, int month)
        {
            ViewData["ReportDate"] = new DateTime(year, month, 1);
            var reports = _context.GetAuthorsReport(year, month);
            return View(reports);
        }

        public ActionResult AuthorsByMagazines(int year, int month)
        {
            var viewData = new ReportViewData();
            viewData.ReportDate = new DateTime(year, month, 1);
            viewData.Authors = _context.GetAuthors();
            viewData.Magazines = _context.GetMagazines();
            viewData.ReportData = _context.GetAuthorsByMagzinesReport(year, month, viewData.Authors, viewData.Magazines);
            return View(viewData);
        }

        public ActionResult AuthorsByMagazinesByEmployment(int year, int month, int? employment)
        {
            var employmentId = employment.HasValue ? employment.Value : 1;

            var viewData = new ReportViewData();
            viewData.ReportDate = new DateTime(year, month, 1);
            viewData.Employment = _context.EmploymentTypes.SingleOrDefault(e => e.Id == employmentId);
            viewData.Authors = _context.GetAuthors().Where(a => a.EmploymentType == viewData.Employment).ToList();
            viewData.Magazines = _context.GetMagazines();
            viewData.ReportData = _context.GetAuthorsByMagzinesReport(year, month, viewData.Authors, viewData.Magazines);
            return View("AuthorsByMagazines", viewData);
        }
    }
}