package com.tzld.piaoquan.growth.common.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
import com.tzld.piaoquan.growth.common.common.enums.ExceptionCodeEnum;
import com.tzld.piaoquan.growth.common.common.enums.MessageAttachmentTypeEnum;
import com.tzld.piaoquan.growth.common.common.exception.CustomizeException;
import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
import com.tzld.piaoquan.growth.common.component.ProxyHttpPoolClient;
import com.tzld.piaoquan.growth.common.dao.mapper.GuaranteesVideoMapper;
import com.tzld.piaoquan.growth.common.dao.mapper.MessageAttachmentMapper;
import com.tzld.piaoquan.growth.common.model.bo.AdPutFlowParam;
import com.tzld.piaoquan.growth.common.model.bo.VideoDetail;
import com.tzld.piaoquan.growth.common.model.bo.VideoParam;
import com.tzld.piaoquan.growth.common.model.po.*;
import com.tzld.piaoquan.growth.common.model.vo.GuaranteedParam;
import com.tzld.piaoquan.growth.common.service.MessageAttachmentService;
import com.tzld.piaoquan.growth.common.service.WeComAccessTokenService;
import com.tzld.piaoquan.growth.common.service.WeComSendService;
import com.tzld.piaoquan.growth.common.utils.DateUtil;
import com.tzld.piaoquan.growth.common.utils.FileUtils;
import com.tzld.piaoquan.growth.common.utils.ImageUrlValidator;
import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.tzld.piaoquan.growth.common.common.constant.MessageConstant.MAX_VIDEO_NUM;
import static com.tzld.piaoquan.growth.common.common.constant.MessageConstant.appid;
import static com.tzld.piaoquan.growth.common.common.constant.OtherServerURL.POST_ADD_TENCENT;
import static com.tzld.piaoquan.growth.common.common.constant.OtherServerURL.POST_VIDEO_DETAIL_URL;
import static com.tzld.piaoquan.growth.common.common.constant.TimeConstant.MILLISECOND_DAY;
import static com.tzld.piaoquan.growth.common.common.constant.WeComConstant.POST_WE_COM_MEDIA_UPLOAD;
import static com.tzld.piaoquan.growth.common.common.constant.WeComConstant.POST_WE_COM_MEDIA_UPLOAD_ATTACHMENT;


@Slf4j
@Service
public class MessageAttachmentServiceImpl implements MessageAttachmentService {

    @Autowired
    private HttpPoolClient httpPoolClient;

    @Autowired
    private ProxyHttpPoolClient proxyHttpPoolClient;

    @Autowired
    private WeComAccessTokenService weComAccessTokenService;

    @Autowired
    private MessageAttachmentMapper messageAttachmentMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private GuaranteesVideoMapper guaranteesVideoMapper;

    @Autowired
    private WeComSendService weComSendService;

    @Override
    public List<Long> addMessageAttachment(List<MessageAttachment> messageAttachmentList, Long createTime) {
        List<Long> messageAttachmentIds = new ArrayList<>();
        for (MessageAttachment messageAttachment : messageAttachmentList) {
            MessageAttachmentExample example = new MessageAttachmentExample();
            MessageAttachmentExample.Criteria criteria = example.createCriteria().andTypeEqualTo(messageAttachment.getType());
            if (messageAttachment.getType().equals(MessageAttachmentTypeEnum.IMAGE.getCode())) {
                if (messageAttachment.getMediaId() != null) {
                    criteria.andMediaIdEqualTo(messageAttachment.getMediaId());
                }
                if (messageAttachment.getPicUrl() != null) {
                    criteria.andPicUrlEqualTo(messageAttachment.getPicUrl());
                }
            }
            if (messageAttachment.getType().equals(MessageAttachmentTypeEnum.MINI_PROGRAM.getCode())) {
                if (messageAttachment.getAppid() != null) {
                    criteria.andAppidEqualTo(messageAttachment.getAppid());
                }
                if (messageAttachment.getMiniprogramVideoId() != null) {
                    criteria.andMiniprogramVideoIdEqualTo(messageAttachment.getMiniprogramVideoId());
                }
                if (messageAttachment.getStaffId() != null) {
                    criteria.andStaffIdEqualTo(messageAttachment.getStaffId());
                }
            }

            if (messageAttachment.getType().equals(MessageAttachmentTypeEnum.LINK.getCode())) {
                if (messageAttachment.getTitle() != null) {
                    criteria.andTitleEqualTo(messageAttachment.getTitle());
                }
                if (messageAttachment.getPicUrl() != null) {
                    criteria.andPicUrlEqualTo(messageAttachment.getPicUrl());
                }
                if (messageAttachment.getDesc() != null) {
                    criteria.andDescEqualTo(messageAttachment.getDesc());
                }
                if (messageAttachment.getUrl() != null) {
                    criteria.andUrlEqualTo(messageAttachment.getUrl());
                }
            }

            List<MessageAttachment> messageAttachments = messageAttachmentMapper.selectByExample(example);
            if (CollectionUtils.isEmpty(messageAttachments)) {
                if (messageAttachment.getType().equals(MessageAttachmentTypeEnum.MINI_PROGRAM.getCode()) &&
                        createTime != null) {
                    messageAttachment.setSendTime(new Date(createTime));
                }
                messageAttachmentMapper.insertSelective(messageAttachment);
            } else {
                messageAttachment.setId(messageAttachments.get(0).getId());
                messageAttachmentMapper.updateByPrimaryKeySelective(messageAttachment);
            }
            messageAttachmentIds.add(messageAttachment.getId());
        }
        return messageAttachmentIds;
    }

    @Override
    public List<MessageAttachment> getMessageAttachment(List<Long> attachmentIds) {
        MessageAttachmentExample example = new MessageAttachmentExample();
        example.createCriteria().andIdIn(attachmentIds);
        return messageAttachmentMapper.selectByExample(example);
    }


    public CommonResponse<Void> createGuaranteedMiniProgram(GuaranteedParam guaranteedParam) {
        if (isInvalidGuaranteedParam(guaranteedParam)) {
            return CommonResponse.create(500, "参数错误");
        }
        Set<Long> videoIds = new HashSet<>();
        for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
            CommonResponse<Void> voidCommonResponse = processVideoParam(videoParam, guaranteedParam.getDate(), videoIds);
            if (voidCommonResponse != null) {
                return voidCommonResponse;
            }
        }
        Map<Long, MessageAttachment> messageAttachmentMap;
        try {
            Map<Long, VideoDetail> coverMap = getVideoDetail(videoIds);
            messageAttachmentMap = createMessageAttachmentMap(videoIds, coverMap);
        } catch (CustomizeException e) {
            return CommonResponse.create(500, e.getMessage());
        }
        List<MessageAttachment> messageAttachmentList = new ArrayList<>();
        for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
            addMessageAttachments(videoParam, messageAttachmentMap, guaranteedParam.getDate(), messageAttachmentList);
        }

        addMessageAttachment(messageAttachmentList, null);
        return CommonResponse.success();
    }

    private boolean isInvalidGuaranteedParam(GuaranteedParam guaranteedParam) {
        return guaranteedParam == null ||
                StringUtils.isEmpty(guaranteedParam.getDate()) ||
                CollectionUtils.isEmpty(guaranteedParam.getVideoParamList());
    }


    private CommonResponse<Void> processVideoParam(VideoParam videoParam, String date, Set<Long> videoIds) {
        if (CollectionUtils.isEmpty(videoParam.getVideoIds()) || videoParam.getVideoIds().size() < MAX_VIDEO_NUM) {
            return CommonResponse.create(500, "保底视频数量异常，请查看" + date);
        }
        List<Long> staffIds = Optional.ofNullable(videoParam.getStaffIds()).orElseGet(() -> {
            List<Long> newStaffIds = new ArrayList<>();
            if (videoParam.getStaffId() != null) {
                newStaffIds.add(videoParam.getStaffId());
            }
            return newStaffIds;
        });
        for (Long staffId : staffIds) {
            CommonResponse<Void> voidCommonResponse = checkVideoSendTime(videoParam, staffId);
            if (voidCommonResponse != null) {
                return voidCommonResponse;
            }
            videoIds.addAll(videoParam.getVideoIds());
        }
        return null;
    }

    private CommonResponse<Void> checkVideoSendTime(VideoParam videoParam, Long staffId) {
        for (Long videoId : videoParam.getVideoIds()) {
            MessageAttachmentExample example = new MessageAttachmentExample();
            example.createCriteria().andMiniprogramVideoIdEqualTo(videoId).andStaffIdEqualTo(staffId);
            List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
            if (CollectionUtils.isEmpty(messageAttachmentList)) {
                continue;
            }
            MessageAttachment messageAttachment = messageAttachmentList.get(0);
            if (messageAttachment.getSendTime() != null &&
                    DateUtil.dateDifference(new Date(), messageAttachment.getSendTime()) < 30 * MILLISECOND_DAY) {
                return CommonResponse.create(500, "保底视频30天内已发送，请查看videoId=" + videoId);
            }
        }
        return null;
    }

    private Map<Long, MessageAttachment> createMessageAttachmentMap(Set<Long> videoIds, Map<Long, VideoDetail> coverMap) {
        Map<Long, MessageAttachment> messageAttachmentMap = new HashMap<>();
        for (Long videoId : videoIds) {
            VideoDetail videoDetail = coverMap.get(videoId);
            if (videoDetail == null || StringUtils.isEmpty(videoDetail.getCover()) || StringUtils.isEmpty(videoDetail.getTitle())) {
                throw new CustomizeException(ExceptionCodeEnum.PARAMS_ERROR, "获取视频详情异常，请查看:" + videoId);
            }
            if (!ImageUrlValidator.isValidImageUrl(videoDetail.getCover())) {
                throw new CustomizeException(ExceptionCodeEnum.PARAMS_ERROR, "保底视频封面异常，请查看:" + videoId);
            }
            MessageAttachment messageAttachment = new MessageAttachment();
            messageAttachment.setMiniprogramVideoId(videoId);
            messageAttachment.setType(MessageAttachmentTypeEnum.MINI_PROGRAM.getCode());
            messageAttachment.setCover(videoDetail.getCover());
            messageAttachment.setTitle(videoDetail.getTitle());
            messageAttachment.setAppid(appid);
            messageAttachmentMap.put(videoId, messageAttachment);
        }
        return messageAttachmentMap;
    }

    private void addMessageAttachments(VideoParam videoParam, Map<Long, MessageAttachment> messageAttachmentMap, String date, List<MessageAttachment> messageAttachmentList) {
        List<Long> staffIds = Optional.ofNullable(videoParam.getStaffIds()).orElseGet(() -> {
            List<Long> newStaffIds = new ArrayList<>();
            if (videoParam.getStaffId() != null) {
                newStaffIds.add(videoParam.getStaffId());
            }
            return newStaffIds;
        });

        for (Long staffId : staffIds) {
            if (staffId == 0) {
                addGuaranteesVideo(date, staffId, videoParam.getVideoIds());
                continue;
            }

            for (Long videoId : videoParam.getVideoIds()) {
                MessageAttachment messageAttachment = messageAttachmentMap.get(videoId);
                if (messageAttachment == null) {
                    continue;
                }

                MessageAttachment newMessageAttachment = new MessageAttachment();
                BeanUtils.copyProperties(messageAttachment, newMessageAttachment);
                newMessageAttachment.setStaffId(staffId);
                messageAttachmentList.add(newMessageAttachment);
            }
            addGuaranteesVideo(date, staffId, videoParam.getVideoIds());
        }
    }

    private void addGuaranteesVideo(String date, Long staffId, List<Long> videoIds) {
        GuaranteesVideoExample example = new GuaranteesVideoExample();
        example.createCriteria().andIsDeleteEqualTo(0).andDateEqualTo(date).andStaffIdEqualTo(staffId);
        List<GuaranteesVideo> guaranteesVideos = guaranteesVideoMapper.selectByExample(example);
        for (GuaranteesVideo guaranteesVideo : guaranteesVideos) {
            guaranteesVideo.setIsDelete(1);
            guaranteesVideoMapper.updateByPrimaryKeySelective(guaranteesVideo);
        }
        GuaranteesVideo guaranteesVideo = new GuaranteesVideo();
        guaranteesVideo.setDate(date);
        guaranteesVideo.setStaffId(staffId);
        guaranteesVideo.setVideoIds(JSONObject.toJSONString(videoIds));
        guaranteesVideoMapper.insertSelective(guaranteesVideo);
    }

    @Override
    public GuaranteedParam getGuaranteedVideo(String date) {
        GuaranteesVideoExample example = new GuaranteesVideoExample();
        example.createCriteria().andDateEqualTo(date).andIsDeleteEqualTo(0);
        List<GuaranteesVideo> guaranteesVideos = guaranteesVideoMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(guaranteesVideos)) {
            LarkRobotUtil.sendMessage("获保底视频空，<at user_id=\"g6732afb\">王云鹏</at>");
            return null;
        }
        GuaranteedParam guaranteedParam = new GuaranteedParam();
        guaranteedParam.setDate(date);
        List<VideoParam> videoParams = new ArrayList<>();
        for (GuaranteesVideo guaranteesVideo : guaranteesVideos) {
            VideoParam videoParam = new VideoParam();
            videoParam.setStaffId(guaranteesVideo.getStaffId());
            List<Long> videoIds = JSONArray.parseArray(guaranteesVideo.getVideoIds(), Long.class);
            videoParam.setVideoIds(videoIds);
            videoParams.add(videoParam);
        }
        guaranteedParam.setVideoParamList(videoParams);
        return guaranteedParam;
    }


    @Override
    public Map<Long, VideoDetail> getVideoDetail(Set<Long> videoIdList) {
        try {
            Map<Long, VideoDetail> map = new HashMap<>();
            JSONObject params = new JSONObject();
            params.put("videoIdList", videoIdList);
            String post = httpPoolClient.post(POST_VIDEO_DETAIL_URL, params.toJSONString());
            JSONObject res = JSONObject.parseObject(post);
            JSONArray data = res.getJSONArray("data");
            for (int i = 0; i < data.size(); i++) {
                VideoDetail videoDetail = new VideoDetail();
                JSONObject jsonObject = data.getJSONObject(i);
                if (Objects.isNull(jsonObject)) {
                    continue;
                }
                Long videoId = jsonObject.getLong("id");
                String shareImgPath = jsonObject.getString("shareImgPath");
                String title = jsonObject.getString("title");
                String videoPath = jsonObject.getString("videoPath");
                String videoCoverSnapshotPath = jsonObject.getString("videoCoverSnapshotPath");
                videoDetail.setCover(shareImgPath);
                videoDetail.setTitle(title);
                videoDetail.setVideoPath(videoPath);
                videoDetail.setVideoCoverSnapshotPath(videoCoverSnapshotPath);
                videoDetail.setAuditStatus(jsonObject.getInteger("auditStatus"));
                videoDetail.setRecommendStatus(jsonObject.getInteger("recommendStatus"));
                map.put(videoId, videoDetail);
            }
            return map;
        } catch (IOException e) {
            log.error("MessageAttachmentServiceImpl getVideDetail error", e);
        }
        return new HashMap<>();
    }

    @Override
    public String getPicMediaId(String cover, Long corpId, Long miniprogramVideoId) {
        if (StringUtils.isEmpty(cover)) {
            Map<Long, VideoDetail> videoDetail = getVideoDetail(Collections.singleton(miniprogramVideoId));
            cover = videoDetail.get(miniprogramVideoId).getCover();
        }
        String key = corpId + "_" + cover;
        String mediaId = (String) redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotEmpty(mediaId)) {
            return mediaId;
        }

        String filePath = UUID.randomUUID() + ".jpg"; // 临时文件路径
        try {
            HttpURLConnection httpUrl = (HttpURLConnection) new URL(cover).openConnection();
            httpUrl.connect();
            InputStream inputStream = httpUrl.getInputStream();

            // 将文件内容写入临时文件
            try (OutputStream outputStream = Files.newOutputStream(Paths.get(filePath))) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
            inputStream.close();
            httpUrl.disconnect();
            File file = new File(filePath);
            String weComAccessToken = weComAccessTokenService.getWeComAccessToken(corpId);
            String url = String.format(POST_WE_COM_MEDIA_UPLOAD + "?access_token=%s&type=%s", weComAccessToken, "image");
            String res;
            if (corpId == 1L) {
                res = httpPoolClient.post(url, file);
            } else {
                res = proxyHttpPoolClient.post(url, file);
            }
            JSONObject jsonObject = JSONObject.parseObject(res);
            if (jsonObject != null && jsonObject.getInteger("errcode") == 0) {
                mediaId = jsonObject.getString("media_id");
                redisTemplate.opsForValue().set(key, mediaId, 2, TimeUnit.DAYS);
            }
            Files.delete(Paths.get(filePath));
        } catch (Exception e) {
            log.error("getPicMediaId error", e);
        }
        return mediaId;

    }

    @Override
    public String getPage(String putScene, String channel, Staff staff, Long videoId,
                          String typeOne, String typeTwo, String typeThree, String experimentId) {
        try {
            if (staff == null || staff.getCarrierId() == null) {
                return "";
            }
            String page = selectPage(putScene, channel, videoId, staff.getCarrierId(), typeOne, typeTwo);
            if (StringUtils.isNotEmpty(page)) {
                return page;
            }
            return insertPage("pages/category.html", putScene, channel, staff.getCarrierId(), videoId, staff.getRemark(), typeOne, typeTwo, typeThree, experimentId);
        } catch (IOException e) {
            log.error("MessageAttachmentService getPage error", e);
        }
        return null;
    }

    @Override
    public String getPageNoCache(String path, String putScene, String channel, Staff staff, Long videoId,
                                 String typeOne, String typeTwo, String typeThree, String experimentId) {
        try {
            if (staff == null || staff.getCarrierId() == null) {
                return "";
            }
            return insertPage(path, putScene, channel, staff.getCarrierId(), videoId, staff.getRemark(), typeOne, typeTwo, typeThree, experimentId);
        } catch (IOException e) {
            log.error("MessageAttachmentService getPageNoCache error", e);
        }
        return null;
    }

    private String insertPage(String path, String putScene, String channel, String carrierId, Long videoId, String remark,
                              String typeOne, String typeTwo, String typeThree, String experimentId) throws IOException {
        AdPutFlowParam param = new AdPutFlowParam();
        param.setChannel(channel);
        param.setPath(path);
        param.setPutCarrierId(carrierId);
        param.setPutScene(putScene);
        param.setPutStartDate(DateUtil.getDayDateString("yyyy-MM-dd"));
        param.setPutTypeOne(typeOne);
        param.setPutTypeTwo(typeTwo);
        param.setPutTypeThree(typeThree);
        param.setRemark(remark);
        param.setVideoId(videoId);
        param.setTestId(experimentId);
        Map<String, String> requestParam = new HashMap<>();
        String experimentIdParam = (experimentId != null && !experimentId.isEmpty()) ? "&experimentId=" + experimentId : "";
        String jumpPage = "pages/user-videos?fromGzh=1&rootShareId=${uuid}&id=${videoId}&shareId=${uuid}&rootSourceId=[rootSourceId]"
                .replace("${videoId}", "" + videoId)
                .replace("${uuid}", "" + UUID.randomUUID())
                + experimentIdParam;
        requestParam.put("jumpPage", jumpPage);
        param.setRequestParam(requestParam);
        String res = httpPoolClient.post(POST_ADD_TENCENT, JSONObject.toJSONString(param));
        JSONObject jsonObject = JSONObject.parseObject(res);
        JSONObject data = jsonObject.getJSONObject("data");
        String pageUrl = data.getString("url");
        // 在返回的url字段后拼接growthExtData参数（URL编码，作为jumpPage内部参数）
        if (experimentId != null && !experimentId.isEmpty() && pageUrl != null) {
            JSONObject growthExtData = new JSONObject();
            growthExtData.put("experimentId", experimentId);
            pageUrl = pageUrl + "%26growthExtData%3D" + URLEncoder.encode(growthExtData.toJSONString(), "UTF-8");
        }
        return pageUrl;
    }

    public String selectPage(String putScene, String channel, Long videoId, String carrierId, String typeOne, String typeTwo) {
        int totalPage = 1;
        for (int n = 1; n <= totalPage; n++) {
            String url = getUrl(videoId, putScene, channel, n);
            try {
                String res = httpPoolClient.get(url);
                JSONObject jsonObject = JSONObject.parseObject(res);
                JSONObject data = jsonObject.getJSONObject("data");
                if (data == null) {
                    continue;
                }
                if (data.getInteger("totalPage") != null) {
                    totalPage = data.getInteger("totalPage");
                }
                JSONArray objs = data.getJSONArray("objs");
                for (int i = 0; i < objs.size(); i++) {
                    JSONObject obj = objs.getJSONObject(i);
                    String putCarrierId = obj.getString("putCarrierId");
                    String page = obj.getString("url");
                    String putTypeOne = obj.getString("putTypeOne");
                    String putTypeTwo = obj.getString("putTypeTwo");

                    if (StringUtils.isEmpty(putCarrierId) || StringUtils.isEmpty(page) || StringUtils.isEmpty(putTypeOne) || StringUtils.isEmpty(putTypeTwo)) {
                        continue;
                    }

                    if (putCarrierId.equals(carrierId) && putTypeOne.equals(typeOne) && putTypeTwo.equals(typeTwo)) {
                        return page;
                    }
                }
            } catch (IOException e) {
                log.error("Error fetching data from API for videoId: " + videoId + ", page: " + n, e);
            }
        }
        return null;
    }

    private static String getUrl(Long videoId, String putScene, String channel, int n) {
        String baseUrl = "https://api.piaoquantv.com/ad/put/flow/list/tencent";
        int pageSize = 20;
        return String.format(
                "%s?videoId=%d&putScene=%s&channel=%s&currentPage=%d&pageSize=%d",
                baseUrl,
                videoId,
                putScene,
                channel,
                n,
                pageSize
        );
    }

    @Override
    public String getPage(String channel, String carrierId, String scene, String putTypeOne,
                          String putTypeTwo, String putTypeThree, Long videoId, String experimentId) {
        AdPutFlowParam param = new AdPutFlowParam();
        param.setChannel(channel);
        param.setPath("pages/category");
        param.setPutCarrierId(carrierId);
        param.setPutScene(scene);
        param.setPutStartDate(DateUtil.getDayDateString("yyyy-MM-dd"));
        param.setPutTypeOne(putTypeOne);
        param.setPutTypeTwo(putTypeTwo);
        param.setPutTypeThree(putTypeThree);
        param.setVideoId(videoId);
        param.setTestId(experimentId);
        Map<String, String> requestParam = new HashMap<>();
        String experimentIdParam = (experimentId != null && !experimentId.isEmpty()) ? "&experimentId=" + experimentId : "";
        String jumpPage = "pages/user-videos?fromGzh=1&rootShareId=${uuid}&id=${videoId}&shareId=${uuid}&rootSourceId=[rootSourceId]"
                .replace("${videoId}", "" + videoId)
                .replace("${uuid}", "" + UUID.randomUUID())
                + experimentIdParam;
        requestParam.put("jumpPage", jumpPage);
        param.setRequestParam(requestParam);
        try {
            String res = httpPoolClient.post(POST_ADD_TENCENT, JSONObject.toJSONString(param));
            JSONObject jsonObject = JSONObject.parseObject(res);
            JSONObject data = jsonObject.getJSONObject("data");
            String pageUrl = data.getString("url");
            // 在返回的url字段后拼接growthExtData参数（URL编码，作为jumpPage内部参数）
            if (experimentId != null && !experimentId.isEmpty() && pageUrl != null) {
                JSONObject growthExtData = new JSONObject();
                growthExtData.put("experimentId", experimentId);
                pageUrl = pageUrl + "%26growthExtData%3D" + URLEncoder.encode(growthExtData.toJSONString(), "UTF-8");
            }
            return pageUrl;
        } catch (Exception e) {
            log.error("MessageAttachmentService getPage error", e);
        }
        return null;
    }

    @Override
    public CommonResponse<Long> createAttachment(Integer type, MultipartFile file, String url, String picUrl, String page, String title, String desc, String appId, Integer extType) {
        if (type == null) {
            return CommonResponse.create(500, "附件类型不能为空");
        }
        if (Objects.equals(MessageAttachmentTypeEnum.MINI_PROGRAM.getCode(), type)) {
            if (StringUtils.isEmpty(title)) {
                return CommonResponse.create(500, "标题不能为空");
            }
            if (StringUtils.isEmpty(page)) {
                return CommonResponse.create(500, "小程序路径不能为空");
            }
            if (file == null || file.isEmpty()) {
                return CommonResponse.create(500, "封面文件不能为空");
            }
            String mediaId = uploadFile(file, "image", extType);
            if (StringUtils.isEmpty(mediaId)) {
                return CommonResponse.create(500, "封面上传失败");
            }
            MessageAttachment messageAttachment = new MessageAttachment();
            messageAttachment.setType(type);
            messageAttachment.setMediaId(mediaId);
            messageAttachment.setTitle(title);
            messageAttachment.setPage(page);
            if (StringUtils.isNotEmpty(appId)) {
                messageAttachment.setAppid(appId);
            } else {
                messageAttachment.setAppid(appid);
            }
            messageAttachmentMapper.insertSelective(messageAttachment);
            return CommonResponse.create(messageAttachment.getId());
        }

        if (Objects.equals(MessageAttachmentTypeEnum.LINK.getCode(), type)) {
            if (StringUtils.isEmpty(title)) {
                return CommonResponse.create(500, "标题不能为空");
            }
            if (StringUtils.isEmpty(desc)) {
                return CommonResponse.create(500, "描述不能为空");
            }
            if (StringUtils.isEmpty(url)) {
                return CommonResponse.create(500, "视频不能为空");
            }
            if (StringUtils.isEmpty(picUrl)) {
                return CommonResponse.create(500, "封面不能为空");
            }
            MessageAttachment messageAttachment = new MessageAttachment();
            messageAttachment.setType(type);
            messageAttachment.setTitle(title);
            messageAttachment.setDesc(desc);
            messageAttachment.setUrl(url);
            messageAttachment.setPicUrl(picUrl);
            messageAttachmentMapper.insertSelective(messageAttachment);
            return CommonResponse.create(messageAttachment.getId());
        }

        if (Objects.equals(MessageAttachmentTypeEnum.IMAGE.getCode(), type)) {
            if (file == null || file.isEmpty()) {
                return CommonResponse.create(500, "图片不能为空");
            }
            String mediaId = uploadFile(file, "image", extType);
            if (StringUtils.isEmpty(mediaId)) {
                return CommonResponse.create(500, "图片上传失败");
            }
            MessageAttachment messageAttachment = new MessageAttachment();
            messageAttachment.setType(type);
            messageAttachment.setMediaId(mediaId);
            messageAttachmentMapper.insertSelective(messageAttachment);
            return CommonResponse.create(messageAttachment.getId());
        }

        if (Objects.equals(MessageAttachmentTypeEnum.VIDEO.getCode(), type)) {
            if (file == null || file.isEmpty()) {
                return CommonResponse.create(500, "视频不能为空");
            }
            String mediaId = uploadFile(file, "video", extType);
            if (StringUtils.isEmpty(mediaId)) {
                return CommonResponse.create(500, "视频上传失败");
            }
            MessageAttachment messageAttachment = new MessageAttachment();
            messageAttachment.setType(type);
            messageAttachment.setMediaId(mediaId);
            messageAttachmentMapper.insertSelective(messageAttachment);
            return CommonResponse.create(messageAttachment.getId());
        }
        return CommonResponse.create(500, "没有对应类型");
    }

    private String uploadFile(MultipartFile multipartFile, String fileType, Integer extType) {
        String mediaId = null;
        try {
            String extension = FileUtils.getExtension(multipartFile);
            String filePath = UUID.randomUUID() + extension; // 临时文件路径
            InputStream inputStream = multipartFile.getInputStream();
            // 将文件内容写入临时文件
            try (OutputStream outputStream = Files.newOutputStream(Paths.get(filePath))) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
            inputStream.close();
            File file = new File(filePath);
            //暂时不区分主体
            String weComAccessToken = weComAccessTokenService.getWeComAccessToken(1L);
            String url;
            if (extType != null && extType == 1) {
                url = String.format(POST_WE_COM_MEDIA_UPLOAD_ATTACHMENT + "?access_token=%s&media_type=%s&attachment_type=1", weComAccessToken, fileType);
            } else {
                url = String.format(POST_WE_COM_MEDIA_UPLOAD + "?access_token=%s&type=%s", weComAccessToken, fileType);
            }
            String res = httpPoolClient.post(url, file);

            JSONObject jsonObject = JSONObject.parseObject(res);
            if (jsonObject != null && jsonObject.getInteger("errcode") == 0) {
                mediaId = jsonObject.getString("media_id");
            }
            Files.delete(Paths.get(filePath));
        } catch (Exception e) {
            log.error("uploadFile error", e);
        }
        return mediaId;
    }


}
