using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Quadarax.Foundation.Core.Business.Interface;
using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;

namespace Quadarax.Foundation.Core.Web.Controllers
{
    public abstract class BaseController<TController, TService>  : ControllerBase 
        where TController : ControllerBase
        where TService : IService 
    {
        private ILogger<TController> _logger;

        protected TService Service { get; }

        protected BaseController(ILoggerFactory logger, TService service)
        {
            _logger = logger.CreateLogger<TController>() ?? throw new ArgumentNullException(nameof(logger));
            Service = service ?? throw new ArgumentNullException(nameof(service));
        }

        protected void ProcessException(ResultDto result, Exception exception)
        {

        }
        
        [HttpGet("test")]
        public ResultPlain Test()
        {
            return Call(() => 
                (ResultPlain)Service.Test()
            );
        }

        public  TResult Call<TResult>(Func<TResult> block) where TResult : ResultDto, new()
        {
            var result = new TResult();
            try
            {
                return block();
            }
            catch (Exception e)
            {
                ProcessException(result, e);
            }

            return result;
        }

        protected void LogInfo(string message)
        {
            _logger.Log(LogLevel.Information, message);
        }

        protected void LogDebug(string message)
        {
            _logger.Log(LogLevel.Debug, message);
        }
        protected void LogTrace(string message)
        {
            _logger.Log(LogLevel.Trace, message);
        }
        protected void LogWarn(string message)
        {
            _logger.Log(LogLevel.Warning, message);
        }
        protected void LogWarn(string message, Exception exception)
        {
            _logger.Log(LogLevel.Warning, message);
        } 
        protected void LogWarn(Exception exception)
        {
            _logger.Log(LogLevel.Warning, exception.ToString());
        }
        protected void LogError(string message)
        {
            _logger.Log(LogLevel.Error, message);
        }
        protected void LogError(string message, Exception exception)
        {
            _logger.Log(LogLevel.Error, message);
        } 
        protected void LogError(Exception exception)
        {
            _logger.Log(LogLevel.Error, exception.ToString());
        }

    }
}
