using JobTrackerApi.Data;
using JobTrackerApi.Models;
using Microsoft.EntityFrameworkCore;

namespace JobTrackerApi.Services;

public sealed record EmailSettingsSnapshot(
    bool Enabled,
    string Host,
    int Port,
    string User,
    string Password,
    string From,
    string FromName,
    bool EnableSsl,
    int TimeoutMs,
    bool UsesOverrides,
    bool HasPassword);

public sealed record EmailSettingsAdminDto(
    bool Enabled,
    string Host,
    int Port,
    string User,
    string From,
    string FromName,
    bool EnableSsl,
    int TimeoutMs,
    bool UsesOverrides,
    bool HasPassword);

public sealed record UpdateEmailSettingsRequest(
    bool Enabled,
    string? Host,
    int Port,
    string? User,
    string? Password,
    bool ClearPassword,
    string? From,
    string? FromName,
    bool EnableSsl,
    int TimeoutMs);

public interface IEmailSettingsResolver
{
    Task<EmailSettingsSnapshot> GetSnapshotAsync(CancellationToken cancellationToken = default);
    Task<EmailSettingsAdminDto> GetAdminDtoAsync(CancellationToken cancellationToken = default);
    Task<EmailSettingsAdminDto> UpdateAsync(UpdateEmailSettingsRequest request, CancellationToken cancellationToken = default);
}

public sealed class EmailSettingsResolver : IEmailSettingsResolver
{
    private readonly IConfiguration _cfg;
    private readonly JobTrackerContext _db;

    public EmailSettingsResolver(IConfiguration cfg, JobTrackerContext db)
    {
        _cfg = cfg;
        _db = db;
    }

    public async Task<EmailSettingsSnapshot> GetSnapshotAsync(CancellationToken cancellationToken = default)
    {
        var overrides = await _db.SystemEmailSettings.AsNoTracking().FirstOrDefaultAsync(x => x.Id == 1, cancellationToken);
        return Merge(overrides);
    }

    public async Task<EmailSettingsAdminDto> GetAdminDtoAsync(CancellationToken cancellationToken = default)
    {
        var snapshot = await GetSnapshotAsync(cancellationToken);
        return new EmailSettingsAdminDto(
            Enabled: snapshot.Enabled,
            Host: snapshot.Host,
            Port: snapshot.Port,
            User: snapshot.User,
            From: snapshot.From,
            FromName: snapshot.FromName,
            EnableSsl: snapshot.EnableSsl,
            TimeoutMs: snapshot.TimeoutMs,
            UsesOverrides: snapshot.UsesOverrides,
            HasPassword: snapshot.HasPassword);
    }

    public async Task<EmailSettingsAdminDto> UpdateAsync(UpdateEmailSettingsRequest request, CancellationToken cancellationToken = default)
    {
        var settings = await _db.SystemEmailSettings.FirstOrDefaultAsync(x => x.Id == 1, cancellationToken);
        if (settings is null)
        {
            settings = new SystemEmailSettings { Id = 1 };
            _db.SystemEmailSettings.Add(settings);
        }

        settings.Enabled = request.Enabled;
        settings.SmtpHost = TrimOrNull(request.Host);
        settings.SmtpPort = request.Port <= 0 ? 587 : request.Port;
        settings.SmtpUser = TrimOrNull(request.User);
        settings.From = TrimOrNull(request.From);
        settings.FromName = TrimOrNull(request.FromName);
        settings.SmtpEnableSsl = request.EnableSsl;
        settings.SmtpTimeoutMs = request.TimeoutMs <= 0 ? 15000 : request.TimeoutMs;

        if (request.ClearPassword)
        {
            settings.SmtpPassword = null;
        }
        else if (!string.IsNullOrWhiteSpace(request.Password))
        {
            settings.SmtpPassword = request.Password.Trim();
        }

        await _db.SaveChangesAsync(cancellationToken);
        return await GetAdminDtoAsync(cancellationToken);
    }

    private EmailSettingsSnapshot Merge(SystemEmailSettings? overrides)
    {
        var host = overrides?.SmtpHost ?? (_cfg["Email:SmtpHost"] ?? string.Empty).Trim();
        var user = overrides?.SmtpUser ?? (_cfg["Email:SmtpUser"] ?? string.Empty).Trim();
        var password = overrides?.SmtpPassword ?? (_cfg["Email:SmtpPassword"] ?? string.Empty).Trim();
        var from = overrides?.From ?? (_cfg["Email:From"] ?? user).Trim();
        var fromName = overrides?.FromName ?? (_cfg["Email:FromName"] ?? "Jobbjakt").Trim();
        var port = overrides?.SmtpPort ?? _cfg.GetValue("Email:SmtpPort", 587);
        if (port <= 0) port = 587;
        var enableSsl = overrides?.SmtpEnableSsl ?? _cfg.GetValue("Email:SmtpEnableSsl", true);
        var timeoutMs = overrides?.SmtpTimeoutMs ?? _cfg.GetValue("Email:SmtpTimeoutMs", 15000);
        if (timeoutMs <= 0) timeoutMs = 15000;
        var enabled = overrides?.Enabled ?? _cfg.GetValue("Email:Enabled", false);
        var usesOverrides = overrides is not null;

        return new EmailSettingsSnapshot(
            Enabled: enabled,
            Host: host,
            Port: port,
            User: user,
            Password: password,
            From: from,
            FromName: fromName,
            EnableSsl: enableSsl,
            TimeoutMs: timeoutMs,
            UsesOverrides: usesOverrides,
            HasPassword: !string.IsNullOrWhiteSpace(password));
    }

    private static string? TrimOrNull(string? value)
    {
        return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
    }
}
