package com.pz.applet;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.pz.common.annotation.Log;
import com.pz.common.annotation.RepeatSubmit;
import com.pz.common.core.controller.BaseController;
import com.pz.common.core.domain.PageQuery;
import com.pz.common.core.domain.R;
import com.pz.common.core.page.TableDataInfo;
import com.pz.common.core.validate.AddGroup;
import com.pz.common.core.validate.EditGroup;
import com.pz.common.enums.BusinessType;
import com.pz.common.helper.LoginHelper;
import com.pz.common.utils.poi.ExcelUtil;
import com.pz.system.domain.bo.CreateOrderBo;
import com.pz.system.domain.bo.PaymentRecordBo;
import com.pz.system.domain.bo.TotalOrderBo;
import com.pz.system.domain.vo.PaymentRecordVo;
import com.pz.system.domain.vo.TotalOrderVo;
import com.pz.system.service.IPayService;
import com.pz.system.service.IPaymentRecordService;
import com.pz.system.service.ITotalOrderService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;

/**
 * 总订单
 *
 * @author ruoyi
 * @date 2023-09-08
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/applet/totalOrder")
public class AppletTotalOrderController extends BaseController {

    private final ITotalOrderService iTotalOrderService;

    private final IPayService iPayService;

    /**
     * 查询总订单列表
     */
    @GetMapping("/list")
    public TableDataInfo<TotalOrderVo> list(TotalOrderBo bo, PageQuery pageQuery) {
        bo.setUid(LoginHelper.getLoginUser().getUserId().intValue());
        return iTotalOrderService.queryPageList(bo, pageQuery);
    }

    /**
     * 获取总订单详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<TotalOrderVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Integer id) {
        return R.ok(iTotalOrderService.queryByAppId(id));
    }


    /**
     * 查询物流信息
     *
     */
    @GetMapping("/selectLogisticsStatus")
    public R<Object> selectLogisticsStatus(TotalOrderBo totalOrderBo) {
        return R.ok(iTotalOrderService.selectLogisticsStatus(totalOrderBo));
    }

    /**
     * 新增总订单
     */
    @RepeatSubmit()
    @PostMapping()
    public R<TotalOrderVo> add(@Validated(AddGroup.class) @RequestBody CreateOrderBo bo) {
        return R.ok(iTotalOrderService.createOrder(bo));
    }

    /**
     * 修改总订单
     */
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TotalOrderBo bo) {
        return toAjax(iTotalOrderService.updateByBo(bo));
    }

    /**
     * 删除总订单
     *
     * @param ids 主键串
     */
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(iTotalOrderService.deleteWithValidByIds(Arrays.asList(ids), true));
    }



    /**
     * 用户评价订单
     */
    @RepeatSubmit()
    @PostMapping("/appraise")
    public R<Void> appraise(@Validated(AddGroup.class) @RequestBody TotalOrderBo recordBo) {
        return toAjax(iTotalOrderService.updateByBo(recordBo));
    }

    /**
     * 用户取消订单
     */
    @RepeatSubmit()
    @PostMapping("/cancelOrder")
    public R<Void> cancelOrder(@Validated(AddGroup.class) @RequestBody TotalOrderBo recordBo) {
        return toAjax(iTotalOrderService.cancelOrder(recordBo));
    }

    /**
     * 用户完成订单
     */
    @RepeatSubmit()
    @PostMapping("/finishOrder")
    public R<Void> finishOrder(@Validated(AddGroup.class) @RequestBody TotalOrderBo recordBo) {
        return toAjax(iTotalOrderService.finishOrder(recordBo));
    }

    /**
     * 订单支付
     */
    @RepeatSubmit()
    @PostMapping("/Orderpay")
    @SaIgnore
    public R<Object> Orderpay(@Validated(AddGroup.class) @RequestBody TotalOrderBo recordBo) {
        return R.ok(iTotalOrderService.payOrder(recordBo));
    }

    /**
     * 订单回调
     */
    @ResponseBody
    @PostMapping("/orderPayCallBack")
    public Map orderPayCallBack(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap();
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult result = iPayService.parseOrderNotifyResult(xmlResult);

            // 加入自己处理订单的业务逻辑,需要判断订单是否已经支付过,否则可能会重复调用
            if(iTotalOrderService.orderPayCallBack(result)){
                map.put("code", "SUCCESS");
                map.put("message", "成功");
                return map;
            }

        } catch (Exception e) {
            System.out.println("微信回调结果异常,异常原因" + e.getMessage());
            map.put("code", "fail");
            map.put("message", "系统错误");
            return map;
        }
        map.put("code", "fail");
        map.put("message", "系统错误");
        return map;
    }


    /**
     * 用户主动退款
     */
    @RepeatSubmit()
    @PostMapping("/refundOrder")
    public R<Boolean> refundOrder(@Validated(AddGroup.class) @RequestBody TotalOrderBo recordBo) {
        return R.ok(iTotalOrderService.refundOrder(recordBo));
    }


    /**
     * 退款回调
     */
    @ResponseBody
    @PostMapping("/orderRefundCallBack")
    public Map orderRefundCallBack(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap();
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayRefundNotifyResult result = iPayService.parseRefundNotifyResult(xmlResult);

            // 加入自己处理订单的业务逻辑,需要判断订单是否已经支付过,否则可能会重复调用
            if(iTotalOrderService.orderRefundCallBack(result)){
                map.put("code", "SUCCESS");
                map.put("message", "成功");
                return map;
            }

        } catch (Exception e) {
            System.out.println("微信回调结果异常,异常原因" + e.getMessage());
            map.put("code", "fail");
            map.put("message", "系统错误");
            return map;
        }
        map.put("code", "fail");
        map.put("message", "系统错误");
        return map;
    }
}