package com.hys.app.controller.erp.use;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.framework.util.DateUtil;
import com.hys.app.framework.util.JsonUtil;
import com.hys.app.framework.util.ScriptUtil;
import com.hys.app.framework.util.StringUtil;
import com.hys.app.mapper.system.AdminUserMapper;
import com.hys.app.mapper.system.RoleMapper;
import com.hys.app.model.erp.dos.OrderCustomerFee;
import com.hys.app.model.erp.dos.OrderDO;
import com.hys.app.model.erp.dto.PayTypeUrl;
import com.hys.app.model.erp.entity.CompanyErp;
import com.hys.app.model.system.dos.AdminUser;
import com.hys.app.model.system.dos.RoleDO;
import com.hys.app.model.system.vo.Menus;
import com.hys.app.pay.ali.AliPayService;
import com.hys.app.pay.ali.PayOrder;
import com.hys.app.pay.wx.WxPayServiceMy;
import com.hys.app.service.erp.CompanyErpManager;
import com.hys.app.service.erp.OrderCustomerFeeManager;
import com.hys.app.service.erp.OrderManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/erp/pay")
@Api(tags = "订单支付")
@Validated
@AllArgsConstructor
public class PayController extends HttpServlet {
    private OrderManager orderManager;
    private AliPayService aliPayService;
    private WxPayServiceMy wxPayServiceMy;
    private OrderCustomerFeeManager orderCustomerFeeManager;
    private CompanyErpManager companyManager;
    private AdminUserMapper adminUserMapper;
    private RoleMapper roleMapper;

    private static final Logger log = LoggerFactory.getLogger(ScriptUtil.class);


    @ApiOperation(value = "扫描完获取拉起支付的url")
    @PostMapping("/getPayUrl")
    public Object getListByScan(@RequestBody @Validated PayTypeUrl payTypeUrl) throws UnknownHostException, WxPayException {
        CompanyErp company = companyManager.getById(payTypeUrl.getId());
        if (ObjectUtil.isNull(company)) {
            throw new ServiceException("未查询到公司信息");
        }
        PayOrder payOrder = new PayOrder();
        payOrder.setTraceNo(company.getId().toString());
        payOrder.setSubject("购买公司使用权账号");
        payOrder.setTimeExpire(LocalDateTime.now().plusMinutes(30));
        payOrder.setTotalAmount(company.getThisMoney().doubleValue());
        payOrder.setOrderPayType("company");
        switch (payTypeUrl.getPayType()) {
            case "ali":
                return aliPayService.pay(payOrder);
            case "wx":
                return "暂未开通";
            default:
                return "不支持的支付方式";
        }
    }

    @PostMapping("/aliReturnCall")
    @Transactional(rollbackFor = Exception.class)
    public String aliReturnCall(HttpServletRequest request) throws Exception {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = String.join(",", values);
            params.put(name, valueStr);
        }
        if (aliPayService.checkReturnParam(params)) {
            String passbackParams = URLDecoder.decode(params.get("passback_params"), "UTF-8");
            if ("company".equals(passbackParams)) {
                CompanyErp company = companyManager.getById(params.get("out_trade_no"));
                //如果结束时间大于当前时间，那么就从现在加起
                Date currentDate = company.getEndUseTime();
                if (new Date().compareTo(company.getEndUseTime()) > 0) {
                    currentDate = new Date();

                }
                // 使用 加上套餐包的天数
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(currentDate);
                calendar.add(Calendar.DAY_OF_MONTH, company.getThisDay());

                company.setEndUseTime(calendar.getTime());
                company.setMoney(company.getMoney().add(company.getThisMoney()));
                company.setRoleId(company.getThisRoleId());
                company.setUserNum(company.getThisUserNum());
                company.setCompanyPackageId(company.getThisCompanyPackageId());

                company.setThisDay(0);
                company.setThisCompanyPackageId(0L);
                company.setThisMoney(new BigDecimal(0));
                company.setThisRoleId(0L);
                company.setThisUserNum(0);

                companyManager.updateById(company);
//                //  不管换没换套餐  把新的套餐权限赋值到公司的admin账号上
                AdminUser user = adminUserMapper.selectOne(new LambdaQueryWrapper<AdminUser>()
                        .eq(AdminUser::getCompanyId, company.getId())
                        .eq(AdminUser::getUsername, "admin").last("limit 1"));
                //把这个管理员能看到的所有页面保存起来
                RoleDO roleDO = roleMapper.selectById(company.getThisRoleId());
                List<Menus> menus = JsonUtil.jsonToList(roleDO.getAuthIds(), Menus.class);
                List<Menus> collect = menus.stream().filter(Menus::isChecked).collect(Collectors.toList());
                user.setAuthIds(JSON.toJSONString(collect));
                adminUserMapper.updateById(user);
            }
        }
        return "success";
    }

    @PostMapping("/wxpay/notify")
    public String parseOrderNotify(@RequestBody String xmlData) {
        try {
            System.out.println("微信支付回调来了啊+11111111111111111111111111111111111111111111111111111111111");
            WxPayServiceImpl wxPayService = new WxPayServiceImpl();
            // 解析支付通知结果
            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            // 处理订单逻辑
            if ("SUCCESS".equals(notifyResult.getResultCode().toUpperCase())) {
                // 支付成功
                OrderDO aDo = orderManager.getById(notifyResult.getOutTradeNo());
                aDo.setHasPayReturn(true);
                orderManager.updateById(aDo);
                // 返回成功响应给微信服务器
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            }
        } catch (WxPayException e) {
            // 处理解析异常，记录日志
            e.printStackTrace();
        }
        return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[解析失败]]></return_msg></xml>";
    }

    @PostMapping("getOpenIdCode/{orderId}")
    public String getOpenIdCode(@PathVariable Long orderId, @RequestBody @Validated Map map) throws UnsupportedEncodingException {
        String openIdCode = wxPayServiceMy.getOpenIdCode(orderId, map.get("ip").toString());
        System.out.println("授权地址+“--------------------------------------------------------" + openIdCode + "ip-----------------" + map.get("ip").toString());
        return wxPayServiceMy.getOpenIdCode(orderId, map.get("ip").toString());
    }

    @GetMapping("/weixin/callback/openidCode")
    public void handleWeixinCallback(@RequestParam("code") String code, @RequestParam("state") String state, HttpSession session, HttpServletResponse response) throws Exception {
        System.out.println("授权回调来了啊    code=" + code + "-111111111111111111111111111111111111111111111state=" + state);
        String[] split = state.split("--");
        String orderId = split[0];
        String ip = split[1];
        if (!state.equals((String) session.getAttribute("WEIXIN_OAUTH_STATE"))) {
            log.error("用户授权，state错误");
        }
        OrderDO aDo = orderManager.getById(Long.valueOf(orderId));
        if (ObjectUtil.isNull(aDo)) {
            log.error("用户授权完成后未找到订单信息：" + state);
        }
        String openId = wxPayServiceMy.getOpenId(code);
        aDo.setOpenId(openId);
        orderManager.updateById(aDo);

        double price;
        List<OrderCustomerFee> list = orderCustomerFeeManager.list(new LambdaQueryWrapper<OrderCustomerFee>().eq(OrderCustomerFee::getOrderId, aDo.getId()));
        if (CollectionUtil.isNotEmpty(list)) {
            price = new BigDecimal(aDo.getRealPrice()).add(list.stream().map(OrderCustomerFee::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add)).multiply(new BigDecimal(1 + aDo.getTaxRate() * 0.01)).doubleValue();
        } else {
            price = aDo.getRealPrice() * (1 + aDo.getTaxRate() * 0.01);
        }
        String url = ip + "#/payType?id=" + aDo.getId() + "&sn=" + aDo.getSn() + "&price=" + price + "&openid=" + openId;
        response.sendRedirect(url);
    }

//    @PostMapping("/aliReturnCall/createCompany")
//    @Transactional(rollbackFor = Exception.class)
//    public String aliReturnCallCreateCompany(HttpServletRequest request) throws Exception {
//        Map<String, String> params = new HashMap<>();
//        Map<String, String[]> requestParams = request.getParameterMap();
//        for (String name : requestParams.keySet()) {
//            String[] values = requestParams.get(name);
//            String valueStr = String.join(",", values);
//            params.put(name, valueStr);
//        }
//        if (aliPayService.checkReturnParam(params)) {
//            String passbackParams = URLDecoder.decode(params.get("passback_params"), "UTF-8");
//            if ("company".equals(passbackParams)){
//                CompanyErp company = companyManager.getById(params.get("out_trade_no"));
//                company.setEndUseTime(company.getEndUseTime().plusDays(company.getThisDay()));
//                company.setThisDay(null);
//                company.setThisMoney(null);
//                companyManager.updateById(company);
//                //给公司创建初始账号
//                String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
//                StringBuilder sb = new StringBuilder();
//                Random random = new Random();
//                for (int i = 0; i < 6; i++) {
//                    int index = random.nextInt(characters.length());
//                    sb.append(characters.charAt(index));
//                }
//                String password = sb.toString();
//
//                //管理员信息入库
//                AdminUser adminUser = new AdminUser();
//                adminUser.setCompanyId(company.getId());
//                adminUser.setUsername("admin");
//                adminUser.setRoleId(company.getRoleId());
//                adminUser.setFounder(0);
//                adminUser.setNickname(company.getName()+"管理员");
//                adminUser.setPassword(StringUtil.md5(password + adminUser.getUsername().toLowerCase()));
//                adminUser.setDateLine(DateUtil.getDateline());
//                adminUser.setUserState(0);
//                adminUserMapper.insert(adminUser);
//                //todo  用短信和邮件把账号密码发给用户
//            }
//        }
//        return "success";
//    }

    @GetMapping("/getIndustry")
    public WxMpTemplateIndustry getIndustry() throws WxErrorException {
        System.out.println("看一下行业----------------------------------------------------------------");
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId("wx51e98f2dee35237d");
        config.setSecret("13803c1b0d911e023c7da0b300cbce89");
        WxMpService   wxService = new WxMpServiceImpl();
        wxService.setWxMpConfigStorage(config);
        return wxService.getTemplateMsgService().getIndustry();
    }


}
