package com.yc.ship.module.otc.service.link;

import cn.hutool.core.io.IoUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.module.infra.api.config.ConfigApi;
import com.yc.ship.module.infra.api.file.FileApi;
import com.yc.ship.module.otc.controller.admin.link.detail.LinkDetailSaveReqVO;
import com.yc.ship.module.otc.controller.admin.link.vo.LinkPageReqVO;
import com.yc.ship.module.otc.controller.admin.link.vo.LinkSaveReqVO;
import com.yc.ship.module.otc.dal.dataobject.link.LinkDO;
import com.yc.ship.module.otc.dal.mysql.link.LinkMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static com.yc.ship.module.otc.enums.ErrorCodeConstants.LINK_NOT_EXISTS;

/**
 * 链接管理 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
@Slf4j
public class LinkServiceImpl implements LinkService {

    @Resource
    private LinkMapper linkMapper;

    @Resource
    private LinkDetailService linkDetailService;

//    @Resource
//    private MarketingParamsApi marketingParamsApi;
//
//    @Resource
//    private ProductApi productApi;

    @Override
    @Transactional
    public Long createLink(LinkSaveReqVO createReqVO) {
        // 插入
        LinkDO link = BeanUtils.toBean(createReqVO, LinkDO.class);
//        Long id = IdWorker.getId(link);
//        link.setId(id);
//        JSONObject params = JSONUtil.createObj();
//        params.set("l", id);
//        // 链接类型 1.门店码 2.员工码 3.产品码 4.子产品码
//        String indexPath = "pages/home/index";
//        String indexPath2 = "pages/home/index";
//        String query = "";
//        if (createReqVO.getIsMultiple() == 1) {
//            if (createReqVO.getType() == 4) {
//                throw exception0(500, "子产品码不能选多个子产品");
//            }
//            // 多选
//            for (int i = 0; i < createReqVO.getCheckedValues().size(); i++) {
//                LinkDetailSaveReqVO reqVO = new LinkDetailSaveReqVO();
//                reqVO.setLinkId(id);
//                reqVO.setSourceCode(createReqVO.getCheckedValues().get(i));
//                reqVO.setType(createReqVO.getType());
//                Long detailId = linkDetailService.createLinkDetail(reqVO);
//            }
//        } else {
//            // 单选
//            LinkDetailSaveReqVO reqVO = new LinkDetailSaveReqVO();
//            reqVO.setLinkId(id);
//            reqVO.setSourceCode(createReqVO.getCheckedValue());
//            reqVO.setType(createReqVO.getType());
//            Long detailId = linkDetailService.createLinkDetail(reqVO);
//            if (createReqVO.getType() == 4) {
//                List<Long> categoryList = new ArrayList<>(3);
//                categoryList.add(createReqVO.getParamValue());
//                // 查询子产品商品类型
//                List<CategoryRespDTO> categoryDTOS = productApi.getCategoryListByIds(2, categoryList).getCheckedData();
//                if (categoryDTOS.isEmpty()) {
//                    throw exception0(500, "未查到对应产品");
//                }
//                CategoryExtraRespDTO extraInfo = categoryDTOS.get(0).getExtraInfo();
//                if (extraInfo == null) {
//                    throw exception0(500, "未查到对应产品");
//                }
//                int spuType = extraInfo.getSpuType();
//                params.set("spuType", spuType);
//                Long checkedValue = createReqVO.getCheckedValue();
//                params.set("productId", checkedValue);
////                query = "id=" + checkedValue + "&spuType=" + spuType;
//                indexPath = "pages/home/catalogue/ticket/ticket-details/index";
//                indexPath2 = "pages/home/catalogue/ticket/ticket-details/index";
//            }
//        }
//        MarketingParamsDto paramsDto = new MarketingParamsDto();
//        paramsDto.setParams(params.toString());
//        Long paramsId = marketingParamsApi.create(paramsDto).getCheckedData();
////        String scene = StringUtils.isNotBlank(query) ? query : "q=" + id;
////        String scene = "q=" + id + (StringUtils.isNotBlank(query) ? "&" + query : "");
//        String scene = "q=" + paramsId;
//        String scene2 = "scene=q%3D" + paramsId;
//        String url = getMiniQr(scene, createReqVO.getLinkName(), indexPath);
//        String linkUrl = getMiniLink(scene2,indexPath2);
//        link.setUrl(url);
//        link.setLinkUrl(linkUrl);
//        link.setContent(StringUtils.isBlank(link.getContent()) ? "" : link.getContent());
//        linkMapper.insert(link);
        // 返回
        return link.getId();
    }

    @Override
    @Transactional
    public void updateLink(LinkSaveReqVO updateReqVO) {
//        Long id = updateReqVO.getId();
//        // 校验存在
//        validateLinkExists(id);
//        // 更新
//        LinkDO updateObj = BeanUtils.toBean(updateReqVO, LinkDO.class);
//        // 删除之前的关联
//        linkDetailService.deleteLinkDetailByLinkId(id);
//        JSONObject params = JSONUtil.createObj();
//        params.set("l", id);
//        // 链接类型 1.门店码 2.员工码 3.产品码 4.子产品码
//        String indexPath = "pages/home/index";
//        String indexPath2 = "pages/home/index";
//        String query = "";
//        if (updateReqVO.getIsMultiple() == 1) {
//            // 多选
//            if (updateReqVO.getType() == 4) {
//                throw exception0(500, "子产品码不能选多个子产品");
//            }
//            for (int i = 0; i < updateReqVO.getCheckedValues().size(); i++) {
//                LinkDetailSaveReqVO reqVO = new LinkDetailSaveReqVO();
//                reqVO.setLinkId(id);
//                reqVO.setSourceCode(updateReqVO.getCheckedValues().get(i));
//                reqVO.setType(updateReqVO.getType());
//                Long detailId = linkDetailService.createLinkDetail(reqVO);
//            }
//        } else {
//            // 单选
//            LinkDetailSaveReqVO reqVO = new LinkDetailSaveReqVO();
//            reqVO.setLinkId(id);
//            reqVO.setSourceCode(updateReqVO.getCheckedValue());
//            reqVO.setType(updateReqVO.getType());
//            Long detailId = linkDetailService.createLinkDetail(reqVO);
//            if (updateReqVO.getType() == 4) {
//                List<Long> categoryList = new ArrayList<>(3);
//                categoryList.add(updateReqVO.getParamValue());
//                // 查询子产品商品类型
//                List<CategoryRespDTO> categoryDTOS = productApi.getCategoryListByIds(2, categoryList).getCheckedData();
//                if (categoryDTOS.isEmpty()) {
//                    throw exception0(500, "未查到对应产品");
//                }
//                CategoryExtraRespDTO extraInfo = categoryDTOS.get(0).getExtraInfo();
//                if (extraInfo == null) {
//                    throw exception0(500, "未查到对应产品");
//                }
//                int spuType = extraInfo.getSpuType();
//                Long checkedValue = updateReqVO.getCheckedValue();
//                params.set("productId", checkedValue);
//                params.set("spuType", spuType);
////                query = "id=" + checkedValue + "&spuType=" + spuType;
//                indexPath = "pages/home/catalogue/ticket/ticket-details/index";
//                indexPath2 = "pages/home/catalogue/ticket/ticket-details/index";
//            }
//        }
//        MarketingParamsDto paramsDto = new MarketingParamsDto();
//        paramsDto.setParams(params.toString());
//        Long paramsId = marketingParamsApi.create(paramsDto).getCheckedData();
////        String scene = StringUtils.isNotBlank(query) ? query : "q=" + id;
////        String scene = "q=" + id + (StringUtils.isNotBlank(query) ? "&" + query : "");
//        String scene = "q=" + paramsId;
//        String scene2 = "scene=q%3D" + paramsId;
//        log.error("scene="+scene);
//        String url = getMiniQr(scene, updateReqVO.getLinkName(), indexPath);
//        updateObj.setUrl(url);
//        String linkUrl = getMiniLink(scene2,indexPath2);
//        updateObj.setLinkUrl(linkUrl);
//        linkMapper.updateById(updateObj);
    }

    @Override
    @Transactional
    public void deleteLink(Long id) {
        // 校验存在
        validateLinkExists(id);
        // 删除之前的关联
        linkDetailService.deleteLinkDetailByLinkId(id);
        // 删除
        linkMapper.deleteById(id);
    }

    private void validateLinkExists(Long id) {
        if (linkMapper.selectById(id) == null) {
            throw exception(LINK_NOT_EXISTS);
        }
    }

    @Override
    public LinkDO getLink(Long id) {
        return linkMapper.selectById(id);
    }

    @Override
    public PageResult<LinkDO> getLinkPage(LinkPageReqVO pageReqVO) {
        return linkMapper.selectPage(pageReqVO);
    }

    @Resource
    private ConfigApi configApi;

    @Resource
    private FileApi fileApi;

    public String getMiniQr(String scene, String linkName, String indexPath) {
//        try {
//            String appId = configApi.getConfigValueByKey("wxMinAppId").getCheckedData();
//            String secret = configApi.getConfigValueByKey("wxMinAppSecret").getCheckedData();
////            indexPath = configApi.getConfigValueByKey("indexPath").getCheckedData();
//            String enVersion = configApi.getConfigValueByKey("enVersion").getCheckedData();
//            //这里调用的是上面的获取access_token方法
//            String access_token = getWxAccessToken(appId, secret);
//            URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token);
//            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//            // 提交模式
//            httpURLConnection.setRequestMethod("POST");
//            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
//            // conn.setReadTimeout(2000);//读取超时 单位毫秒
//            // 发送POST请求必须设置如下两行
//            httpURLConnection.setDoOutput(true);
//            httpURLConnection.setDoInput(true);
//            // 发送请求参数
//            JSONObject paramJson = new JSONObject();
//            paramJson.set("scene", scene);//这就是你二维码里携带的参数 String型  名称不可变
//            paramJson.set("page", indexPath); //这是设置扫描二维码后跳转的页面pages/home/home
//            paramJson.set("width", 1280);//默认430，二维码的宽度，单位 px，最小 280px，最大 1280 px
//            paramJson.set("is_hyaline", true);
//            paramJson.set("check_path", false);
//            paramJson.set("auto_color", true);
//            paramJson.set("env_version", enVersion);//正式版为 "release"，体验版为 "trial"，开发版为 "develop"。默认是正式版。
//            // 发送请求 获取URLConnection对象对应的输出流
//            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
//            printWriter.write(paramJson.toString());
//            printWriter.flush();
//            // 获取二维码图片流并保存
//            String linkUrl = fileApi.createFile(linkName, "", IoUtil.readBytes(httpURLConnection.getInputStream()));
//            // 返回生成的带文字的二维码图片文件名
//            return linkUrl;
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw exception0(30_003, e.getMessage());
//        }
        //TODO: 去掉
        return "";
    }

    public String getMiniLink(String scene, String indexPath) {
//        try {
//            //这里调用的是上面的获取access_token方法
//            String appId = configApi.getConfigValueByKey("wxMinAppId").getCheckedData();
//            String secret = configApi.getConfigValueByKey("wxMinAppSecret").getCheckedData();
//            String enVersion = configApi.getConfigValueByKey("enVersion").getCheckedData();
//            String access_token = getWxAccessToken(appId, secret);
//            System.err.println("access_token:"+access_token);
//            if(access_token==null){
//                return "";
//            }
//            JSONObject jsonBody = new JSONObject();
//            jsonBody.put("path", indexPath);
//            jsonBody.put("expire_type", 1+"");
//            jsonBody.put("expire_interval", 30+"");
//            jsonBody.put("query", scene+"");
//            jsonBody.put("env_version", enVersion+"");
//
//            String result = sendPost("https://api.weixin.qq.com/wxa/generate_urllink?access_token=" + access_token, jsonBody.toString());
//            log.info("【小程序链接】，jsonBody:{}, result:{}", jsonBody, result);
//            com.alibaba.fastjson.JSONObject jsonObject1 = com.alibaba.fastjson.JSONObject.parseObject(result);
//            Integer errcode1 = jsonObject1.getInteger("errcode");
//            if (0 == errcode1) {
//                String urlLink = jsonObject1.getString("url_link");
//                if (org.apache.commons.lang3.StringUtils.isEmpty(urlLink)) {
//                    return "";
//                }
//                return urlLink;
//            }
//            // 返回生成的带文字的二维码图片文件名
//            return "";
//        } catch (Exception e) {
//            e.printStackTrace();
//            return "";
//        }
        //TODO: 去掉
        return "";
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param)
    {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try
        {
            log.info("sendPost - {}", url);
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            }
            catch (IOException ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    private String getMiniQrCode(Long id, String linkName) {
//        try {
//            String appId = configApi.getConfigValueByKey("wxMinAppId").getCheckedData();
//            String secret = configApi.getConfigValueByKey("wxMinAppSecret").getCheckedData();
//            String indexPath = configApi.getConfigValueByKey("indexPath").getCheckedData();
//            //这里调用的是上面的获取access_token方法
//            String access_token = getWxAccessToken(appId, secret);
//            URL url = new URL("https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + access_token);
//            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//            httpURLConnection.setRequestMethod("POST");// 提交模式
//            httpURLConnection.setConnectTimeout(10000);//连接超时 单位毫秒
//            httpURLConnection.setReadTimeout(2000);//读取超时 单位毫秒
//            // 发送POST请求必须设置如下两行
//            httpURLConnection.setDoOutput(true);
//            httpURLConnection.setDoInput(true);
//            JSONObject paramJson = new JSONObject();
//            paramJson.set("width", 1280);//这就是你二维码里携带的参数 String型  名称不可变
//            paramJson.set("path", indexPath + "?linkId=" + id); //这是设置扫描二维码后跳转的页面pages/home/home
//            // 发送请求
//            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
//            printWriter.write(paramJson.toString());
//            printWriter.flush();
//            // 获取二维码图片流并保存
//            String linkUrl = fileApi.createFile(linkName, "", IoUtil.readBytes(httpURLConnection.getInputStream()));
//            // 返回生成的带文字的二维码图片文件名
//            return linkUrl;
//        } catch (Exception e) {
//            throw exception0(30_003, e.getMessage());
//        }
        //TODO: 去掉
        return "";
    }

    public String getWxAccessToken(String wxAppId, String wxAppKey) {
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxAppId + "&secret=" + wxAppKey;
        try {
            String jsonStr = HttpUtil.get(tokenUrl);
            JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
            if (jsonObject.containsKey("access_token")) {
                return jsonObject.getStr("access_token");
            } else {
                throw exception0(30_003, jsonObject.getStr("errmsg"));
            }
        } catch (Exception e) {
            throw exception0(30_003, "请求微信公众平台发生异常");
        }
    }
}
