﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Cbn.Lib.Authentication;
using Cbn.Lib.Web.Authentication;
using System.Threading;
using System.Web;

namespace Cbn.Lib.Web.Filters
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class ApiAuthenticationFilterAttribute : ActionFilterAttribute
    {
        public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            var requestScope = actionContext.Request.GetDependencyScope();
            var service = requestScope.GetService(typeof(IAuthenticationUserService)) as IAuthenticationUserService;
            var tokenId = actionContext.Request.Headers.GetCookies(AuthenticationConst.CookieKey).FirstOrDefault()?.Cookies.FirstOrDefault(x => x.Name == AuthenticationConst.CookieKey)?.Value;

            tokenId = await service.SetAuthenticationUserAsync(tokenId);
            if (tokenId == null)
            {
                var myCookie = new CookieHeaderValue(AuthenticationConst.CookieKey, "");
                myCookie.Expires = DateTime.Now.AddDays(-1d);
                var response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                response.Headers.AddCookies(new[] { myCookie });
                actionContext.Response = response;
                return;
            }

            await base.OnActionExecutingAsync(actionContext, cancellationToken);
        }

        public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            var tokenId = actionExecutedContext.Request.Headers.GetCookies(AuthenticationConst.CookieKey).FirstOrDefault()?.Cookies.FirstOrDefault(x => x.Name == AuthenticationConst.CookieKey)?.Value;
            var requestScope = actionExecutedContext.Request.GetDependencyScope();
            var service = requestScope.GetService(typeof(IAuthenticationUserService)) as IAuthenticationUserService;
            var newTokenId = await service.GetTokenIdAsync();
            if (tokenId != newTokenId)
            {
                var cookie = new CookieHeaderValue(AuthenticationConst.CookieKey, newTokenId);
                cookie.Expires = DateTime.Now.AddDays(-1d);
                actionExecutedContext.Response.Headers.AddCookies(new[] { cookie });
            }
            actionExecutedContext.Response.Headers.AddCookies(new[] { new CookieHeaderValue(AuthenticationConst.CookieKey, newTokenId) });
            await base.OnActionExecutedAsync(actionExecutedContext, cancellationToken);
        }
    }
}
