using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json.Linq;
using AyaNova.Models;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Biz;


namespace AyaNova.Api.Controllers
{

    /// <summary>
    /// Log files controller
    /// </summary>
    [ApiVersion("8.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [Authorize]
    public class EventLogController : Controller
    {
        private readonly AyContext ct;
        private readonly ILogger<LogFilesController> log;
        private readonly ApiServerState serverState;


        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="dbcontext"></param>
        /// <param name="logger"></param>
        /// <param name="apiServerState"></param>
        public EventLogController(AyContext dbcontext, ILogger<LogFilesController> logger, ApiServerState apiServerState)
        {
            ct = dbcontext;
            log = logger;
            serverState = apiServerState;
        }




        /// <summary>
        /// Get event log for object and date range specified
        /// 
        /// Required roles:
        /// Read rights to object type specified
        /// 
        /// </summary>        
        /// <returns>Event log entry list for object</returns>
        [HttpGet("ObjectLog")]
        public async Task<IActionResult> GetObjectLog([FromQuery] EventLogOptions opt)
        {
            if (serverState.IsClosed)
            {
                return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
            }

            if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, opt.AyType))
            {
                return StatusCode(401, new ApiNotAuthorizedResponse());
            }

            var result = await EventLogProcessor.GetLogForObject(opt, ct);
            return Ok(new ApiOkResponse(result));
        }



        /// <summary>
        /// Get event log entries for a specified user and date range
        /// 
        /// Required roles:
        /// Read rights to User object or UserId specified must be requestor Id
        /// 
        /// </summary>        
        /// <returns>Event log for user</returns>
        [HttpGet("UserLog")]
        public async Task<IActionResult> GetUserLog([FromQuery] EventLogOptions opt)
        {
            if (serverState.IsClosed)
            {
                return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
            }

            if (opt.AyType != AyaType.User)
            {
                //return bad request
                return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, "AyType", "User type required"));
            }

            long UserId = UserIdFromContext.Id(HttpContext.Items);

            //If not authorized to read a user and also not the current user asking for their own log then NO LOG FOR YOU!
            if (!Authorized.IsAuthorizedToReadFullRecord(HttpContext.Items, AyaType.User) && opt.AyId != UserId)
            {
                return StatusCode(401, new ApiNotAuthorizedResponse());
            }

            var result = await EventLogProcessor.GetLogForUser(opt, ct);

             return Ok(new ApiOkResponse(result));
        }




        //------------


        public sealed class EventLogOptions
        {
            [FromQuery]
            public AyaType AyType { get; set; }
            [FromQuery]
            public long AyId { get; set; }
            [FromQuery]
            public DateTime? StartDate { get; set; }
            [FromQuery]
            public DateTime? EndDate { get; set; }
        }



        public sealed class ObjectEventLogItem
        {
            //DateTime, UserId, Event, Textra           
            public DateTime Date { get; set; }
            public long UserId { get; set; }
            public AyaEvent Event { get; set; }
            public string Textra { get; set; }
        }

        public sealed class UserEventLogItem
        {
            //DateTime, ObjectType, ObjectId, Event, Textra       
            public DateTime Date { get; set; }
            public AyaType ObjectType { get; set; }
            public long ObjectId { get; set; }
            public AyaEvent Event { get; set; }
            public string Textra { get; set; }
        }


    }//eoc
}//eons