package com.greenorange.promotion.controller.project;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
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.CommonBatchRequest;
import com.greenorange.promotion.model.dto.promoCodeApply.PromoCodeApplyAddRequest;
import com.greenorange.promotion.model.dto.promoCodeApply.PromoCodeApplyQueryRequest;
import com.greenorange.promotion.model.dto.promoCodeApply.PromoCodeApplyRequest;
import com.greenorange.promotion.model.dto.promoCodeApply.PromoCodeApplyUpdateRequest;
import com.greenorange.promotion.model.entity.Project;
import com.greenorange.promotion.model.entity.PromoCode;
import com.greenorange.promotion.model.entity.PromoCodeApply;
import com.greenorange.promotion.model.entity.UserProject;
import com.greenorange.promotion.model.vo.promoCodeApply.PromoCodeApplyVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.project.ProjectService;
import com.greenorange.promotion.service.project.PromoCodeApplyService;
import com.greenorange.promotion.service.project.PromoCodeService;
import com.greenorange.promotion.service.project.UserProjectService;
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 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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.model.dto.CommonRequest;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;


/**
 * 推广码申请记录 控制器
 */
@RestController
@RequestMapping("promoCodeApply")
@Slf4j
@Tag(name = "推广码申请记录管理")
@Transactional
public class PromoCodeApplyController {

    @Resource
    private PromoCodeApplyService promoCodeApplyService;

    @Resource
    private CommonService commonService;

    @Resource
    private PromoCodeService promoCodeService;

    @Resource
    private UserProjectService userProjectService;

    @Resource
    private ProjectService projectService;



    /**
     * 小程序用户申请推广码
     * @param promoCodeApplyRequest 推广码申请请求体
     * @return 项目详情
     */
    @PostMapping("apply")
    @Operation(summary = "小程序用户申请推广码", description = "参数：无，权限：管理员，方法名：applyPromoCode")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目管理", content = "小程序用户申请推广码")
    public BaseResponse<Boolean> applyPromoCode(@Valid @RequestBody PromoCodeApplyRequest promoCodeApplyRequest, HttpServletRequest request) {
        // 获取用户id
        Long userId = (Long) request.getAttribute("userId");
        // 取出当前项目的推广码
        Long projectId = promoCodeApplyRequest.getProjectId();
        String phoneNumber = promoCodeApplyRequest.getSalespersonPhone();
        // 判断是否重复绑定了手机号
        Map<SFunction<PromoCodeApply, ?>, Object> applyConditions = Map.of(PromoCodeApply::getUserId,  userId, PromoCodeApply::getProjectId, projectId, PromoCodeApply::getSalespersonPhone, phoneNumber);
        List<PromoCodeApply> promoCodeApplyList = commonService.findByFieldEqTargetFieldsWithSpecificColumns(applyConditions, promoCodeApplyService, List.of(PromoCodeApply::getId));
        ThrowUtils.throwIf(!promoCodeApplyList.isEmpty(), ErrorCode.OPERATION_ERROR, "不能重复绑定手机号");

        Map<SFunction<PromoCode, ?>, Object> fieldConditions = Map.of(PromoCode::getProjectId, projectId, PromoCode::getPromoCodeStatus, false);
        List<PromoCode> promoCodeList = commonService.findByFieldEqTargetFieldsWithSpecificColumns(fieldConditions, promoCodeService, List.of(PromoCode::getId));
        ThrowUtils.throwIf(promoCodeList.size() == 0, ErrorCode.OPERATION_ERROR, "当前项目没有推广码");
        PromoCode promoCode = promoCodeList.get(0);
        promoCode.setPromoCodeStatus(true);
        promoCodeService.updateById(promoCode);
        // 获取推广码参数信息
        String promoCodeInfoKey = promoCode.getPromoCodeInfoKey();
        String promoCodeLink = promoCode.getPromoCodeLink();
        String promoCodeImage = promoCode.getPromoCodeImage();
        // 获取项目的参数信息
        Project project = projectService.getById(projectId);

        // 更新项目的推广人数
        Map<SFunction<UserProject, ?>, Object> projectConditions = Map.of(UserProject::getProjectId, projectId, UserProject::getUserId, userId);
        List<UserProject> userProjectList = commonService.findByFieldEqTargetFieldsWithSpecificColumns(projectConditions, userProjectService, List.of(UserProject::getId));
        if (userProjectList.isEmpty()) project.setCurrentPromotionCount(project.getCurrentPromotionCount() + 1);

        projectService.updateById(project);
        String projectName = project.getProjectName();
        String projectImage = project.getProjectImage();
        Integer projectSettlementCycle = project.getProjectSettlementCycle();
        // 获取业务员信息
        String salespersonName = promoCodeApplyRequest.getSalespersonName();
        String salespersonPhone = promoCodeApplyRequest.getSalespersonPhone();
        // 添加推广码申请记录
        PromoCodeApply promoCodeApply = PromoCodeApply.builder()
                .salespersonName(salespersonName)
                .salespersonPhone(salespersonPhone)
                .promoCodeInfoKey(promoCodeInfoKey)
                .promoCodeLink(promoCodeLink)
                .promoCodeImage(promoCodeImage)
                .projectId(projectId)
                .projectName(projectName)
                .projectImage(projectImage)
                .userId(userId)
                .build();
        promoCodeApplyService.save(promoCodeApply);

        // 添加用户项目记录
        if (userProjectList.isEmpty()) {
            UserProject userProject = UserProject.builder()
                    .projectId(projectId)
                    .projectName(projectName)
                    .projectImage(projectImage)
                    .projectSettlementCycle(projectSettlementCycle)
                    .userId(userId)
                    .build();
            userProjectService.save(userProject);
        }
        return ResultUtils.success(true);
    }




    /**
     * Web端管理员分页查询推广码申请记录
     * @param promoCodeApplyQueryRequest 推广码申请记录查询请求体
     * @return 推广码申请记录列表
     */
    @PostMapping("page")
    @Operation(summary = "Web端管理员分页查询推广码申请记录", description = "参数：推广码申请记录查询请求体，权限：管理员，方法名：listPromoCodeApplyByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "推广码申请记录管理", content = "Web端管理员分页查询推广码申请记录")
    public BaseResponse<Page<PromoCodeApplyVO>> listPromoCodeApplyByPage(@Valid @RequestBody PromoCodeApplyQueryRequest promoCodeApplyQueryRequest) {
        long current = promoCodeApplyQueryRequest.getCurrent();
        long pageSize = promoCodeApplyQueryRequest.getPageSize();
        QueryWrapper<PromoCodeApply> queryWrapper = promoCodeApplyService.getQueryWrapper(promoCodeApplyQueryRequest);
        Page<PromoCodeApply> page = promoCodeApplyService.page(new Page<>(current, pageSize), queryWrapper);
        List<PromoCodeApply> promoCodeApplyList = page.getRecords();
        List<PromoCodeApplyVO> promoCodeApplyVOList = commonService.convertList(promoCodeApplyList, PromoCodeApplyVO.class);
        Page<PromoCodeApplyVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(promoCodeApplyVOList);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }
}