using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using PowderCoating.Application.Interfaces;
using PowderCoating.Core.Entities;
using PowderCoating.Core.Interfaces;
using PowderCoating.Infrastructure.Data;

namespace PowderCoating.Web.Filters;

/// <summary>
/// Action filter that injects platform-level feature flags and the current tenant's display
/// timezone into ViewBag before every controller action renders. Views read these to
/// conditionally show features and convert UTC timestamps to local time.
/// </summary>
public class PlatformFeaturesFilter : IAsyncActionFilter
{
    private readonly IPlatformSettingsService _settings;
    private readonly ITenantContext _tenantContext;
    private readonly ApplicationDbContext _db;
    private readonly UserManager<ApplicationUser> _userManager;

    /// <summary>Initialises the filter.</summary>
    public PlatformFeaturesFilter(
        IPlatformSettingsService settings,
        ITenantContext tenantContext,
        ApplicationDbContext db,
        UserManager<ApplicationUser> userManager)
    {
        _settings = settings;
        _tenantContext = tenantContext;
        _db = db;
        _userManager = userManager;
    }

    /// <summary>
    /// Reads platform feature flags and resolves the display timezone, storing both in ViewBag.
    /// Timezone resolution order: company timezone → user profile timezone → null (UTC).
    /// </summary>
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (context.Controller is Controller controller)
        {
            var rawSms = await _settings.GetAsync(PlatformSettingKeys.SmsEnabled);
            controller.ViewBag.SmsEnabled =
                string.Equals(rawSms, "true", StringComparison.OrdinalIgnoreCase);

            string? displayTz = null;

            // Company users: use their company's configured timezone
            var companyId = _tenantContext.GetCurrentCompanyId();
            if (companyId is > 1)
            {
                displayTz = await _db.Companies
                    .Where(c => c.Id == companyId.Value)
                    .Select(c => c.TimeZone)
                    .FirstOrDefaultAsync();
            }

            // SuperAdmins or no company timezone set: fall back to the user's personal timezone
            if (string.IsNullOrWhiteSpace(displayTz))
            {
                var appUser = await _userManager.GetUserAsync(context.HttpContext.User);
                displayTz = appUser?.TimeZone;
            }

            controller.ViewBag.CompanyTimeZone = displayTz;
        }

        await next();
    }
}
