package com.greenorange.promotion.controller.userInfo;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.CommonRequest;
import com.greenorange.promotion.model.dto.CommonStringRequest;
import com.greenorange.promotion.model.dto.advancementApply.*;
import com.greenorange.promotion.model.entity.AdvancementApply;
import com.greenorange.promotion.model.entity.UserInfo;
import com.greenorange.promotion.model.enums.ReviewStatusEnum;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import com.greenorange.promotion.model.vo.advancementApply.AdvancementApplyApproveVO;
import com.greenorange.promotion.model.vo.advancementApply.AdvancementApplyVOPlus;
import com.greenorange.promotion.model.vo.advancementApply.AdvancementApplyVO;
import com.greenorange.promotion.model.vo.userInfo.SupervisorUserInfoVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.userInfo.AdvancementApplyService;
import com.greenorange.promotion.service.userInfo.UserInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
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.util.List;



/**
 * 晋升申请 控制器
 */
@RestController
@RequestMapping("advancementApply")
@Slf4j
@Tag(name = "晋升申请模块")
@Transactional
public class AdvancementApplyController {

    @Resource
    private AdvancementApplyService advancementApplyService;

    @Resource
    private CommonService commonService;

    @Resource
    private UserInfoService userInfoService;

    /**
     * 小程序端用户申请晋升
     * @param advancementApplyAddRequest 晋升申请记录添加请求体
     * @return 申请记录查询凭据
     */
    @PostMapping("add")
    @Operation(summary = "小程序端用户申请晋升", description = "参数：晋升申请添加请求体，权限：管理员，方法名：addAdvancementApply")
//    @SysLog(title = "晋升申请管理", content = "小程序端用户申请晋升")
    public BaseResponse<Long> addAdvancementApply(@Valid @RequestBody AdvancementApplyAddRequest advancementApplyAddRequest) {
        String phone = advancementApplyAddRequest.getPhone();
        String verificationCode = advancementApplyAddRequest.getVerificationCode();
        // 校验用户手机号和验证码
        userInfoService.checkPhoneAndVerificationCode(phone, verificationCode, UserRoleEnum.STAFF);
        // 校验当前身份证号是否申请过
        String idCard = advancementApplyAddRequest.getIdCard();
        LambdaQueryWrapper<AdvancementApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdvancementApply::getIdCard, idCard)
                        .or()
                        .eq(AdvancementApply::getPhone, phone)
                        .and(w -> w.in(AdvancementApply::getReviewStatus, ReviewStatusEnum.APPROVED.getValue(), ReviewStatusEnum.PENDING.getValue()));
        long count = advancementApplyService.count(queryWrapper);
        ThrowUtils.throwIf(count > 0, ErrorCode.OPERATION_ERROR, "当前手机号或身份证号已申请过");
        AdvancementApply advancementApply = commonService.copyProperties(advancementApplyAddRequest, AdvancementApply.class);
        advancementApplyService.save(advancementApply);
        return ResultUtils.success(advancementApply.getId());
    }


    /**
     * 小程序端用户撤销晋升申请记录
     * @param commonRequest 晋升申请记录id
     * @return 是否更新成功
     */
    @PostMapping("modify/status")
    @Operation(summary = "小程序端用户撤销晋升申请记录", description = "参数：晋升申请记录id，权限：管理员，方法名：revokeAdvancementApply")
//    @SysLog(title = "晋升申请管理", content = "小程序端用户撤销晋升申请记录")
    public BaseResponse<Boolean> revokeAdvancementApply(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        LambdaUpdateWrapper<AdvancementApply> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AdvancementApply::getId, id).set(AdvancementApply::getReviewStatus, ReviewStatusEnum.WITHDRAWN.getValue());
        advancementApplyService.update(updateWrapper);
        return ResultUtils.success(true);
    }

//
//    /**
//     * 小程序端用户根据id修改晋升申请记录信息
//     * @param advancementApplyUpdateRequest 晋升申请更新请求体
//     * @return 是否更新成功
//     */
//    @PostMapping("update")
//    @Operation(summary = "小程序端用户根据id修改晋升申请记录信息", description = "参数：晋升申请更新请求体，权限：管理员，方法名：updateAdvancementApply")
//    @SysLog(title = "晋升申请管理", content = "小程序端用户根据id修改晋升申请记录信息")
//    public BaseResponse<Boolean> updateAdvancementApply(@Valid @RequestBody AdvancementApplyUpdateRequest advancementApplyUpdateRequest) {
//        String phone = advancementApplyUpdateRequest.getPhone();
//        String verificationCode = advancementApplyUpdateRequest.getVerificationCode();
//        // 校验用户手机号和验证码
//        userInfoService.checkPhoneAndVerificationCode(phone, verificationCode, UserRoleEnum.STAFF);
//        AdvancementApply advancementApply = commonService.copyProperties(advancementApplyUpdateRequest, AdvancementApply.class);
//        advancementApplyService.updateById(advancementApply);
//        return ResultUtils.success(true);
//    }


    /**
     * 小程序端用户根据身份证号查询晋升申请记录
     * @param commonStringRequest 查询凭证
     * @return 晋升申请记录信息
     */
    @PostMapping("query/credential")
    @Operation(summary = "小程序端用户根据身份证号查询晋升申请记录", description = "参数：晋升申请更新请求体，权限：管理员，方法名：queryAdvancementApplyByCredential")
    public BaseResponse<AdvancementApplyApproveVO> queryAdvancementApplyByCredential(@Valid @RequestBody CommonStringRequest commonStringRequest) {
        String idCard = commonStringRequest.getTemplateString();
        LambdaQueryWrapper<AdvancementApply> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AdvancementApply::getIdCard, idCard);
        AdvancementApply advancementApply = advancementApplyService.getOne(lambdaQueryWrapper);
        ThrowUtils.throwIf(advancementApply == null, ErrorCode.OPERATION_ERROR, "未找到该申请记录");
        AdvancementApplyApproveVO advancementApplyApproveVO = commonService.copyProperties(advancementApply, AdvancementApplyApproveVO.class);
        String reviewStatus = advancementApply.getReviewStatus();
        ReviewStatusEnum reviewStatusEnum = ReviewStatusEnum.getEnumByValue(reviewStatus);
        // 如果审核通过，填充账号密码
        if (ReviewStatusEnum.APPROVED.equals(reviewStatusEnum)) {
            Long userId = advancementApply.getUserId();
            UserInfo userInfo = userInfoService.getById(userId);
            advancementApplyApproveVO.setUserPassword(userInfo.getUserPassword());
            advancementApplyApproveVO.setUserRole(userInfo.getUserRole());
        }
        // 如果审核拒绝，填充拒绝理由
        if (ReviewStatusEnum.REJECTED.equals(reviewStatusEnum)) {
            advancementApplyApproveVO.setRejectReason(advancementApply.getRejectReason());
        }
        return ResultUtils.success(advancementApplyApproveVO);
    }


    /**
     * web端管理员批准用户的晋升申请
     * @param advancementApplyApproveRequest 晋升申请等信息
     * @return 晋升用户的账号密码
     */
    @PostMapping("approve")
    @Operation(summary = "web端管理员批准用户的晋升申请", description = "参数：晋升申请id，权限：管理员，方法名：approveAdvancementApply")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "晋升申请管理", content = "web端管理员批准用户的晋升申请")
    public BaseResponse<Boolean> approveAdvancementApply(@Valid @RequestBody AdvancementApplyApproveRequest advancementApplyApproveRequest) {
        userInfoService.staffUserInfoMiniRegister(advancementApplyApproveRequest);
        return ResultUtils.success(true);
    }


    /**
     * web端管理员拒绝晋升申请
     * @param advancementApplyRejectRequest 晋升申请拒绝请求体
     * @return 晋升申请信息
     */
    @PostMapping("reject")
    @Operation(summary = "web端管理员拒绝晋升申请", description = "参数：晋升申请拒绝请求体，权限：管理员，方法名：rejectAdvancementApply")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "晋升申请管理", content = "web端管理员拒绝晋升申请")
    public BaseResponse<Boolean> rejectAdvancementApply(@Valid @RequestBody AdvancementApplyRejectRequest advancementApplyRejectRequest) {
        Long applyId = advancementApplyRejectRequest.getApplyId();
        String rejectReason = advancementApplyRejectRequest.getRejectReason();
        LambdaUpdateWrapper<AdvancementApply> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AdvancementApply::getId, applyId)
                .set(AdvancementApply::getReviewStatus, ReviewStatusEnum.REJECTED.getValue())
                .set(AdvancementApply::getRejectReason, rejectReason);
        advancementApplyService.update(updateWrapper);
        return ResultUtils.success(true);
    }


    /**
     * web端管理员根据id查询晋升申请
     * @param commonRequest 晋升申请id
     * @return 晋升申请信息
     */
    @PostMapping("queryById")
    @Operation(summary = "web端管理员根据id查询晋升申请", description = "参数：晋升申请id，权限：管理员，方法名：queryAdvancementApplyById")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "晋升申请管理", content = "web端管理员根据id查询晋升申请")
    public BaseResponse<AdvancementApplyVOPlus> queryAdvancementApplyById(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        AdvancementApply advancementApply = advancementApplyService.getById(id);
        AdvancementApplyVOPlus advancementApplyVOPlus = commonService.copyProperties(advancementApply, AdvancementApplyVOPlus.class);
        return ResultUtils.success(advancementApplyVOPlus);
    }


    /**
     * Web端管理员分页查询晋升申请
     * @param advancementApplyQueryRequest 晋升申请查询请求体
     * @return 晋升申请列表
     */
    @PostMapping("page")
    @Operation(summary = "Web端管理员分页查询晋升申请", description = "参数：晋升申请查询请求体，权限：管理员，方法名：listAdvancementApplyByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "晋升申请管理", content = "Web端管理员分页查询晋升申请")
    public BaseResponse<Page<AdvancementApplyVO>> listAdvancementApplyByPage(@Valid @RequestBody AdvancementApplyQueryRequest advancementApplyQueryRequest) {
        long current = advancementApplyQueryRequest.getCurrent();
        long pageSize = advancementApplyQueryRequest.getPageSize();
        QueryWrapper<AdvancementApply> queryWrapper = advancementApplyService.getQueryWrapper(advancementApplyQueryRequest);
        Page<AdvancementApply> page = advancementApplyService.page(new Page<>(current, pageSize), queryWrapper);
        List<AdvancementApply> advancementApplyList = page.getRecords();
        List<AdvancementApplyVO> advancementApplyVOList = commonService.convertList(advancementApplyList, AdvancementApplyVO.class);
        Page<AdvancementApplyVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(advancementApplyVOList);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }


    /**
     * Web端管理员查询主管信息列表
     * @return 主管信息列表
     */
    @PostMapping("query/supervisor")
    @Operation(summary = "Web端管理员查询主管信息列表", description = "参数：无，权限：管理员，方法名：listSupervisorUserInfo")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "晋升申请管理", content = "Web端管理员分页查询晋升申请")
    public BaseResponse<List<SupervisorUserInfoVO>> listSupervisorUserInfo() {
        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserConstant.SUPERVISOR_ROLE, userInfoService);
        List<SupervisorUserInfoVO> supervisorUserInfoVOS = commonService.convertList(userInfoList, SupervisorUserInfoVO.class);
        return ResultUtils.success(supervisorUserInfoVOS);
    }
}