using GerbilManagerWebAPI.Models;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.EntityFrameworkCore;

namespace GerbilManagerWebAPI.Inbox
{
    /// <summary>
    /// Reads/updates the singleton MailSettings. The Gmail App Password is encrypted at rest
    /// with ASP.NET Data Protection and is NEVER returned over the wire (only used server-side
    /// to open the IMAP/SMTP connection).
    /// </summary>
    public sealed class MailSettingsService
    {
        private readonly ApplicationContext _db;
        private readonly IDataProtector _protector;

        public MailSettingsService(ApplicationContext db, IDataProtectionProvider dp)
        {
            _db = db;
            _protector = dp.CreateProtector("GerbilManager.MailSettings.AppPassword.v1");
        }

        public async Task<MailSettings> GetAsync(CancellationToken ct = default)
        {
            var s = await _db.MailSettings.FirstOrDefaultAsync(ct);
            if (s is null)
            {
                s = new MailSettings { Id = MailSettings.SingletonId };
                _db.MailSettings.Add(s);
                await _db.SaveChangesAsync(ct);
            }
            return s;
        }

        public bool HasAppPassword(MailSettings s) => !string.IsNullOrEmpty(s.AppPasswordProtected);

        public string? DecryptPassword(MailSettings s) =>
            string.IsNullOrEmpty(s.AppPasswordProtected) ? null : _protector.Unprotect(s.AppPasswordProtected);

        public void SetPassword(MailSettings s, string? plain) =>
            s.AppPasswordProtected = string.IsNullOrEmpty(plain) ? null : _protector.Protect(plain);
    }
}
