package org.dromara.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lakala.zf.laop.java.sdk.demo.BaseCommonDemo;
import com.lkl.laop.sdk.LKLSDK;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.system.domain.SysUser;
import org.dromara.system.service.ISysUserService;
import org.dromara.work.domain.TpOrderPay;
import org.dromara.work.domain.bo.TpOrderPayBo;
import org.dromara.work.domain.bo.TpUserRecordBo;
import org.dromara.work.service.ITpOrderPayService;
import org.dromara.work.service.ITpOrderService;
import org.dromara.work.service.ITpUserRecordService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 回调接口
 * @author Maosw
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/callback")
@Tag(name = "回调接口")
public class ApiCallbackController extends BaseCommonDemo {

    private final ITpOrderService tpOrderService;

    private final ITpOrderPayService tpOrderPayService;

    private final ITpUserRecordService tpUserRecordService;

    private final ISysUserService tzUserService;

    /**
     * DD画图订单回调地址
     */
    @RequestMapping("/order")
    @RepeatSubmit(interval = 1, timeUnit = TimeUnit.SECONDS, message = "重复请求")
    public Map<String, String> order(HttpServletRequest request) throws Exception {
        System.out.println("DD画图订单回调开始...");
        // 1. 配置初始化
        doInit();
        LKLSDK.notificationHandle(request);

        String body = getBody(request);
        // 业务处理
        JSONObject respData = JSON.parseObject(body);

        String orderNo = respData.getString("out_order_no");
        String payOrderNo = respData.getString("pay_order_no");
        String orderStatus = respData.getString("order_status");
        JSONObject jsonObject = respData.getJSONObject("order_trade_info");
        String tradeNo = jsonObject.getString("trade_no");
        String logNo = jsonObject.getString("log_no");

        if ("2".equals(orderStatus)) {
            TpOrderPay orderPay = tpOrderPayService.queryByOrderNo(orderNo, payOrderNo);
            if (orderPay == null) {
                throw new RuntimeException("支付订单不存在");
            }
            boolean result = tpOrderService.callbackOrder(orderPay.getId(),orderPay,tradeNo,logNo,respData);
            if (result) {
                return getKlkCommonResp();
            }
        }
        return null;
    }


    /**
     * 余额充值订单回调地址
     */
    @RequestMapping("/rechargeOrder")
    @RepeatSubmit(interval = 1, timeUnit = TimeUnit.SECONDS, message = "重复请求")
    public Map<String, String> rechargeOrder(HttpServletRequest request) throws Exception {
        System.out.println("余额充值订单回调地址回调开始...");
        // 1. 配置初始化
        doInit();
        LKLSDK.notificationHandle(request);

        String body = getBody(request);
        // 业务处理
        JSONObject respData = JSON.parseObject(body);

        String orderNo = respData.getString("out_order_no");
        String payOrderNo = respData.getString("pay_order_no");
        String orderStatus = respData.getString("order_status");
        JSONObject jsonObject = respData.getJSONObject("order_trade_info");
        String tradeNo = jsonObject.getString("trade_no");
        String logNo = jsonObject.getString("log_no");

        if ("2".equals(orderStatus)) {
            TpOrderPay orderPay = tpOrderPayService.queryByOrderNo(orderNo, payOrderNo);
            if (orderPay == null) {
                throw new RuntimeException("支付订单不存在");
            }

            //更新用户余额
            SysUser tzUser = tzUserService.queryById(orderPay.getUserId());
            tzUser.setYue(tzUser.getYue().add(orderPay.getAmount()));
            if (!tzUserService.updateById(tzUser)) {
                throw new RuntimeException("充值用户余额失败");
            }

            //新增用户资金记录
            TpUserRecordBo bo = new TpUserRecordBo();
            bo.setUserId(orderPay.getUserId());
            bo.setUserName(tzUser.getUserName());
            bo.setUserPhone(tzUser.getPhonenumber());
            bo.setAmount(orderPay.getAmount());
            bo.setType(1);
            bo.setBalance(tzUser.getYue());
            bo.setRemark("余额充值");
            tpUserRecordService.insertByBo(bo);

            //更新支付订单
            TpOrderPayBo orderPayBo = new TpOrderPayBo();
            orderPayBo.setId(orderPay.getId());
            orderPayBo.setStatus(2);
            orderPayBo.setPayerInfo(String.valueOf(respData));
            boolean result = tpOrderPayService.updateByBo(orderPayBo);
            if (result) {
                return getKlkCommonResp();
            }
        }
        return null;
    }


    /*@RequestMapping("/applyBind")
    @Operation(summary = "分账关系绑定申请回调" , description = "分账关系绑定申请回调")
    public Map<String, String> applyBind(@RequestBody String requestBody) throws Exception {
        System.out.println("分账关系绑定结果开始回调...");
        // 1. 配置初始化
        doInit();
        //业务处理
        JSONObject jsonObject = JSON.parseObject(requestBody);
        String receiverNo = jsonObject.getString("receiverNo");
        TzBankCard bankCard = bankCardService.queryByReceiverNo(receiverNo);
        if ("1".equals(jsonObject.getString("auditStatus"))) {
            // 绑定成功
            bankCard.setStatus(1);

            //提款模式设置
            V2LaepIndustryEwalletSettleProfileRequest ewalletSettleProfileRequest = new V2LaepIndustryEwalletSettleProfileRequest();
            ewalletSettleProfileRequest.setBmcpNo(KlkConstant.ORG_CODE);
            ewalletSettleProfileRequest.setMercId(receiverNo);
            ewalletSettleProfileRequest.setSettleType("02");
            ewalletSettleProfileRequest.setPayType("04");
            V3LakalaUserUtils.setWithdrawMode(ewalletSettleProfileRequest);

        } else {
            bankCard.setStatus(2);
            bankCard.setRemark(jsonObject.getString("remark"));
        }
        if (!bankCardService.updateById(bankCard)) {
            throw new RuntimeException("绑定银行卡回调更新数据失败");
        }
        return getKlkCommonResp();
    }*/

    /**
     * 提现结果回调处理
     */
    /*@RequestMapping("/withdrawal")
    public Map<String, String> withdrawal(@RequestBody String requestBody) throws Exception {
        System.out.println("提现结果开始回调...");

        // 1. 配置初始化
        doInit();
        //业务处理
        JSONObject respData = JSON.parseObject(requestBody);
        String separateNo = respData.getString("separate_no");
        String outSeparateNo = respData.getString("out_separate_no");
        String finalStatus = respData.getString("final_status");
        String cmdType = respData.getString("cmd_type");

        if("SEPARATE".equals(cmdType)){
            TzWithdrawRequest withdrawRequest = withdrawRequestService.queryWithdrawRequest(separateNo, outSeparateNo);
            if (withdrawRequest != null) {
                if("SUCCESS".equals(finalStatus)){
                    withdrawRequest.setWithdrawStatus(3);
                    withdrawRequestService.updateById(withdrawRequest);
                    return getKlkCommonResp();
                }
            }
        }
        return null;
    }*/

    /**
     * 会员兑换码订单回调地址
     */
    /*@RequestMapping("/codeOrder")
    public Map<String, String> codeOrder(@RequestBody String requestBody) throws Exception {
        System.out.println("会员兑换码订单开始回调...");
        // 1. 配置初始化
        doInit();
        //业务处理
        JSONObject respData = JSON.parseObject(requestBody);
        String orderNo = respData.getString("out_order_no");
        String payOrderNo = respData.getString("pay_order_no");
        String orderStatus = respData.getString("order_status");

        if ("2".equals(orderStatus)) {
            HyCodeOrder codeOrder = codeOrderService.queryByOrderNo(orderNo, payOrderNo);
            boolean result = codeOrderService.generateMemberCodes(codeOrder.getId());
            if (result) {
                return getKlkCommonResp();
            }
        }
        return null;
    }*/


    /**
     * 读取请求头
     */
    private String getAuthorization(HttpServletRequest request) {
        return request.getHeader("Authorization");
    }

    /**
     * 读取请求体
     */
    private String getBody(HttpServletRequest request) {
        try (InputStreamReader in = new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8)) {
            StringBuilder bf = new StringBuilder();
            int len;
            char[] chs = new char[1024];
            while ((len = in.read(chs)) != -1) {
                bf.append(new String(chs, 0, len));
            }
            return bf.toString();
        } catch (Exception e) {
            throw new RuntimeException("读取body失败");
        }

    }

    private Integer getWithdrawalStatus(String drawState) {
        //提现状态：1-处理中 2-已受理 3-成功 4-失败 5-冻结 -1-未关联卡拉卡平台
        if ("DRAW.PROCESSING".equals(drawState)) {
            return 1;
        } else if ("DRAW.ACCEPTED".equals(drawState)) {
            return 2;
        } else if ("DRAW.SUCCESS".equals(drawState)) {
            return 3;
        } else if ("DRAW.FAILED".equals(drawState)) {
            return 4;
        } else if ("DRAW.FREEZE".equals(drawState)) {
            return 5;
        } else {
            return -1;
        }
    }

    /**
     * 卡拉卡回调统一响应
     * {
     *     "code":"SUCCESS",
     *     "message":"执行成功"
     * }
     */
    public Map<String, String> getKlkCommonResp() {
        Map<String, String> map = new HashMap<>();
        map.put("code", "SUCCESS");
        map.put("message", "执行成功");
        return map;
    }

}
