package com.greenorange.promotion.controller.projectSettlement;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.annotation.RequiresPermission;
import com.greenorange.promotion.annotation.SysLog;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.exception.ThrowUtils;
import com.greenorange.promotion.model.dto.withdrawalApply.WithdrawalApplyAddRequest;
import com.greenorange.promotion.model.dto.withdrawalApply.WithdrawalApplyQueryRequest;
import com.greenorange.promotion.model.entity.FundsChange;
import com.greenorange.promotion.model.entity.UserAccount;
import com.greenorange.promotion.model.entity.UserMainInfo;
import com.greenorange.promotion.model.entity.WithdrawalApply;
import com.greenorange.promotion.model.vo.fundsChange.FundsChangeVO;
import com.greenorange.promotion.model.vo.fundsChange.FundsItemVO;
import com.greenorange.promotion.model.vo.userAccount.UserAccountConditionVO;
import com.greenorange.promotion.model.vo.withdrawalApply.WithdrawalApplyVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.settle.FundsChangeService;
import com.greenorange.promotion.service.settle.UserAccountService;
import com.greenorange.promotion.service.settle.WithdrawalApplyService;
import com.greenorange.promotion.service.userInfo.UserMainInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;


/**
 * 提现申请记录 控制器
 */
@RestController
@RequestMapping("withdrawalApply")
@Slf4j
@Tag(name = "提现申请记录管理")
@Transactional
public class WithdrawalApplyController {

    @Resource
    private WithdrawalApplyService withdrawalApplyService;

    @Resource
    private FundsChangeService fundsChangeService;

    @Resource
    private CommonService commonService;

    @Resource
    private UserMainInfoService userMainInfoService;

    @Resource
    private UserAccountService userAccountService;


    /**
     * 小程序端用户查询账户提现状况
     * @return 提现申请记录id
     */
    @PostMapping("query/condition")
    @Operation(summary = "小程序端用户查询账户提现状况", description = "参数：无，权限：管理员，方法名：queryWithdrawalCondition")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<UserAccountConditionVO> queryWithdrawalCondition(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        LambdaQueryWrapper<UserMainInfo> userMainInfoLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserMainInfo::getUserId, userId, userMainInfoService);
        UserMainInfo userMainInfo = userMainInfoService.getOne(userMainInfoLambdaQueryWrapper);
        LambdaQueryWrapper<UserAccount> userAccountLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserAccount::getUserId, userId, userAccountService);
        UserAccount userAccount = userAccountService.getOne(userAccountLambdaQueryWrapper);
        String bankCardNumber = userAccount == null ? "" : userAccount.getBankCardNumber();
        UserAccountConditionVO userAccountConditionVO = UserAccountConditionVO.builder()
                .currentBalance(userMainInfo.getCurrentBalance())
                .bankCardNumber(bankCardNumber)
                .build();
        return ResultUtils.success(userAccountConditionVO);
    }


    /**
     * 小程序端用户申请提现
     * @param withdrawalApplyAddRequest 提现申请记录查添加请求体
     * @return 提现申请记录id
     */
    @PostMapping("add")
    @Operation(summary = "小程序端用户申请提现", description = "参数：提现申请记录查添加请求体，权限：管理员，方法名：addWithdrawalApply")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "提现申请记录管理", content = "小程序端用户申请提现")
    public BaseResponse<Long> addWithdrawalApply(@Valid @RequestBody WithdrawalApplyAddRequest withdrawalApplyAddRequest, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        LambdaQueryWrapper<UserAccount> userAccountLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserAccount::getUserId, userId, userAccountService);
        UserAccount userAccount = userAccountService.getOne(userAccountLambdaQueryWrapper);
        ThrowUtils.throwIf(userAccount == null, ErrorCode.OPERATION_ERROR, "请先绑定银行卡");
        BigDecimal withdrawnAmount = withdrawalApplyAddRequest.getWithdrawnAmount();
        WithdrawalApply withdrawalApply = WithdrawalApply.builder()
                .withdrawnAmount(withdrawnAmount)
                .cardHolder(userAccount.getCardHolder())
                .idCardNumber(userAccount.getIdCardNumber())
                .phoneNumber(userAccount.getPhoneNumber())
                .bankCardNumber(userAccount.getBankCardNumber())
                .openBank(userAccount.getOpenBank())
                .userId(userId)
                .build();
        withdrawalApplyService.save(withdrawalApply);
        // 修改个人主要信息
        LambdaQueryWrapper<UserMainInfo> userMainInfoLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserMainInfo::getUserId, userId, userMainInfoService);
        UserMainInfo userMainInfo = userMainInfoService.getOne(userMainInfoLambdaQueryWrapper);
        userMainInfo.setWithdrawalAmount(userMainInfo.getWithdrawalAmount().add(withdrawnAmount));
        userMainInfo.setCurrentBalance(userMainInfo.getCurrentBalance().subtract(withdrawnAmount));
        userMainInfoService.updateById(userMainInfo);
        // 添加资金明细记录
        FundsChange fundsChange = FundsChange.builder()
                .projectName("用户提现")
                .changeAmount(withdrawnAmount.negate())
                .currentAmount(userMainInfo.getCurrentBalance())
                .userId(userId)
                .projectSettlementId(0L)
                .build();
        fundsChangeService.save(fundsChange);
        return ResultUtils.success(withdrawalApply.getId());
    }


    /**
     * 小程序端用户查询提现申请记录
     * @return 提现申请记录列表
     */
    @PostMapping("query")
    @Operation(summary = "小程序端用户查询提现申请记录", description = "参数：无，权限：管理员，方法名：queryWithdrawalApplyByUserId")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "提现申请记录管理", content = "小程序端用户查询提现申请记录")
    public BaseResponse<List<WithdrawalApplyVO>> queryWithdrawalApplyByUserId(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        List<WithdrawalApply> withdrawalApplyList = commonService.findByFieldEqTargetField(WithdrawalApply::getUserId, userId, withdrawalApplyService);
        List<WithdrawalApplyVO> withdrawalApplyVOS = commonService.convertList(withdrawalApplyList, WithdrawalApplyVO.class);
        Collections.reverse(withdrawalApplyVOS);
        return ResultUtils.success(withdrawalApplyVOS);
    }


    /**
     * 小程序端用户查询资金变动记录
     * @return 提现申请记录id
     */
    @PostMapping("query/change")
    @Operation(summary = "小程序端用户查询资金变动记录", description = "参数：无，权限：管理员，方法名：queryFundsChangeByUserId")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "提现申请记录管理", content = "小程序端用户查询资金变动记录")
    public BaseResponse<FundsItemVO> queryFundsChangeByUserId(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        LambdaQueryWrapper<UserMainInfo> userMainInfoLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserMainInfo::getUserId, userId, userMainInfoService);
        UserMainInfo userMainInfo = userMainInfoService.getOne(userMainInfoLambdaQueryWrapper);
        FundsItemVO fundsItemVO = commonService.copyProperties(userMainInfo, FundsItemVO.class);
        List<FundsChange> fundsChangeList = commonService.findByFieldEqTargetField(FundsChange::getUserId, userId, fundsChangeService);
        List<FundsChangeVO> fundsChangeVOS = commonService.convertList(fundsChangeList, FundsChangeVO.class);
        Collections.reverse(fundsChangeVOS);
        fundsItemVO.setFundsChangeVOList(fundsChangeVOS);
        return ResultUtils.success(fundsItemVO);
    }



    /**
     * Web端管理员分页查询提现申请记录
     * @param withdrawalApplyQueryRequest 提现申请记录查询请求体
     * @return 提现申请记录列表
     */
    @PostMapping("page")
    @Operation(summary = "Web端管理员分页查询提现申请记录", description = "参数：提现申请记录查询请求体，权限：管理员，方法名：listWithdrawalApplyByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "提现申请记录管理", content = "Web端管理员分页查询提现申请记录")
    public BaseResponse<Page<WithdrawalApplyVO>> listWithdrawalApplyByPage(@Valid @RequestBody WithdrawalApplyQueryRequest withdrawalApplyQueryRequest) {
        long current = withdrawalApplyQueryRequest.getCurrent();
        long pageSize = withdrawalApplyQueryRequest.getPageSize();
        QueryWrapper<WithdrawalApply> queryWrapper = withdrawalApplyService.getQueryWrapper(withdrawalApplyQueryRequest);
        Page<WithdrawalApply> page = withdrawalApplyService.page(new Page<>(current, pageSize), queryWrapper);
        List<WithdrawalApply> withdrawalApplyList = page.getRecords();
        List<WithdrawalApplyVO> withdrawalApplyVOList = commonService.convertList(withdrawalApplyList, WithdrawalApplyVO.class);
        Page<WithdrawalApplyVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(withdrawalApplyVOList);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }
}