<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Admin\Service\Common;

use Admin\Data\Common;
use Admin\Data\Config;
use Laminas\Crypt\BlockCipher;
use Laminas\Http\Client;
use Laminas\Json\Json;
use Laminas\View\Helper\ServerUrl;
use PHPMailer\PHPMailer\PHPMailer;

class ShopMessage
{
    /**
     * 邮件发送
     * @param $emailData
     * @return bool
     * @throws \PHPMailer\PHPMailer\Exception
     */
    public static function sendMail($emailData)
    {
        $mailConfig = Common::configValue('email', 'config');
        if($mailConfig['email_service_state'] != 1 || empty($mailConfig['email_service_type'])) return false;

        return $mailConfig['email_service_type'] == 'smtpService' ? self::sendSmtpMail($mailConfig, $emailData) : self::sendDbshopEmail($mailConfig, $emailData);
    }

    /**
     * 订单提醒邮件发送
     * @param $subject
     * @param $userEmail
     * @param $emailData
     * @param $mailTemplate
     * @return bool
     * @throws \PHPMailer\PHPMailer\Exception
     */
    public static function sendOrderMail($subject, $userEmail, $emailData, $mailTemplate)
    {
        $mailConfig = Common::configValue('email', 'config');
        if($mailConfig['email_service_state'] != 1 || empty($mailConfig['email_service_type'])) return false;

        $emailMessage = Common::readConfigFile('emailMessage');

        $sendAdminStateStr  = 'admin'.$mailTemplate.'Send';
        $sendUserStateStr   = 'buyer'.$mailTemplate.'Send';
        $mailTemplate       = lcfirst($mailTemplate).'EmailBody';

        if(!isset($emailMessage[$mailTemplate])) return false;
        $emailBody = str_replace(["\r\n", " "], ["<br>", "&nbsp;"], htmlspecialchars($emailMessage[$mailTemplate]));
        $emailBody = self::createOrderMailContent($emailData, $emailBody);

        $mail = null;
        if(isset($emailMessage[$sendAdminStateStr]) && $emailMessage[$sendAdminStateStr] == 1 && !empty($emailMessage['adminEmail'])) $mail = explode("\r\n", $emailMessage['adminEmail']);
        if(isset($emailMessage[$sendUserStateStr]) && $emailMessage[$sendUserStateStr] == 1) {
            if($mail == null) $mail = $userEmail;
            else $mail[] = $userEmail;
        }

        if(empty($mail) || empty($emailBody)) return false;

        return $mailConfig['email_service_type'] == 'smtpService' ? self::sendSmtpMail($mailConfig, ['subject' => $subject, 'body' => $emailBody, 'mail' => $mail]) : self::sendDbshopEmail($mailConfig, ['subject' => $subject, 'body' => $emailBody, 'mail' => $mail]);
    }

    /**
     * 发送SMTP电邮
     * @param $mailConfig
     * @param $emailData
     * @return bool
     * @throws \PHPMailer\PHPMailer\Exception
     */
    private static function sendSmtpMail($mailConfig, $emailData)
    {
        $mail = new PHPMailer();
        $mail->isSMTP();
        $mail->Host = $mailConfig['smtp_location'];
        $mail->SMTPAuth = $mailConfig['smtp_check'] == 1;
        $mail->Username = $mailConfig['smtp_name'];
        $mail->Password = $mailConfig['smtp_password'];
        $mail->Port     = $mailConfig['smtp_port'];
        if($mailConfig['smtp_secure_conn'] != 'no') $mail->SMTPSecure = strtolower($mailConfig['smtp_secure_conn']);
        $mail->CharSet  = 'utf-8';
        $mail->setFrom($mailConfig['send_from_mail'], $mailConfig['send_name']);
        $mail->Subject  = $emailData['subject'];
        $mail->isHTML(true);
        $mail->AltBody  = "text/html";
        $mail->msgHTML($emailData['body']);

        if(is_array($emailData['mail'])) {
            foreach ($emailData['mail'] as $emailValue) {
                $mail->addAddress($emailValue);
            }
        } else $mail->addAddress($emailData['mail']);

        try {
            $mail->send();
        }catch (\Exception $e) {
            return false;
        }
        return true;
    }

    /**
     * 发送DBShop官方邮件服务
     * @param $mailConfig
     * @param $emailData
     * @return bool
     */
    private static function sendDbshopEmail($mailConfig, $emailData)
    {
        if (empty($mailConfig['send_name']) || empty($mailConfig['dbshop_email_service_password'])) return false;

        $serviceConfig = Common::readConfigFile('dbshopService');
        if (!$serviceConfig['key'] || !$serviceConfig['code'] || !$serviceConfig['userName']) return false;

        $serverUrl = new ServerUrl();

        $blockCipher = BlockCipher::factory('openssl', ['algo' => 'aes', 'mode' => 'gcm']);
        $blockCipher->setKey($serviceConfig['key']);
        $dataStr = $blockCipher->encrypt(Json::encode([
            'code'          => $serviceConfig['code'],
            'host'          => $serverUrl->getHost(),
            'sendName'      => $mailConfig['send_name'],
            'servicePassword' => $mailConfig['dbshop_email_service_password'],
            'emailData'     => $emailData,
            'versionNumber' => DBSHOP_VERSION_NUMBER,
        ]));
        $client = new Client(Config::SERVICE_URL . 'email-api', [
            'adapter' => 'Laminas\Http\Client\Adapter\Curl',
            'curloptions' => [
                CURLOPT_SSL_VERIFYPEER => false
            ]
        ]);
        $client->setHeaders(['Accept' => 'application/json']);
        $client->setMethod('POST');
        $client->setParameterPost([
            'userName'      => $serviceConfig['userName'],
            'systemType'    => 'dbshop',
            'action'        => 'sendShopEmail',
            'dataStr'       => $dataStr
        ]);
        try {
            $client->send();
        } catch (\Exception $e) {
            return false;
        }
        return true;
    }

    /**
     * 对订单提醒的电邮内容进行解析
     * @param $data
     * @param $mailContent
     * @return string|string[]
     */
    private static function createOrderMailContent($data, $mailContent)
    {
        $replaceArray = [
            '{shopName}'        => $data['shopName'] ?? '',   //网站名称
            '{buyName}'         => $data['buyName'] ?? '',    //买家名称
            '{orderSn}'         => $data['orderSn'] ?? '',    //订单编号
            '{orderTotal}'      => $data['orderTotal'] ?? '', //订单金额
            '{addOrderTime}'    => isset($data['addOrderTime'])     ? date("Y-m-d H:i:s", $data['addOrderTime']) : '',      //订单提交时间
            '{paymentOrderTime}'=> isset($data['paymentOrderTime']) ? date("Y-m-d H:i:s", $data['paymentOrderTime']) : '',  //订单付款时间
            '{deliveryName}'    => $data['deliveryName'] ?? '',   //快递名称
            '{expressNumber}'   => $data['expressNumber'] ?? '',  //快递单号
            '{shipOrderTime}'   => isset($data['shipOrderTime'])    ? date("Y-m-d H:i:s", $data['shipOrderTime']) : '',     //订单发货时间
            '{receiptOrderTime}'=> isset($data['receiptOrderTime']) ? date("Y-m-d H:i:s", $data['receiptOrderTime']) : '',  //订单收货时间
            '{cancelOrderTime}' => isset($data['cancelOrderTime'])  ? date("Y-m-d H:i:s", $data['cancelOrderTime']) : '',   //订单取消时间
            '{shopUrl}'         => isset($data['shopUrl'])          ? '<a href="'.$data['shopUrl'].'" target="_blank">'.$data['shopUrl'].'</a>' : '', //网站网址

            '{goodsName}'       => $data['goodsName'] ?? '',    //商品名称
            '{goodsStock}'      => $data['goodsStock'] ?? '',   //商品库存
        ];
        $replaceArray = array_filter($replaceArray);

        if(!empty($replaceArray)) foreach ($replaceArray as $key => $value) {
            $mailContent = str_replace($key, $value, $mailContent);
        }

        return $mailContent;
    }
}