package com.yc.ship.module.trade.service.order.handler;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yc.ship.module.infra.api.config.ConfigApi;
import com.yc.ship.module.system.api.user.AdminUserApi;
import com.yc.ship.module.system.api.user.dto.AdminUserRespDTO;
import com.yc.ship.module.trade.api.sms.dto.SmsSendLogDTO;
import com.yc.ship.module.trade.controller.admin.smsSendconfig.vo.SmsSendconfigQueryRespVO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderDO;
import com.yc.ship.module.trade.service.order.TradeOrderRepositoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * &#064;Description 保险处理
 * &#064;Author qsl
 * &#064;Date 2025/8/16 14:49
 */
@Component
@Order(TradeOrderHandler.SMS_ORDER)
@Slf4j
public class SmsHandler implements TradeOrderHandler {


    @Resource
    private TradeOrderRepositoryService tradeOrderRepositoryService;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private ConfigApi configApi;

    @Override
    public void processOrderCreateSuccess(TradeOrderDO tradeOrderDO) {
        try {
            if(tradeOrderDO.getSellMethod()!=null && tradeOrderDO.getSellMethod()==3){
                return;
            }
            List<SmsSendconfigQueryRespVO> list = tradeOrderRepositoryService.getCreateOrderSmsInfo(tradeOrderDO.getId(), 0);
            if (list.isEmpty()) {
                return;
            }
            for (SmsSendconfigQueryRespVO smsSendconfigQueryRespVO : list) {
                if (smsSendconfigQueryRespVO.getMobile() != null) {
                    sendMsg(smsSendconfigQueryRespVO);
                }
            }
        } catch (Exception e) {
            log.error("短信发送异常", e);
        }
    }

    /***
     * 转确认单发送 旅行社和直客
     * 2026/3/6 17:28
     */
    @Override
    public void afterProcessSuccess(TradeOrderDO tradeOrderDO) {
        try {
            if(tradeOrderDO.getSellMethod()==3) {
                List<SmsSendconfigQueryRespVO> list = tradeOrderRepositoryService.getOrderSmsInfo(tradeOrderDO.getId(), 4);
                if (list.isEmpty()) {
                    return;
                }
                for (SmsSendconfigQueryRespVO smsSendconfigQueryRespVO : list) {
                    if (smsSendconfigQueryRespVO.getMobile() != null) {
                        sendMsg(smsSendconfigQueryRespVO);
                    }
                }
            }
        } catch (Exception e) {
            log.error("短信发送异常", e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public String sendMsg(SmsSendconfigQueryRespVO smsSendconfigQueryRespVO) {
        try {

            String appId = smsSendconfigQueryRespVO.getApiKey();
            String secretKey = smsSendconfigQueryRespVO.getApiSecret();
            String signName = smsSendconfigQueryRespVO.getSignature();
            String content = smsSendconfigQueryRespVO.getSmsParms();
            String smsContent = smsSendconfigQueryRespVO.getSmsContent();
            //【1】航次名称； 【2】订单号； 【3】游玩日期； 【4】联系人；【5】购买数量；
            //            【6】团号； 【7】旅行社联系人； 【8】联系电话；【9】航线名称；【10】产品简称；【11】咨询电话；【12】游船；【13】开航时间；
            //            【14】出发时间；【15】违约金；【16】补缴费；【17】小程序链接；【18】登船时间
            content = content.replaceAll("【1】", smsSendconfigQueryRespVO.getVoyageName());
            content = content.replaceAll("【2】", smsSendconfigQueryRespVO.getOrderNo());
            content = content.replaceAll("【3】", smsSendconfigQueryRespVO.getUseDate().substring(0, 10));
            content = content.replaceAll("【12】", smsSendconfigQueryRespVO.getShipName());
            content = content.replaceAll("【13】", smsSendconfigQueryRespVO.getUseDate().substring(0, 10));
            content = content.replaceAll("【4】", smsSendconfigQueryRespVO.getContactName());
            content = content.replaceAll("【5】", smsSendconfigQueryRespVO.getNum() + "");
            content = content.replaceAll("【6】", smsSendconfigQueryRespVO.getGroupNo());
            content = content.replaceAll("【7】", smsSendconfigQueryRespVO.getContactName());
            content = content.replaceAll("【8】", smsSendconfigQueryRespVO.getMobile());
            content = content.replaceAll("【9】", smsSendconfigQueryRespVO.getRouteName());
            content = content.replaceAll("【10】", smsSendconfigQueryRespVO.getShortName());
            content = content.replaceAll("【14】", smsSendconfigQueryRespVO.getLeaveTime().substring(0, 10));
            content = content.replaceAll("【18】", smsSendconfigQueryRespVO.getLeaveTime().substring(0, 10));
            DateTime dateTime = DateUtil.offsetDay(DateUtil.parse(smsSendconfigQueryRespVO.getLeaveTime()), -7);
            DateTime dateTime2 = DateUtil.offsetDay(DateUtil.parse(smsSendconfigQueryRespVO.getLeaveTime()), -1);
            content = content.replaceAll("【19】", DateUtil.format(dateTime, "yyyy-MM-dd"));
            content = content.replaceAll("【20】", DateUtil.format(dateTime2, "yyyy-MM-dd"));

            Pattern pattern = Pattern.compile("\\【(.*?)\\】");
            Matcher matcher = pattern.matcher(smsContent);
            List<String> list = new ArrayList<>();
            while (matcher.find()) {
                String result = smsContent.substring(matcher.start() + 1, matcher.end() - 1);
                list.add(result);
            }
            JSONObject jsonObject = new JSONObject();
            List<String> parmlist = JSONUtil.toList(content, String.class);
            for (int i = 0; i < list.size(); i++) {
                jsonObject.set(list.get(i), parmlist.get(i));
            }
            String mobile = smsSendconfigQueryRespVO.getMobile();
            log.error("[下单成功短信发送参数]：" + smsSendconfigQueryRespVO.getApiTemplateId() + ";" + mobile + ";" + jsonObject.toString());
            SendSmsResponse result = MoblieMessageAliyunUtil.sendSms(appId, secretKey, signName, mobile, jsonObject.toString(), smsSendconfigQueryRespVO.getApiTemplateId() + "");
            log.error("[下单成功短信返回参数]：" + JSONUtil.toJsonStr(result));
            if (result != null && "OK".equals(result.getCode())) {
                log.error("[下单成功短信发送成功]：" + mobile);
                SmsSendLogDTO reqDTO = new SmsSendLogDTO();
                reqDTO.setId(IdWorker.getId());
                reqDTO.setTenantId(smsSendconfigQueryRespVO.getTenantId());
                reqDTO.setMobile(mobile);
                reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId()+"");
                reqDTO.setOrderNo(smsSendconfigQueryRespVO.getOrderNo());
                reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId() + "");
                reqDTO.setResult(JSONUtil.toJsonStr(result));
                reqDTO.setStatus(1);
                reqDTO.setSmsContent(content);
                tradeOrderRepositoryService.insertSmsLog(reqDTO);
                return "发送成功";
            }else{
                SmsSendLogDTO reqDTO = new SmsSendLogDTO();
                reqDTO.setId(IdWorker.getId());
                reqDTO.setTenantId(smsSendconfigQueryRespVO.getTenantId());
                reqDTO.setMobile(mobile);
                reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId()+"");
                reqDTO.setOrderNo(smsSendconfigQueryRespVO.getOrderNo());
                reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId() + "");
                reqDTO.setResult(JSONUtil.toJsonStr(result));
                reqDTO.setStatus(0);
                reqDTO.setSmsContent(content);
                tradeOrderRepositoryService.insertSmsLog(reqDTO);
                return "短信发送失败";
            }
        } catch (Exception e) {
            SmsSendLogDTO reqDTO = new SmsSendLogDTO();
            reqDTO.setId(IdWorker.getId());
            reqDTO.setTenantId(smsSendconfigQueryRespVO.getTenantId());
            reqDTO.setMobile(smsSendconfigQueryRespVO.getMobile());
            reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId()+"");
            reqDTO.setOrderNo(smsSendconfigQueryRespVO.getOrderNo());
            reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId() + "");
            reqDTO.setResult("异常"+e.getMessage());
            reqDTO.setStatus(0);
            reqDTO.setSmsContent(smsSendconfigQueryRespVO.getSmsContent());
            tradeOrderRepositoryService.insertSmsLog(reqDTO);
            log.error("[下单成功短信发送失败]：" + e.getMessage());
            return "短信发送失败: " + e.getMessage();
        }
    }

    private String md5(String input) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(input.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : array) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5加密失败", e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public String sendMsg2(SmsSendconfigQueryRespVO smsSendconfigQueryRespVO) {
        try {
            String telphone = "0717-6910001";
            if (StringUtils.isNotEmpty(smsSendconfigQueryRespVO.getSellerId())) {
                try {
                    AdminUserRespDTO user = adminUserApi.getUserIgnoreTenant(Long.parseLong(smsSendconfigQueryRespVO.getSellerId()));
                    if (StringUtils.isNotEmpty(user.getMobile())) {
                        //如果有售票员的电话则发送售票员的电话作为咨询电话
                        telphone = user.getMobile();
                    } else {
                        //读取配置文件默认参数
                        String mtelphone = configApi.getPlatformConfigValueByKey("telphone");
                        if (mtelphone != null) {
                            telphone = mtelphone;
                        }
                    }
                } catch (Exception e) {
                    log.error("用户信息获取异常" + smsSendconfigQueryRespVO.getSellerId(), e);
                }
            }

            //sxly
            String appId = smsSendconfigQueryRespVO.getApiKey();
            //Sx@202305
            String secretKey = smsSendconfigQueryRespVO.getApiSecret();
            //https://112.35.10.201:58888/sms/tmpsubmit
            String url = smsSendconfigQueryRespVO.getApiUrl();
            //jFKNw6Cis
            String signName = smsSendconfigQueryRespVO.getSignature();
            String input = smsSendconfigQueryRespVO.getSmsParms();
            //【1】产品名称； 【2】订单号； 【3】游玩日期； 【4】联系人；【5】购买数量； 【6】团名称； 【7】旅行社联系人； 【8】联系电话；【9】时间方案名称；【10】产品简称； 【11】咨询电话；
            input = input.replaceAll("【1】", smsSendconfigQueryRespVO.getProductName().substring(0, 10).replace("【", "").replace("】", "").replace("-", ""));
            input = input.replaceAll("【2】", smsSendconfigQueryRespVO.getOrderNo());
            input = input.replaceAll("【3】", smsSendconfigQueryRespVO.getUseDate().substring(0, 10));
            input = input.replaceAll("【4】", smsSendconfigQueryRespVO.getContactName());
            input = input.replaceAll("【5】", smsSendconfigQueryRespVO.getNum() + "");
            input = input.replaceAll("【6】", smsSendconfigQueryRespVO.getSourceName());
            input = input.replaceAll("【7】", smsSendconfigQueryRespVO.getContactName());
            input = input.replaceAll("【8】", smsSendconfigQueryRespVO.getMobile());
            input = input.replaceAll("【9】", smsSendconfigQueryRespVO.getRouteName());
            input = input.replaceAll("【10】", smsSendconfigQueryRespVO.getShortName());
            input = input.replaceAll("【11】", telphone);
            JSONArray parts = JSONUtil.parseArray(input);
            JSONArray templates = JSONUtil.parseArray(smsSendconfigQueryRespVO.getTemplateParams());
            Map map = new HashMap<>();
            for (int i = 0; i < templates.size(); i++) {
                String key = templates.getStr(i);
                String value = parts.getStr(i);
                map.put(key, value);
            }
            String content = StrUtil.format(smsSendconfigQueryRespVO.getSmsContent(), map);
            String mobile = smsSendconfigQueryRespVO.getMobile();
            log.error("[下单成功短信发送参数]：" + content + ";手机号：" + mobile);
            HttpClient httpclient = new HttpClient();
            PostMethod post = new PostMethod(url);
            post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "gbk");
            post.addParameter("SpCode", signName);
            post.addParameter("LoginName", appId);
            post.addParameter("Password", secretKey);
            post.addParameter("MessageContent", content);
            post.addParameter("UserNumber", mobile);
            Random random = new Random();
            int ranNum = random.nextInt(9);
            String serialNumber = SmsUtil.createOrderNo(ranNum + "");
            if (serialNumber.length() > 20) {
                serialNumber = serialNumber.substring(0, 19);
            }
            post.addParameter("SerialNumber", serialNumber);
            post.addParameter("ScheduleTime", "");
            post.addParameter("templateId", smsSendconfigQueryRespVO.getApiTemplateId());
            post.addParameter("f", "1");
            httpclient.executeMethod(post);
            String result = new String(post.getResponseBody(), "gbk");
            log.error("[下单成功短信返回参数]：" + result);
            if (result.contains("result=0")) {
                log.error("[下单成功短信发送成功]：" + mobile);
                SmsSendLogDTO reqDTO = new SmsSendLogDTO();
                reqDTO.setId(IdWorker.getId());
                reqDTO.setTenantId(smsSendconfigQueryRespVO.getTenantId());
                reqDTO.setMobile(mobile);
                reqDTO.setSmsConfigId(mobile);
                reqDTO.setOrderNo(smsSendconfigQueryRespVO.getOrderNo());
                reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId() + "");
                reqDTO.setResult(result);
                reqDTO.setStatus(1);
                reqDTO.setSmsContent(content);
                tradeOrderRepositoryService.insertSmsLog(reqDTO);
                return "发送成功";
            } else {
                SmsSendLogDTO reqDTO = new SmsSendLogDTO();
                reqDTO.setId(IdWorker.getId());
                reqDTO.setTenantId(smsSendconfigQueryRespVO.getTenantId());
                reqDTO.setMobile(mobile);
                reqDTO.setSmsConfigId(mobile);
                reqDTO.setOrderNo(smsSendconfigQueryRespVO.getOrderNo());
                reqDTO.setSmsConfigId(smsSendconfigQueryRespVO.getId() + "");
                reqDTO.setResult(result);
                reqDTO.setStatus(0);
                reqDTO.setSmsContent(content);
                tradeOrderRepositoryService.insertSmsLog(reqDTO);
                return "发送失败";
            }
        } catch (Exception e) {
            log.error("[下单成功短信发送失败]：" + e.getMessage());
            return "短信发送失败: " + e.getMessage();
        }
    }


    private static class MyHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    public static String sendPost(String url, String param, Map<String, String> headParam) {
        Long s0 = System.currentTimeMillis();
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            HttpURLConnection conn;
            if ("https".equalsIgnoreCase(realUrl.getProtocol())) {
                HttpsURLConnection httpsConn = (HttpsURLConnection) realUrl.openConnection();
                httpsConn.setHostnameVerifier(new MyHostnameVerifier());
                conn = httpsConn;
            } else {
                conn = (HttpURLConnection) realUrl.openConnection();
            }

            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept-Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("charset", "UTF-8");
            if (headParam != null) {
                for (Map.Entry<String, String> entry : headParam.entrySet()) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            // 发送POST请求必须设置如下两行
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(1000000);
            conn.setReadTimeout(1000000);

//            System.setProperty("sun.net.client.defaultConnectTimeout", "1000000");
//            System.setProperty("sun.net.client.defaultReadTimeout", "1000000");
            // 获取URLConnection对象对应的输出流
            if (StringUtils.isNotBlank(param)) {
                out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
                out.write(param);
                // flush输出流的缓冲
                out.flush();
            }

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            //LogUtil.appLog.info("sendPost>>"+url+">>"+param+">>>"+headParam+">>>>>执行时间："+(System.currentTimeMillis()-s0));
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.offsetDay(DateUtil.parse("2026-03-20"), -7));
    }

}
