package org.dromara.zhishu.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import com.pdd.pop.sdk.common.util.JsonUtil;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.ISysUserService;
import org.dromara.system.service.IUserTransferService;
import org.dromara.zhishu.domain.vo.ShopVo;
import org.dromara.zhishu.domain.vo.UserAccountVo;
import org.dromara.zhishu.service.IShopService;
import org.dromara.zhishu.service.IUserAccountService;
import org.dromara.zhishu.util.InterfaceUtils;
import org.dromara.zhishu.util.WxPayUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.zhishu.domain.vo.UserRechargeVo;
import org.dromara.zhishu.domain.bo.UserRechargeBo;
import org.dromara.zhishu.service.IUserRechargeService;
import org.dromara.common.mybatis.core.page.TableDataInfo;

/**
 * 用户充值
 *
 * @author yxy
 * @date 2025-04-26
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/zhishu/userRecharge")
public class UserRechargeController extends BaseController {

    private final IUserRechargeService userRechargeService;
    private final ISysConfigService configService;
    private final IUserAccountService userAccountService;
    private final ISysUserService userService;
    private final IShopService shopService;


    /**
     * 查询用户充值列表
     */
    @SaCheckPermission("zhishu:userRecharge:list")
    @GetMapping("/list")
    public TableDataInfo<UserRechargeVo> list(UserRechargeBo bo, PageQuery pageQuery) {
        return userRechargeService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出用户充值列表
     */
    @SaCheckPermission("zhishu:userRecharge:export")
    @Log(title = "用户充值", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(UserRechargeBo bo, HttpServletResponse response) {
        List<UserRechargeVo> list = userRechargeService.queryList(bo);
        ExcelUtil.exportExcel(list, "用户充值", UserRechargeVo.class, response);
    }

    /**
     * 获取用户充值详细信息
     *
     * @param id 主键
     */
    @SaCheckPermission("zhishu:userRecharge:query")
    @GetMapping("/{id}")
    public R<UserRechargeVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(userRechargeService.queryById(id));
    }

    @GetMapping(value = "/configKey/{configKey}")
    public R<String> getConfigKey(@PathVariable String configKey) {
        return R.ok(configService.selectConfigByKey(configKey));
    }

    /**
     * 新增用户充值
     */
    @SaCheckPermission("zhishu:userRecharge:add")
    @Log(title = "用户充值", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody UserRechargeBo bo) {
        return toAjax(userRechargeService.insertByBo(bo));
    }

    @PostMapping("/userRechargeNoCommission")
    public R<Map> userRechargeNoCommission(@RequestBody UserRechargeBo bo){
        //支付方式 1 微信
        String type = bo.getRechargType();
        //充值金额 单位 元
        BigDecimal price = bo.getRechargPrice();
        //计算后金额 单位 分
        BigDecimal priceResult = price.multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP);

        bo.setCommission(BigDecimal.ZERO);

        //获取登录用户id
        String userId = LoginHelper.getUserId().toString();
        if(type.equals("1")){
            //换算手续费为 分
            bo.setRechargPrice(bo.getRechargPrice().multiply(new BigDecimal(100)));
            //创建任务
            bo.setUserId(Long.parseLong(userId));
            //状态 0 待支付 1 支付完成 2 支付过期
            bo.setStatus("0");
            userRechargeService.insertByBo(bo);
            String data = WxPayUtil.wxPay(bo.getId(),Integer.parseInt(priceResult.toString()),price.toString());

            String base64Str = WxPayUtil.generateQRCode(data);

            Map map = new HashMap();
            map.put("img",base64Str);
            map.put("id", bo.getId());
            return R.ok(map);
        }
        return R.fail("充值订单生成失败，请联系管理员");
    }

    @PostMapping("/userRecharge")
    public R<Map> userRecharge(@RequestBody UserRechargeBo bo){
        //支付方式 1 微信 2 线下支付  3 卡密支付
        String type = bo.getRechargType();
        //充值金额 单位 元
        BigDecimal price = bo.getRechargPrice();

        //获取登录用户id
        String userId = LoginHelper.getUserId().toString();

        if(type.equals("1")){
            //手续费  单位 元
            String commissionStr = new BigDecimal(configService.selectConfigByKey("becharge.commission")).divide(new BigDecimal(10000)).toString();
            BigDecimal commission = price.multiply(new BigDecimal(commissionStr));
            //计算后金额 单位 分
            BigDecimal priceResult = price.add(commission).multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP);
            //手续费换算单位为分
            commission = commission.multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP);

            if(commission.compareTo(new BigDecimal(0)) == 0){
                commission = new BigDecimal(1);
            }
            bo.setCommission(commission);



            //换算手续费为 分
            bo.setRechargPrice(bo.getRechargPrice().multiply(new BigDecimal(100)));
            //创建任务
            bo.setUserId(Long.parseLong(userId));
            //状态 0 待支付 1 支付完成 2 支付过期 3 审核中 4 审核通过 5 拒绝
            bo.setStatus("0");
            userRechargeService.insertByBo(bo);
            String data = WxPayUtil.wxPay(bo.getId(),Integer.parseInt(priceResult.toString()),price.toString());

            String base64Str = WxPayUtil.generateQRCode(data);

            Map map = new HashMap();
            map.put("img",base64Str);
            map.put("id", bo.getId());
            return R.ok(map);
        }else if (type.equals("2")){
            // 出账用户
            UserAccountVo billingAccountVo = userAccountService.queryById(Long.parseLong(bo.getBillingAccount()));
            // 入账用户
            UserAccountVo depositAccountVo = userAccountService.queryById(Long.parseLong(bo.getDepositAccount()));
            // 充值金额
            price = price.multiply(new BigDecimal(100));
            // 线下充值
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("rechargPrice",price);
            jsonObject.put("billingAccount",bo.getBillingAccount());
            jsonObject.put("billingTxt","【"+billingAccountVo.getAccountType()+"】"+"【"+billingAccountVo.getAccountName()+"】"+"【"+billingAccountVo.getAccount()+"】");
            jsonObject.put("depositAccount",bo.getDepositAccount());
            jsonObject.put("depositTxt","【"+depositAccountVo.getAccountType()+"】"+"【"+depositAccountVo.getAccountName()+"】"+"【"+depositAccountVo.getAccount()+"】");
            jsonObject.put("transactionId",bo.getTransactionId());
            jsonObject.put("remark",bo.getRemark());
            jsonObject.put("voucherImg",bo.getVoucherImg());

            String json = jsonObject.toString();
            bo.setAllDataStr(json);
            bo.setRechargPrice(price);
            bo.setLogTxt("入账账户："+jsonObject.get("depositTxt"));
            //状态 0 待支付 1 支付完成 2 支付过期 3 审核中 4 审核通过 5 拒绝
            bo.setStatus("3");
            userRechargeService.insertByBo(bo);
            return R.ok("提交充值订单成功");
        }else if (type.equals("3")){
            // 卡密支付
            String cardKey = bo.getCardKey();
            String result = InterfaceUtils.getInterface("https://wallet.api.buzhiyushu.cn","/api/card/activate/"+cardKey+"/ERP-"+userId);
            Map resultMap = JsonUtil.transferToObj(result,Map.class);
            String msg = resultMap.get("message").toString();
            String code = resultMap.get("code").toString();
            if (code.equals("200")){
                // 成功
                Map dataMap = (Map) resultMap.get("data");
                BigDecimal points = new BigDecimal(dataMap.get("points").toString()).multiply(new BigDecimal(100)).setScale(0, RoundingMode.DOWN); // 直接舍弃小数部分;
                SysUserVo userVo = userService.selectUserById(Long.parseLong(userId));
                BigDecimal newPrice =  userVo.getBalance().add(points);
                bo.setRechargPrice(points);
                bo.setStatus("1");
                bo.setLogTxt("卡密："+cardKey);
                bo.setOriginalPrice(userVo.getBalance());
                bo.setUpdatePrice(newPrice);
                bo.setSuccessTime(DateUtils.getNowDate());
                userRechargeService.insertByBo(bo);
                SysUserBo userBo = new SysUserBo();
                userBo.setUserId(userVo.getUserId());
                userBo.setBalance(newPrice);
                userService.updateUser(userBo);
                return R.ok(msg);
            }else{
                return R.fail(500,"支付失败："+msg);
            }
        }

        return R.fail("充值订单生成失败，请联系管理员");
    }


    @PostMapping("/balancePayment")
    public R<Map> balancePayment(@RequestBody Map map){
        Long userId = map.get("userId") == null ? LoginHelper.getUserId() : Long.parseLong(map.get("userId").toString());
        Long shopId = map.get("shopId") == null ? null : Long.parseLong(map.get("shopId").toString());
        int logType = map.get("logType") == null ? 0 : Integer.parseInt(map.get("logType").toString());
        BigDecimal rechargPrice = map.get("rechargPrice") == null ? new BigDecimal(0) : new BigDecimal(map.get("rechargPrice").toString());
        rechargPrice = rechargPrice.multiply(new BigDecimal(100)).setScale(0, RoundingMode.DOWN);
        return userRechargeService.balancePayment(userId,shopId,logType,rechargPrice);
    }


    @PostMapping("/apiBalancePayment")
    @SaIgnore
    public R<Map> apiBalancePayment(Long userId,Long shopId,int logType,Long rechargPrice){
        BigDecimal newRechargPrice = new BigDecimal(rechargPrice).multiply(new BigDecimal(100)).setScale(0, RoundingMode.DOWN);
        return userRechargeService.balancePayment(userId,shopId,logType,newRechargPrice);
    }

    @PostMapping("/review")
    public R<Void> review(@RequestBody Map<String,String> map){
        // type 0 拒绝  1 通过
        String type = map.get("type");
        String status = null;
        if (type.equals("1")){
            status = "4";
        }else{
            status = "5";
        }
        String idsStr = map.get("ids");
        String[] ids = idsStr.split(",");
        for (String id : ids){
            // 如果是通过，则增加用户的金额
            UserRechargeVo vo = userRechargeService.queryById(Long.parseLong(id));
            if (!vo.getStatus().equals("3")){
                continue;
            }
            UserRechargeBo bo = new UserRechargeBo();
            if (type.equals("1")){
                // 申请人
                String createBy = vo.getCreateBy();
                // 申请金额
                Long rechargPrice = vo.getRechargPrice();
                SysUserVo userVo = userService.selectUserById(Long.parseLong(createBy));
                BigDecimal newPrice =  userVo.getBalance().add(new BigDecimal(rechargPrice));
                SysUserBo userBo = new SysUserBo();
                userBo.setUserId(userVo.getUserId());
                userBo.setBalance(newPrice);
                userService.updateUser(userBo);
                // 记录新旧价格
                bo.setOriginalPrice(userVo.getBalance());
                bo.setUpdatePrice(newPrice);
                bo.setSuccessTime(DateUtils.getNowDate());
            }
            bo.setId(Long.parseLong(id));
            bo.setStatus(status);
            userRechargeService.updateByBo(bo);
        }

        return R.ok();
    }

    /**
     * 充值金额到钱包里
     * @return
     */
    @PostMapping("/addUserBalance")
    public R<Void> addUserBalance(@RequestBody UserRechargeBo bo){
       return userRechargeService.addUserBalance(bo);
    }


    @GetMapping("/checkTask/{id}")
    public String checkTask(@PathVariable("id") String id){
        UserRechargeVo userRechargeVo = userRechargeService.queryById(Long.parseLong(id));
        return userRechargeVo.getStatus();
    }

    @GetMapping("/editRechargeToError/{id}")
    public void editRechargeToError(@PathVariable("id") String id){
        UserRechargeBo bo = new UserRechargeBo();
        bo.setId(Long.parseLong(id));
        bo.setStatus("2");
        userRechargeService.updateByBo(bo);
    }

    /**
     * 修改用户充值
     */
    @SaCheckPermission("zhishu:userRecharge:edit")
    @Log(title = "用户充值", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserRechargeBo bo) {
        return toAjax(userRechargeService.updateByBo(bo));
    }

    /**
     * 删除用户充值
     *
     * @param ids 主键串
     */
    @SaCheckPermission("zhishu:userRecharge:remove")
    @Log(title = "用户充值", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(userRechargeService.deleteWithValidByIds(List.of(ids), true));
    }
}
