using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PowderCoating.Core.Interfaces;
using PowderCoating.Shared.Constants;

namespace PowderCoating.Web.Controllers;

/// <summary>
/// SuperAdmin view of per-company SMS terms agreement history.
/// Shows which companies have accepted the current SMS terms, who accepted them,
/// and the full acceptance log for each company.
/// </summary>
[Authorize(Policy = AppConstants.Policies.SuperAdminOnly)]
public class SmsAgreementsController : Controller
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly ILogger<SmsAgreementsController> _logger;

    public SmsAgreementsController(IUnitOfWork unitOfWork, ILogger<SmsAgreementsController> logger)
    {
        _unitOfWork = unitOfWork;
        _logger = logger;
    }

    /// <summary>
    /// Lists every company with its current SMS agreement status and full acceptance history.
    /// Uses IgnoreQueryFilters on both queries so deleted/inactive companies and all historical
    /// agreement records are included in the audit view.
    /// </summary>
    public async Task<IActionResult> Index(string? search = null, string? filter = null)
    {
        var companies = await _unitOfWork.Companies.GetAllAsync(ignoreQueryFilters: true);
        var allAgreements = await _unitOfWork.CompanySmsAgreements.GetAllAsync(ignoreQueryFilters: true);

        var agreementsByCompany = allAgreements
            .GroupBy(a => a.CompanyId)
            .ToDictionary(g => g.Key, g => g.OrderByDescending(a => a.AgreedAt).ToList());

        var rows = companies
            .OrderBy(c => c.CompanyName)
            .Select(c =>
            {
                var agreements = agreementsByCompany.TryGetValue(c.Id, out var list) ? list : [];
                var current = agreements.FirstOrDefault(a => a.TermsVersion == AppConstants.SmsTermsVersion);
                return new CompanySmsRow
                {
                    CompanyId = c.Id,
                    CompanyName = c.CompanyName ?? "(unnamed)",
                    SmsEnabled = c.SmsEnabled,
                    SmsDisabledByAdmin = c.SmsDisabledByAdmin,
                    CurrentAgreement = current,
                    LatestAgreement = agreements.FirstOrDefault(),
                    AllAgreements = agreements,
                    IsDeleted = c.IsDeleted
                };
            })
            .ToList();

        // Filter
        rows = filter switch
        {
            "accepted" => rows.Where(r => r.CurrentAgreement != null).ToList(),
            "pending"  => rows.Where(r => r.CurrentAgreement == null).ToList(),
            "enabled"  => rows.Where(r => r.SmsEnabled).ToList(),
            "disabled" => rows.Where(r => r.SmsDisabledByAdmin).ToList(),
            _          => rows
        };

        if (!string.IsNullOrWhiteSpace(search))
            rows = rows.Where(r => r.CompanyName.Contains(search, StringComparison.OrdinalIgnoreCase)).ToList();

        ViewBag.Search = search;
        ViewBag.Filter = filter ?? "all";
        ViewBag.CurrentTermsVersion = AppConstants.SmsTermsVersion;

        // Stats (pre-filter totals)
        var all = companies.ToList();
        ViewBag.TotalCompanies    = all.Count(c => !c.IsDeleted);
        ViewBag.AcceptedCount     = agreementsByCompany.Count(kvp =>
            kvp.Value.Any(a => a.TermsVersion == AppConstants.SmsTermsVersion) &&
            !all.FirstOrDefault(c => c.Id == kvp.Key)?.IsDeleted == true);
        ViewBag.SmsEnabledCount   = all.Count(c => !c.IsDeleted && c.SmsEnabled);

        return View(rows);
    }
}

/// <summary>View model for one company row on the SMS agreements page.</summary>
public class CompanySmsRow
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; } = string.Empty;
    public bool SmsEnabled { get; set; }
    public bool SmsDisabledByAdmin { get; set; }
    public bool IsDeleted { get; set; }
    public PowderCoating.Core.Entities.CompanySmsAgreement? CurrentAgreement { get; set; }
    public PowderCoating.Core.Entities.CompanySmsAgreement? LatestAgreement { get; set; }
    public List<PowderCoating.Core.Entities.CompanySmsAgreement> AllAgreements { get; set; } = [];
}
