<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\service\domain\notification\driver;

use app\service\ConfigService;
use PHPMailer\PHPMailer\PHPMailer;
use think\App;
use think\facade\Log;


/**
 * Email Driver
 * @package app\service\domain\notification\driver
 */
class EmailDriver implements NotificationDriverInterface
{
    private App $app;

    /**
     * @param App $app
     */
    public function __construct(App $app)
    {
        $this->app = $app;
    }


    /**
     * 返回驱动类型标识
     * @return string
     */
    public function driverType(): string
    {
        return 'email';
    }


    /**
     * 返回驱动显示名称
     * @return string
     */
    public function name(): string
    {
        return '';
    }


    /**
     * 发送邮件通知
     * @param array $to 接收方信息（email）
     * @param string $templateId 模板ID
     * @param array $data 模板变量数据
     * @param array $config 驱动配置（subject_template/body_template）
     * @return array
     */
    public function send(array $to, string $templateId, array $data, array $config): array
    {
        $email = (string)($to['email'] ?? '');
        if ($email === '') {
            return ['code' => 0, 'msg' => '', 'raw' => []];
        }

        $subject = $this->renderTemplate((string)($config['subject_template'] ?? ''), $data);
        $body = $this->renderTemplate((string)($config['body_template'] ?? ''), $data);

        if ($subject === '') {
            $scene = (string)($data['_scene'] ?? '');
            $subject = $scene !== '' ? '' . $scene : '';
        }

        if ($this->app->isDebug()) {
            Log::info('', [
                'email' => $email,
                'subject' => $subject,
            ]);
            return ['code' => 0, 'msg' => 'ok[test]', 'raw' => ['mock' => true]];
        }

        try {
            $smtpHost = ConfigService::getString('email_smtp_host', '');
            $smtpPort = ConfigService::getString('email_smtp_port', '465');
            $smtpUser = ConfigService::getString('email_smtp_user', '');
            $smtpPass = ConfigService::getString('email_smtp_pass', '');
            $senderName = ConfigService::getString('email_sender_name', '');

            if ($smtpHost === '' || $smtpUser === '' || $smtpPass === '') {
                return ['code' => 1, 'msg' => '', 'raw' => []];
            }

            $mail = new PHPMailer(true);
            $mail->isSMTP();
            $mail->Host       = $smtpHost;
            $mail->SMTPAuth   = true;
            $mail->Username   = $smtpUser;
            $mail->Password   = $smtpPass;
            $mail->SMTPSecure = ((int)$smtpPort === 465) ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = (int)$smtpPort;
            $mail->CharSet    = 'UTF-8';

            $mail->setFrom($smtpUser, $senderName);
            $mail->addAddress($email);

            $mail->isHTML(!empty($body));
            $mail->Subject = $subject;
            if (!empty($body)) {
                $mail->Body = $body;
            } else {
                $mail->Body = $this->buildDefaultBody($data);
            }

            $mail->send();

            Log::info('', ['email' => $email, 'subject' => $subject]);

            return ['code' => 0, 'msg' => 'ok', 'raw' => ['email' => $email]];
        } catch (\Throwable $e) {
            Log::error('' . $e->getMessage());
            return ['code' => 1, 'msg' => $e->getMessage(), 'raw' => []];
        }
    }


    /**
     * 渲染邮件模板变量
     * 将模板中的 {key} 占位符替换为实际数据
     * @param string $template 模板字符串
     * @param array $data 模板变量数据
     * @return string 渲染后的内容
     */
    private function renderTemplate(string $template, array $data): string
    {
        if ($template === '') {
            return '';
        }

        $replacements = [];
        foreach ($data as $key => $value) {
            $replacements['{' . $key . '}'] = is_scalar($value) ? (string)$value : '';
        }

        return strtr($template, $replacements);
    }


    /**
     * 构建默认邮件正文（无模板时使用）
     * 将数据键值对格式化为HTML段落
     * @param array $data 消息数据
     * @return string HTML正文
     */
    private function buildDefaultBody(array $data): string
    {
        $lines = [];
        foreach ($data as $key => $value) {
            if (str_starts_with((string)$key, '_')) {
                continue;
            }
            $label = $key;
            $lines[] = '<p><strong>' . htmlspecialchars($label) . '' . htmlspecialchars((string)$value) . '</p>';
        }
        return '<div style="font-family:Arial,sans-serif;padding:20px;">' . implode('', $lines) . '</div>';
    }
}