package com.ffii.fpsms.modules.common.alert

import com.ffii.fpsms.modules.common.SettingNames
import com.ffii.fpsms.modules.common.mail.service.MailSenderService
import com.ffii.fpsms.modules.settings.service.SettingsService
import jakarta.mail.internet.InternetAddress
import org.slf4j.LoggerFactory
import org.springframework.mail.javamail.MimeMessageHelper
import org.springframework.stereotype.Service

/**
 * Plain-text alert emails via existing Office 365 SMTP settings in DB
 * ([SettingNames.MAIL_SMTP_HOST] = smtp.office365.com, port 587, etc.).
 */
@Service
open class SyncAlertEmailSender(
    private val mailSenderService: MailSenderService,
    private val settingsService: SettingsService,
) {
    private val logger = LoggerFactory.getLogger(SyncAlertEmailSender::class.java)

    open fun isSmtpConfigured(): Boolean {
        return smtpConfigIssue() == null
    }

    /** Null if OK; otherwise a short message for UI/logs. */
    open fun smtpConfigIssue(): String? {
        return try {
            val username = settingsService.findByName(SettingNames.MAIL_SMTP_USERNAME).orElse(null)?.value
            val password = settingsService.findByName(SettingNames.MAIL_SMTP_PASSWORD).orElse(null)?.value
            val host = settingsService.findByName(SettingNames.MAIL_SMTP_HOST).orElse(null)?.value
            when {
                host.isNullOrBlank() -> "MAIL.smtp.host is empty"
                username.isNullOrBlank() -> "MAIL.smtp.username is empty"
                password.isNullOrBlank() -> "MAIL.smtp.password is empty"
                else -> null
            }
        } catch (_: Exception) {
            "MAIL.smtp settings missing in settings table"
        }
    }

    open fun resolveFromAddress(): String? =
        settingsService.findByName(SettingNames.MAIL_SMTP_USERNAME).orElse(null)?.value?.trim()?.takeIf { it.isNotEmpty() }

    open fun send(toAddresses: List<String>, subject: String, body: String) {
        require(toAddresses.isNotEmpty()) { "No email recipients" }
        smtpConfigIssue()?.let { throw IllegalStateException(it) }
        val from = resolveFromAddress()
            ?: throw IllegalStateException("MAIL.smtp.username is not set in settings")

        try {
            val sender = mailSenderService.get()
            val mimeMessage = sender.createMimeMessage()
            val helper = MimeMessageHelper(mimeMessage, false, Charsets.UTF_8.name())
            helper.setFrom(InternetAddress(from))
            helper.setTo(toAddresses.toTypedArray())
            helper.setSubject(subject)
            helper.setText(body, false)

            sender.send(mimeMessage)
            logger.info("Sync alert email sent from {} to {}", from, toAddresses.joinToString())
        } catch (e: Exception) {
            logger.error("Sync alert email failed from {}: {}", from, e.message, e)
            throw e
        }
    }
}
