package com.gxwebsoft.shop.controller;

import cn.hutool.core.util.StrUtil;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.entity.ShopDealerUser;
import com.gxwebsoft.shop.service.ShopDealerUserService;
import com.gxwebsoft.shop.service.ShopDealerWithdrawService;
import com.gxwebsoft.shop.entity.ShopDealerWithdraw;
import com.gxwebsoft.shop.param.ShopDealerWithdrawParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.payment.exception.PaymentException;
import com.gxwebsoft.payment.service.WxTransferService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 分销商提现明细表控制器
 *
 * @author 科技小王子
 * @since 2025-08-11 23:51:41
 */
@Tag(name = "分销商提现明细表管理")
@RestController
@RequestMapping("/api/shop/shop-dealer-withdraw")
public class ShopDealerWithdrawController extends BaseController {
    @Resource
    private ShopDealerWithdrawService shopDealerWithdrawService;
    @Resource
    private ShopDealerUserService shopDealerUserService;
    @Resource
    private WxTransferService wxTransferService;

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:list')")
    @Operation(summary = "分页查询分销商提现明细表")
    @GetMapping("/page")
    public ApiResult<PageResult<ShopDealerWithdraw>> page(ShopDealerWithdrawParam param) {
        // 使用关联查询
        return success(shopDealerWithdrawService.pageRel(param));
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:list')")
    @Operation(summary = "查询全部分销商提现明细表")
    @GetMapping()
    public ApiResult<List<ShopDealerWithdraw>> list(ShopDealerWithdrawParam param) {
        // 使用关联查询
        return success(shopDealerWithdrawService.listRel(param));
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:list')")
    @Operation(summary = "根据id查询分销商提现明细表")
    @GetMapping("/{id}")
    public ApiResult<ShopDealerWithdraw> get(@PathVariable("id") Integer id) {
        // 使用关联查询
        return success(shopDealerWithdrawService.getByIdRel(id));
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:save')")
    @Transactional(rollbackFor = {Exception.class})
    @Operation(summary = "添加分销商提现明细表")
    @PostMapping()
    public ApiResult<?> save(@RequestBody ShopDealerWithdraw shopDealerWithdraw) {
        // 记录当前登录用户id
        User loginUser = getLoginUser();
        if (loginUser != null) {
         shopDealerWithdraw.setUserId(loginUser.getUserId());
          final ShopDealerUser dealerUser = shopDealerUserService.getByUserIdRel(loginUser.getUserId());
          // 扣除提现金额
          dealerUser.setMoney(dealerUser.getMoney().subtract(shopDealerWithdraw.getMoney()));
          shopDealerUserService.updateById(dealerUser);
          if (shopDealerWithdrawService.save(shopDealerWithdraw)) {
            return success("添加成功");
          }
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:update')")
    @Transactional(rollbackFor = {Exception.class})
    @Operation(summary = "修改分销商提现明细表")
    @PutMapping()
    public ApiResult<?> update(@RequestBody ShopDealerWithdraw shopDealerWithdraw) {
        if (shopDealerWithdraw.getId() == null) {
            return fail("id不能为空");
        }

        // 以DB原数据为准，避免前端未传字段导致逻辑判断错误/金额被篡改等问题
        ShopDealerWithdraw db = shopDealerWithdrawService.getByIdRel(shopDealerWithdraw.getId());
        if (db == null) {
            return fail("提现记录不存在");
        }

        Integer newStatus = shopDealerWithdraw.getApplyStatus() != null ? shopDealerWithdraw.getApplyStatus() : db.getApplyStatus();
        Integer oldStatus = db.getApplyStatus();
        Integer payType = shopDealerWithdraw.getPayType() != null ? shopDealerWithdraw.getPayType() : db.getPayType();

        // 驳回操作（状态迁移到30时），退回金额，避免重复退回
        if (Integer.valueOf(30).equals(newStatus) && !Integer.valueOf(30).equals(oldStatus)) {
            ShopDealerUser dealerUser = shopDealerUserService.getByUserIdRel(db.getUserId());
            if (dealerUser != null && dealerUser.getMoney() != null && db.getMoney() != null) {
                dealerUser.setMoney(dealerUser.getMoney().add(db.getMoney()));
                shopDealerUserService.updateById(dealerUser);
            }
        }

        // 微信收款且审核通过（迁移到20时），自动发起商家转账到零钱，并将状态置为已打款(40)
        if (Integer.valueOf(10).equals(payType)
            && Integer.valueOf(20).equals(newStatus)
            && !Integer.valueOf(20).equals(oldStatus)
            && !Integer.valueOf(40).equals(oldStatus)) {

            Integer tenantId = db.getTenantId() != null ? db.getTenantId() : getTenantId();
            if (tenantId == null) {
                return fail("tenantId为空，无法发起微信转账");
            }

            String openid = StrUtil.isNotBlank(db.getOpenId()) ? db.getOpenId() : db.getOfficeOpenid();
            if (StrUtil.isBlank(openid)) {
                // 兜底：从分销商信息关联获取openid
                ShopDealerUser dealerUser = shopDealerUserService.getByUserIdRel(db.getUserId());
                if (dealerUser != null && StrUtil.isNotBlank(dealerUser.getOpenid())) {
                    openid = dealerUser.getOpenid();
                }
            }
            if (StrUtil.isBlank(openid)) {
                return fail("用户openid为空，无法发起微信转账");
            }

            // 微信支付商家转账接口对商户单号通常有最小长度限制（当前实测为 >= 5）。
            // 使用 0 填充，避免如 "WD59" 这种过短导致 PARAM_ERROR。
            String outBillNo = String.format("WD%03d", db.getId());
            String remark = "分销商提现";
            String userName = db.getRealName();

            try {
                wxTransferService.initiateSingleTransfer(
                    tenantId,
                    openid,
                    db.getMoney(),
                    outBillNo,
                    remark,
                    userName
                );
            } catch (PaymentException e) {
                return fail(e.getMessage());
            }

            shopDealerWithdraw.setApplyStatus(40);
            shopDealerWithdraw.setAuditTime(LocalDateTime.now());
        }

        // 已打款：非微信自动转账的场景，要求上传凭证
        if (Integer.valueOf(40).equals(newStatus)) {
            shopDealerWithdraw.setAuditTime(LocalDateTime.now());
            if (!Integer.valueOf(10).equals(payType) && StrUtil.isBlankIfStr(shopDealerWithdraw.getImage())) {
                return fail("请上传打款凭证");
            }
        }
        if (shopDealerWithdrawService.updateById(shopDealerWithdraw)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:remove')")
    @OperationLog
    @Operation(summary = "删除分销商提现明细表")
    @DeleteMapping("/{id}")
    public ApiResult<?> remove(@PathVariable("id") Integer id) {
        if (shopDealerWithdrawService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:save')")
    @OperationLog
    @Operation(summary = "批量添加分销商提现明细表")
    @PostMapping("/batch")
    public ApiResult<?> saveBatch(@RequestBody List<ShopDealerWithdraw> list) {
        if (shopDealerWithdrawService.saveBatch(list)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:update')")
    @OperationLog
    @Operation(summary = "批量修改分销商提现明细表")
    @PutMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerWithdraw> batchParam) {
        if (batchParam.update(shopDealerWithdrawService, "id")) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('shop:shopDealerWithdraw:remove')")
    @OperationLog
    @Operation(summary = "批量删除分销商提现明细表")
    @DeleteMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
        if (shopDealerWithdrawService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

}
