package org.jeecg.modules.apiservice.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.shiro.ShiroRealm;
import org.jeecg.modules.apiBean.OrderPayBean;
import org.jeecg.modules.apiBean.OrderWaterPageBean;
import org.jeecg.modules.apiUtils.HttpClientUtil;
import org.jeecg.modules.apiUtils.WxQrCodeVo;
import org.jeecg.modules.apiUtils.printUtil;
import org.jeecg.modules.apiUtils.printUtils;
import org.jeecg.modules.apiUtils.printUtilTwo;
import org.jeecg.modules.apiservice.CheerTwoService;
import org.jeecg.modules.bean.ShopOrderPageBean;
import org.jeecg.modules.bean.ShopPageBean;
import org.jeecg.modules.cheerAdmin.entity.CheerAdmin;
import org.jeecg.modules.cheerAdmin.service.ICheerAdminService;
import org.jeecg.modules.cheerConf.entity.CheerConf;
import org.jeecg.modules.cheerConf.service.ICheerConfService;
import org.jeecg.modules.cheerPrinter.entity.CheerPrinter;
import org.jeecg.modules.cheerPrinter.service.ICheerPrinterService;
import org.jeecg.modules.cheerRecharge.entity.CheerRecharge;
import org.jeecg.modules.cheerRecharge.service.ICheerRechargeService;
import org.jeecg.modules.cheerShop.entity.CheerShop;
import org.jeecg.modules.cheerShop.service.ICheerShopService;
import org.jeecg.modules.cheerWater.entity.CheerWater;
import org.jeecg.modules.cheerWater.service.ICheerWaterService;
import org.jeecg.modules.hanHaiMember.entity.HanHaiMember;
import org.jeecg.modules.hanHaiMember.service.IHanHaiMemberService;
import org.jeecg.modules.pay.MpWxPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class CheerTwoServiceImpl implements CheerTwoService {
    //权限验证
    @Resource
    private ShiroRealm shiroRealm;
    //获取加油站信息
    @Resource
    private ICheerShopService cheerShopService;
    @Resource
    private ICheerPrinterService cheerPrinterService;
    @Resource
    private ICheerRechargeService cheerRechargeService;
    @Resource
    private ICheerWaterService cheerWaterService;
    @Resource
    private ICheerAdminService cheerAdminService;
    @Resource
    private ICheerConfService cheerConfService;
    //支付接口
    @Autowired
    private MpWxPayService mpWxPayService;
    //缓存记录
    @Resource
    private RedisUtil redisUtil;
    @Value("${wechat.mpAppId}")
    private String appid;
    @Value("${wechat.mpAppSecret}")
    private String secret;
    @Value("${jeecg.oss.endpoint}")
    private String endpoint;
    @Value("${jeecg.oss.accessKey}")
    private String accessKey;
    @Value("${jeecg.oss.secretKey}")
    private String secretKey;
    @Value("${jeecg.oss.bucketName}")
    private String bucketName;

    //获取个人信息接口
    @Resource
    private IHanHaiMemberService hanHaiMemberService;


    //获取加油站列表带分页
    @Override
    public Result<?> getGasStationList(ShopPageBean bean){

        Page<CheerShop> page = new Page<CheerShop>(bean.getPageNo(), bean.getPageSize());
        Page<CheerShop> page1 = cheerShopService.lambdaQuery()
                .eq(CheerShop::getIsOpen, "Y")
                .orderByDesc(CheerShop::getCreateTime)
                .page(page);
        return Result.OK("加油站列表数据",page1);
    }


    //根据加油站标识获取加油站充值套餐信息
    @Override
    public Result<?> getRechargeList(ShopOrderPageBean bean){

        Page<CheerRecharge> page = new Page<CheerRecharge>(bean.getPageNo(), bean.getPageSize());
        Page<CheerRecharge> page1 = cheerRechargeService.lambdaQuery()
                .eq(CheerRecharge::getShopId, bean.getId())
                .page(page);
        return Result.OK("加油站充值套餐信息",page1);
    }



    //根据加油站标识获取相关配置信息
    @Override
    public Result<?> getConfig(String shopId){
        CheerShop byId = cheerShopService.getById(shopId);
        return Result.OK("配置信息",byId);
    }


    //获取订单列表带分页
    @Override
    public Result<?> getOrderWaterPage(String token, OrderWaterPageBean bean){
        HanHaiMember hanHaiMember = shiroRealm.checkUserTokenIsEffectHanHaiOpenId(token);
        Page<CheerWater> page = new Page<CheerWater>(bean.getPageNo(), bean.getPageSize());
        Page<CheerWater> page1 = cheerWaterService.lambdaQuery()
                .eq(CheerWater::getUserId, hanHaiMember.getId())
                .eq(CheerWater::getState, "1")
                .orderByDesc(CheerWater::getCreateTime)
                .page(page);
        //获取当前订单信息
        List<CheerWater> records = page1.getRecords();
        //创建新的集合
        List<CheerWater> newList = new ArrayList<>();
        for (CheerWater cheerWater : records) {
            CheerShop cheerShop = cheerShopService.getById(cheerWater.getShopId());
            cheerWater.setShopId(cheerShop.getName());
            newList.add(cheerWater);
        }
        page1.setRecords(newList);
        return Result.OK("加油流水",page1);
    }




    //加油小程序-用户输入支付创建支付订单并且支付
    @Override
    public Result<?> createOrderPay(String token, OrderPayBean bean){
        HanHaiMember hanHaiMember = shiroRealm.checkUserTokenIsEffectHanHaiOpenId(token);
        //当前加油站未配置打印机
        CheerShop byId = cheerShopService.getById(bean.getShopId());
        //根据打印机标识查询是否有打印机
        CheerPrinter byId1 = cheerPrinterService.getById(byId.getPrinterId());
        if(byId1 == null){
            return Result.error("当前加油站未配置打印机");
        }



        //判断输入金额是否为空
        if(bean.getMoney() == null){
            return Result.error("支付金额不能为空");
        }
        //判断加油站标识不能为空
        if(bean.getShopId() == null){
            return Result.error("加油站标识不能为空");
        }
        //根据加油站标识查询相关信息
        CheerShop cheerShop = cheerShopService.getById(bean.getShopId());
        //判断当前信息不能为空
        if(cheerShop == null){
            return Result.error("加油站信息不存在");
        }
        if(cheerShop.getIsOpen().equals("N")){
            return Result.error("当前加油站已关闭");
        }
        BigDecimal oldMoney = bean.getMoney();
        //支付金额不能为0
        if(bean.getMoney().compareTo(new BigDecimal(0)) == 0){
            return Result.error("支付金额不能为0");
        }
        //支付金额不能为负数
        if(bean.getMoney().compareTo(new BigDecimal(0)) == -1){
            return Result.error("支付金额不能为负数");
        }
        //获取当前折扣
        BigDecimal discount = cheerShop.getPreferential();
        //保留小数点后两位
        BigDecimal money = bean.getMoney().divide(discount).setScale(2, BigDecimal.ROUND_HALF_UP);

        //创建订单流水
        CheerWater cheerWater = new CheerWater();
        cheerWater.setShopId(bean.getShopId());
        cheerWater.setUserId(hanHaiMember.getId());
        cheerWater.setOldPrice(money);
        cheerWater.setPrice(oldMoney);
        cheerWater.setState("0");
        cheerWater.setCreateTime(new Date());
        cheerWater.setName(cheerShop.getTitle());
        cheerWater.setUserHead(hanHaiMember.getHeadImage());
        cheerWaterService.save(cheerWater);



        //吊起微信支付
        String s = bean.getMoney().multiply(new BigDecimal(100)).toString();
        int i1 = Double.valueOf(s).intValue();
        Object appOrder = mpWxPayService.createOrderGo(
                "购买"+cheerWater.getName() ,
                "127.0.0.1",
                cheerWater.getId(),
                i1,
                cheerWater.getId(),
                hanHaiMember.getAppletOpenid(),
                cheerWater.toString());



        return Result.OK("支付成功",appOrder);
    }



    //查询当前用户是否是管理员
    @Override
    public Result<?> isAdmin( String token){
        HanHaiMember hanHaiMember = shiroRealm.checkUserTokenIsEffectHanHaiOpenId(token);
//        CheerAdmin one = cheerAdminService.lambdaQuery()
//                .eq(CheerAdmin::getUserId, hanHaiMember.getId())
//                .one();
        CheerShop one = cheerShopService.lambdaQuery()
                .eq(CheerShop::getUserId, hanHaiMember.getId())
                .one();
        return Result.OK(one);
    }



    //获取推广二维码
    @Override
    public Result<?> getQrCode(String token){
        HanHaiMember member = shiroRealm.checkUserTokenIsEffectHanHaiOpenId(token);
        //根据用户标识查询用户是否是管理员
        CheerAdmin one = cheerAdminService.lambdaQuery()
                .eq(CheerAdmin::getUserId, member.getId())
                .one();
        if(one == null){
            return Result.error("当前用户不是管理员");
        }

        CheerConf vsion = cheerConfService.lambdaQuery()
                .eq(CheerConf::getKeyValue, "v_sion")
                .one();
        Integer vsionStr = Integer.parseInt(vsion.getKeyCentent());
        String trial = "release";
        if(vsionStr == 0){
            trial= "release";
        }else if(vsionStr == 1){
            trial= "trial";
        }else{
            trial= "develop";
        }

//        WxQrCodeVo o = (WxQrCodeVo)redisUtil.get("CodeImage::" + trial+ member.getId());
//        if(o!=null){
//            CheerShop cheerShop = cheerShopService.lambdaQuery()
//                    .eq(CheerShop::getUserId, member.getId())
//                    .one();
//
//            o.setName(cheerShop.getName());
//            return Result.OK(o);
//        }
//        LambdaQueryWrapper<DbConf> config = new LambdaQueryWrapper<>();
//        config.eq(DbConf::getIsDel,0).eq(DbConf::getKeyValue,"xcxSharePage");
//        DbConf one = confService.getOne(config);
//        String xcxSharePage = one.getValue();
        Map<String, Object> param = new HashMap<>();

        CheerConf xcxSharePage = cheerConfService.lambdaQuery()
                .eq(CheerConf::getKeyValue, "xcxSharePage")
                .one();





        String key = "shareId=" + one.getShopId();

        param.put("path", xcxSharePage.getKeyCentent() + "?" + key); //跳转页面
        String accessToken = this.getAccessToken();
        RestTemplate rest = new RestTemplate();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        File file = null;

//        LambdaQueryWrapper<DbConf> configImg = new LambdaQueryWrapper<>();
//        configImg.eq(DbConf::getIsDel,0).eq(DbConf::getKeyValue,"codeImg");
//        DbConf oneImg = confService.getOne(configImg);

        CheerConf oneImage = cheerConfService.lambdaQuery()
                .eq(CheerConf::getKeyValue, "codeImg")
                .one();




        String codeImg = oneImage.getKeyCentent();
        try{
            String url = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken;
            param.put("scene", one.getShopId());
            param.put("width", 150);
            param.put("auto_color", false);
            param.put("env_version", trial);
            Map<String, Object> line_color = new HashMap<>();
            line_color.put("r", 0);
            line_color.put("g", 0);
            line_color.put("b", 0);
            param.put("line_color", line_color);
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            org.springframework.http.HttpEntity requestEntity = new org.springframework.http.HttpEntity(JSON.toJSONString(param), headers);
            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            byte[] result = entity.getBody();

            inputStream = new ByteArrayInputStream(result);
            String tempSave = codeImg;
            String filePath = tempSave;
            log.info("文件临时存储路径，{}", filePath);
            file = new File(filePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            outputStream = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.flush();
            /**
             * 将文件上传至阿里云
             */
            DiskFileItemFactory factory = new DiskFileItemFactory(16, null);
            FileItem item = factory.createItem("File", "text/plain", true, file.getName());
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            try {
                FileInputStream fis = new FileInputStream(file);
                OutputStream os = item.getOutputStream();
                while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            MultipartFile mf = new CommonsMultipartFile(item);
            //返回图片下载地址
            WxQrCodeVo wxCodeVo = new WxQrCodeVo();
            wxCodeVo.setUrl(this.uploadAliYunOss(mf));


            CheerShop cheerShop = cheerShopService.lambdaQuery()
                    .eq(CheerShop::getUserId, member.getId())
                    .one();


            wxCodeVo.setName(cheerShop.getName());

//            redisUtil.set("CodeImage::"+trial+member.getId(),wxCodeVo);
            return Result.OK(wxCodeVo);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //删除文件
            if (file.exists()) {
                file.delete();
            }
        }
        return null;
    }


    /**
     * 获取令牌
     *
     * @return
     */
    private String getAccessToken() {
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
        String doGet2 = HttpClientUtil.doGet2(requestUrl);
        Map<String, String> map = JSON.parseObject(doGet2, new TypeReference<Map<String, String>>() {
        });
        return map.get("access_token");
    }
    /**
     * 上传文件至阿里云oss
     *
     * @return
     */
    private String uploadAliYunOss(MultipartFile mf) throws Exception {
        String uploadFile = "WxCodeFile";
        String fileName = new StringBuffer(mf.getOriginalFilename()).append(".jpg").toString();// 获取文件名
        String dbpath = uploadFile + File.separator + fileName;
        if (dbpath.contains("\\")) {
            dbpath = dbpath.replace("\\", "/");
        }
        String endpoint = this.endpoint;
        String accessKey = this.accessKey;
        String secretKey = this.secretKey;
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey);
        // 上传Byte数组。
        byte[] content = mf.getBytes();
        String bucketName = this.bucketName;
        ossClient.putObject(bucketName, dbpath, new ByteArrayInputStream(content));
        // 关闭OSSClient。
        ossClient.shutdown();
        return dbpath;
    }



    //支付回调
    @Override
    public Object createNotify(String requestBody){
        WxPayOrderNotifyResult notify = mpWxPayService.notify(requestBody);

        String outTradeNo = notify.getOutTradeNo();

        //开始处理业务逻辑
        CheerWater  byId = cheerWaterService.getById(outTradeNo);

        if(byId!=null){
            if(!byId.getState().equals("1")){
                cheerWaterService.lambdaUpdate()
                        .set(CheerWater::getState,"1")
                        .eq(CheerWater::getId,outTradeNo)
                        .update();

                //根据流水中的用户标识查询用户信息
                HanHaiMember hanHaiMember = hanHaiMemberService.getById(byId.getUserId());

//                //根据配置信息获得当前单价
//                CheerConf price = cheerConfService.lambdaQuery()
//                        .eq(CheerConf::getKeyValue,"price")
//                        .one();
//
//                //根据配置信息获得当前
//                CheerConf title = cheerConfService.lambdaQuery()
//                        .eq(CheerConf::getKeyValue,"title")
//                        .one();
//
//                //获取配置中的打印次数
//                CheerConf num = cheerConfService.lambdaQuery()
//                        .eq(CheerConf::getKeyValue,"num")
//                        .one();

                //获取店铺信息
                CheerShop cheerShop = cheerShopService.lambdaQuery()
                        .eq(CheerShop::getId,byId.getShopId())
                        .one();

                //根据打印机标识获取打印机信息
                CheerPrinter cheerPrinter = cheerPrinterService.lambdaQuery()
                        .eq(CheerPrinter::getId,cheerShop.getPrinterId())
                        .one();

                //拼接打印信息
                String content = printUtils.spellMessage(
                        hanHaiMember.getNickName(),
                        byId.getOldPrice().toString(),
                        byId.getPrice().toString(),
                        cheerShop.getTitle(),
                        cheerShop.getPrice()
                );

                //客户要求打印两次
                for (int i = 0; i < cheerShop.getNum(); i++){
//                    System.out.println("打印第"+i+"次");
//                    System.out.println("打印内容："+content);
//                    System.out.println("打印机sn："+cheerPrinter.getSn());
//                    System.out.println("打印机snList："+cheerPrinter.getSnList());
//                    System.out.println("打印机url："+cheerPrinter.getUrl());
//                    System.out.println("打印机user："+cheerPrinter.getUser());
//                    System.out.println("打印机ukey："+cheerPrinter.getUserKey());

                    if(cheerPrinter.getSn().equals("222539759")){
                        printUtilTwo.printBill(content);
                    }else{
                        printUtil.printBill(content);
                    }



//                    printUtils.printBill(content,cheerPrinter.getSn(),cheerPrinter.getSnList(),cheerPrinter.getUrl(),cheerPrinter.getUser(),cheerPrinter.getUserKey());
                }


            }
        }
        return null;
    }


}
