package com.ruoyi.mall.controller;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ApiResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.mall.domain.MallOrderOrder;
import com.ruoyi.mall.domain.MallSalesmanAchievement;
import com.ruoyi.mall.domain.MallShopShop;
import com.ruoyi.mall.domain.vo.MallOrderGoodsVO;
import com.ruoyi.mall.mapper.MallSalesmanAchievementMapper;
import com.ruoyi.mall.service.IMallOrderGoodsService;
import com.ruoyi.mall.service.IMallOrderOrderService;
import com.ruoyi.mall.service.IMallShopShopService;
import com.ruoyi.web.controller.utils.XiaochengxuPayService;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.mall.domain.MallOrderBack;
import com.ruoyi.mall.service.IMallOrderBackService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 退款单Controller
 *
 * @author chang
 * @date 2021-11-25
 */
@RestController
@RequestMapping("/mall/mallOrderBack")
public class MallOrderBackController extends BaseController
{
    @Autowired
    private IMallOrderBackService mallOrderBackService;

    @Autowired
    private IMallOrderOrderService orderOrderService;

    @Autowired
    private IMallShopShopService shopShopService;

    @Autowired
    private IMallOrderGoodsService orderGoodsService;

    @Autowired
    private MallSalesmanAchievementMapper mallSalesmanAchievementMapper;
    /**
     * 查询退款单列表
     */
    @PreAuthorize("@ss.hasPermi('mall:mallOrderBack:list')")
    @GetMapping("/list")
    public TableDataInfo list(MallOrderBack mallOrderBack)
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        MallShopShop mallShopShop = shopShopService.selectMallShopShopBySysUserId(loginUser.getUserId());
        if (ObjectUtils.isNotEmpty(mallShopShop)){
            mallOrderBack.setShopId(mallShopShop.getShopId());
        }

        startPage();
        List<MallOrderBack> list = mallOrderBackService.selectMallOrderBackList(mallOrderBack);
        return getDataTable(list);
    }

    /**
     * 导出退款单列表
     */
    @PreAuthorize("@ss.hasPermi('mall:mallOrderBack:export')")
    @Log(title = "退款单", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(MallOrderBack mallOrderBack)
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        MallShopShop mallShopShop = shopShopService.selectMallShopShopBySysUserId(loginUser.getUserId());
        if (ObjectUtils.isNotEmpty(mallShopShop)){
            mallOrderBack.setShopId(mallShopShop.getShopId());
        }
        List<MallOrderBack> list = mallOrderBackService.selectMallOrderBackList(mallOrderBack);
        ExcelUtil<MallOrderBack> util = new ExcelUtil<MallOrderBack>(MallOrderBack.class);
        return util.exportExcel(list, "退款单数据");
    }

    /**
     * 获取退款单详细信息
     */
    @PreAuthorize("@ss.hasPermi('mall:mallOrderBack:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(mallOrderBackService.selectMallOrderBackById(id));
    }

    /**
     * 新增退款单
     */
    @PreAuthorize("@ss.hasPermi('mall:mallOrderBack:add')")
    @Log(title = "退款单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody MallOrderBack mallOrderBack)
    {
        return toAjax(mallOrderBackService.insertMallOrderBack(mallOrderBack));
    }

    /**
     * 修改退款单
     */
    @PreAuthorize("@ss.hasPermi('mall:mallOrderBack:edit')")
    @Log(title = "退款单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MallOrderBack mallOrderBack)
    {
        if ("1".equals(mallOrderBack.getStatus())){
            return refundAgree(mallOrderBack);
        }
        if ("3".equals(mallOrderBack.getStatus())){
            mallOrderBackService.updateMallOrderBack(mallOrderBack);
            return AjaxResult.success("操作完成");
        }
        return AjaxResult.error("错误操作，只能同意或拒绝！");
    }

    public AjaxResult refundAgree(MallOrderBack mallOrderBack) {
        MallOrderBack orderBack = mallOrderBackService.selectMallOrderBackById(mallOrderBack.getId());
        if (orderBack == null) {
            return AjaxResult.error("退款信息异常");
        }
        if (!"0".equals(orderBack.getStatus())) {
            return AjaxResult.error("只有待审核状态才能退款");
        }
        MallOrderOrder orderOrder = orderOrderService.selectMallOrderOrderById(orderBack.getOrderId());
        List<MallOrderOrder> orderList = orderOrderService.selectMallOrderOrderByTotalOrderSn(orderOrder.getTotalOrderSn());
        BigDecimal totalPayment = BigDecimal.ZERO;
        for (MallOrderOrder order : orderList) {
                totalPayment = totalPayment.add(order.getPayment());//支付的时候按合同号这么支付的，这里金额也要这么对应
        }


        if (orderOrder == null) {
            return AjaxResult.error("订单信息异常");
        }
        SortedMap<String, String> data = new TreeMap<>();
        //退款到用户微信
        String nonce_str = Md5Utils.getRandomStringByLength(32);
        data.put("nonce_str", nonce_str);
        //商户订单号
        data.put("out_trade_no", orderOrder.getTotalOrderSn());
        //商户退款单号,一笔退款失败后重新提交，请不要更换退款单号，请使用原商户退款单号
        data.put("out_refund_no", orderBack.getId().toString());//分批退款，退款单号不能相同，取退款单主键刚好
        int total_fee = Math.round(Float.valueOf(orderBack.getPrice().multiply(new BigDecimal(100)).toString()));
        //支付金额，微信支付提交的金额是不能带小数点的，且是以分为单位,这边需要转成字符串类型，否则后面的签名会失败
        data.put("total_fee", String.valueOf(totalPayment.multiply(new BigDecimal("100")).intValue()));

        //退款总金额,单位为分,只能为整数
        data.put("refund_fee", String.valueOf(Math.round(total_fee)));
        String str = XiaochengxuPayService.wxXcxRefund(data);
        if (str.length() > 0) {
            return AjaxResult.error(str);
        }
        // 查询该订单所有退款单中，所有的退款金额相加
        List<MallOrderBack> mallOrderBacks = mallOrderBackService.selectMallOrderBackByOrderId(orderOrder.getId());
        BigDecimal totalRefund = BigDecimal.ZERO;
        for (MallOrderBack item : mallOrderBacks){
            if ("1".equals(item.getStatus())){//只计算退款成功的
                totalRefund = totalRefund.add(item.getPrice());
            }
        };
        //订单商品明细列表（用于计算退款后的提成变化）
        List<MallOrderGoodsVO> list = orderGoodsService.selectMallOrderGoodsByOrderId(orderOrder.getId());
        BigDecimal currentCommission = BigDecimal.ZERO;//退款部分提成
        for (MallOrderGoodsVO mallOrderGoodsVO : list) {
            if ("1".equals(mallOrderGoodsVO.getReturnStatus())){
                //退货数量【由于每次是累加的，所以计算出订单的剩余提成就行】
                BigDecimal num = new BigDecimal(mallOrderGoodsVO.getTotal() - mallOrderGoodsVO.getReturnTotal());
                currentCommission = currentCommission.add(mallOrderGoodsVO.getCommission().multiply(num));
            }
        }
        //订单支付金额-退款单已退款金额
        orderOrder.setReturnablePrice(orderOrder.getPayment().subtract(totalRefund));//todo 1待测试优惠券情况-支付金额减还可以吗 2上面的微信退款接口还可能微信支付金额不一样
        // 如果没有全部退款, 订单状态恢复待发货   (该退款单和剩余可退款金额比较)
        System.out.println("退款金额：" + orderBack.getPrice() + "  剩余可退款金额：" + orderOrder.getReturnablePrice());
        if (orderBack.getPrice().compareTo(orderOrder.getReturnablePrice()) < 0){
            // 部分退款 → 恢复订单状态
            System.out.println("状态改为待配送");
            orderOrder.setStatus("1");
            orderOrder.setOrderStatus("1");
            orderOrder.setIsExamine("0");
            //订单除去退款部分后的提成
            orderOrder.setCommissionPrice(currentCommission);

        }else {
            // 全额退款 → 关闭订单（根据业务需求）
            System.out.println("状态改为已退款");
            orderOrder.setStatus("6"); // 例如：6 表示退货成功
            orderOrder.setOrderStatus("10"); // 例如：10 表示退款成功
            orderOrder.setCommissionPrice(BigDecimal.ZERO);//全额退款提成归零
            //审核状态已经是1了
        }
        System.out.println(orderOrder);
        orderOrderService.updateMallOrderOrder(orderOrder);
        //更新业务员业绩
        MallSalesmanAchievement mallSalesmanAchievement = mallSalesmanAchievementMapper.selectMallSalesmanAchievementByOrderId(orderOrder.getId());
        if (mallSalesmanAchievement != null){
            mallSalesmanAchievement.setMoney(orderOrder.getCommissionPrice());
            mallSalesmanAchievementMapper.updateMallSalesmanAchievement(mallSalesmanAchievement);
        }
        mallOrderBack.setStatus("1");//该退款单状态改为退款成功
        mallOrderBackService.updateMallOrderBack(mallOrderBack);
        return AjaxResult.success("退款成功");
    }

    /**
     * 删除退款单
     */
    @PreAuthorize("@ss.hasPermi('mall:mallOrderBack:remove')")
    @Log(title = "退款单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(mallOrderBackService.deleteMallOrderBackByIds(ids));
    }

    @PostMapping("/handleRefund")
    public ApiResult handleRefund(@RequestBody Map<String, Object> params)
    {
        if (!params.containsKey("refundId")||StringUtils.isEmpty(params.get("refundId").toString())){
            return ApiResult.error("缺少参数");
        }
        Boolean isAccept = orderOrderService.refundStatusRoute(Integer.parseInt("1"),params.get("refundId").toString());
        if (isAccept == true) {
            int status = mallOrderBackService.handleRefund(params);
            return status > 0 ? ApiResult.ok("操作成功") : ApiResult.error("操作失败");
        }else {
            return ApiResult.error("订单异常");
        }
    }
}
