using CvMatcher.Models.Responses;
using CvSearch.Models.Data.Entities;
using MailKit.Net.Smtp;
using MailKit.Security;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MimeKit;

namespace CvSearchJob.Services;

public sealed class CvSearchEmailSender
{
    private readonly IConfiguration _config;
    private readonly ILogger<CvSearchEmailSender> _logger;

    public CvSearchEmailSender(IConfiguration config, ILogger<CvSearchEmailSender> logger)
    {
        _config = config;
        _logger = logger;
    }

    public async Task SendResultsAsync(
        string toEmail,
        string? attachmentPath,
        IReadOnlyList<JobSearchResultEntity> results,
        CancellationToken ct)
    {
        var smtpHost = _config["Smtp:Host"];
        var smtpPort = int.TryParse(_config["Smtp:Port"], out var port) ? port : 587;
        var smtpUser = _config["Smtp:Username"];
        var smtpPass = _config["Smtp:Password"];
        var useStartTls = bool.TryParse(_config["Smtp:UseStartTls"], out var tls) && tls;
        var contactToEmail = _config["Contact:ToEmail"];

        if (string.IsNullOrWhiteSpace(smtpHost)) return;

        var recipients = new List<string>();
        if (!string.IsNullOrWhiteSpace(toEmail)) recipients.Add(toEmail);
        if (!string.IsNullOrWhiteSpace(contactToEmail) &&
            !recipients.Any(r => string.Equals(r, contactToEmail, StringComparison.OrdinalIgnoreCase)))
            recipients.Add(contactToEmail);

        if (recipients.Count == 0) return;

        var body = BuildBody(results);
        var subject = $"MyAi.ro: {results.Count} joburi potrivite CV-ului tau";
        var environmentName = Environment.GetEnvironmentVariable("APP_ENVIRONMENT_NAME") ?? "Development";

        foreach (var recipient in recipients)
        {
            var msg = new MimeMessage();
            msg.From.Add(MailboxAddress.Parse(smtpUser!));
            msg.To.Add(MailboxAddress.Parse(recipient));
            msg.Subject = $"[{environmentName}] {subject}";

            var builder = new BodyBuilder { TextBody = body };
            if (!string.IsNullOrWhiteSpace(attachmentPath) && File.Exists(attachmentPath))
                builder.Attachments.Add(attachmentPath);

            msg.Body = builder.ToMessageBody();

            try
            {
                using var client = new SmtpClient();
                var tls2 = useStartTls ? SecureSocketOptions.StartTls : SecureSocketOptions.Auto;
                await client.ConnectAsync(smtpHost, smtpPort, tls2, ct);
                if (!string.IsNullOrWhiteSpace(smtpUser))
                    await client.AuthenticateAsync(smtpUser, smtpPass ?? string.Empty, ct);
                await client.SendAsync(msg, ct);
                await client.DisconnectAsync(true, ct);
                _logger.LogInformation("Job search results email sent to {Recipient}", recipient);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to send job search results email to {Recipient}", recipient);
            }
        }
    }

    private static string BuildBody(IReadOnlyList<JobSearchResultEntity> results)
    {
        if (results.Count == 0)
            return "MyAi.ro nu a gasit joburi care sa corespunda CV-ului tau. Incercati mai tarziu sau ajustati CV-ul.";

        var lines = new System.Text.StringBuilder();
        lines.AppendLine($"MyAi.ro a gasit {results.Count} joburi potrivite CV-ului tau:");
        lines.AppendLine();

        for (int i = 0; i < results.Count; i++)
        {
            var r = results[i];
            var matchResp = TryParseResult(r.ResultJson);
            lines.AppendLine($"{i + 1}. {r.JobTitle} ({r.Score}% match) [{r.ProviderName}]");
            lines.AppendLine($"   {r.JobUrl}");
            if (matchResp is not null && !string.IsNullOrWhiteSpace(matchResp.Summary))
                lines.AppendLine($"   {matchResp.Summary}");
            lines.AppendLine();
        }

        return lines.ToString();
    }

    private static JobMatchResponse? TryParseResult(string json)
    {
        try { return System.Text.Json.JsonSerializer.Deserialize<JobMatchResponse>(json, new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.Web)); }
        catch { return null; }
    }
}
