package com.ym.mec.student.controller;


import com.alibaba.fastjson.JSON;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.DegreeRegistrationActivityDto;
import com.ym.mec.biz.dal.dto.SporadicPayDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.OrderTypeEnum;
import com.ym.mec.biz.dal.enums.SporadicChargeTypeEnum;
import com.ym.mec.biz.dal.page.SporadicChargeInfoQueryInfo;
import com.ym.mec.biz.service.DegreeRegistrationService;
import com.ym.mec.biz.service.SporadicChargeInfoService;
import com.ym.mec.biz.service.StudentPaymentOrderService;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.entity.HttpResponseResult;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.util.idcard.IdcardValidator;
import com.ym.mec.util.validator.CommonValidator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RequestMapping("degree")
@Api(tags = "考级报名服务")
@RestController
public class DegreeController extends BaseController {

    @Autowired
    private DegreeRegistrationDao degreeRegistrationDao;

    @Autowired
    private DegreeRegistrationService degreeRegistrationService;

    @Autowired
    private SporadicChargeInfoDao sporadicChargeInfoDao;

    @Autowired
    private SporadicChargeInfoService sporadicChargeInfoService;

    @Autowired
    private SysUserFeignService sysUserFeignService;

    @Autowired
    private StudentDao studentDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;

    @ApiOperation(value = "考级报名支付")
    @PostMapping("/pay")
    public HttpResponseResult pay(@RequestBody DegreeRegistrationActivityDto degreeRegistration) throws Exception {
        SysUser user = sysUserFeignService.queryUserInfo();
        if(Objects.isNull(user)){
            return failed(HttpStatus.FORBIDDEN,"请登录");
        }
        degreeRegistration.setUserId(user.getId());

        if(Objects.nonNull(degreeRegistration.getSporadicId())&&Objects.nonNull(degreeRegistration.getTheoryLevel())){
            IdcardValidator idcardValidator = new IdcardValidator();
            if (!idcardValidator.isValidatedAllIdcard(degreeRegistration.getIdcard())) {
                throw new BizException("身份证号不正确，请核对");
            }
            SporadicChargeInfo info = sporadicChargeInfoDao.get(degreeRegistration.getSporadicId());
            if (info == null || info.getDelFlag().equals(1)) {
                return failed("报名信息不存在");
            }
            if (info.getOrganId() != 42 || !info.getChargeType().equals(SporadicChargeTypeEnum.LEVEL)) {
                return failed("报名信息不存在");
            }
        }else{
            degreeRegistration.setOrganId(user.getOrganId());
        }

        if(Objects.isNull(degreeRegistration.getOrganId()) || degreeRegistration.getOrganId() != 40){
            return failed("该分部暂未参与此活动");
        }

        return degreeRegistrationService.pay(degreeRegistration);
    }

    @ApiOperation(value = "考级报名支付")
    @PostMapping("/theoryPay")
    public HttpResponseResult theoryPay(@RequestBody DegreeRegistrationActivityDto degreeRegistration) throws Exception {
        SysUser user = sysUserFeignService.queryUserInfo();
        if(Objects.isNull(user)){
            return failed(HttpStatus.FORBIDDEN,"请登录");
        }
        degreeRegistration.setUserId(user.getId());

        if(Objects.nonNull(degreeRegistration.getTheoryLevel())){
            IdcardValidator idcardValidator = new IdcardValidator();
            if (!idcardValidator.isValidatedAllIdcard(degreeRegistration.getIdcard())) {
                throw new BizException("身份证号不正确，请核对");
            }
        }else{
            degreeRegistration.setOrganId(user.getOrganId());
        }

        if(Objects.isNull(degreeRegistration.getOrganId()) || degreeRegistration.getOrganId() != 40){
            return failed("该分部暂未参与此活动");
        }

        return degreeRegistrationService.theoryPay(degreeRegistration);
    }

    @ApiOperation(value = "考级报名检查")
    @PostMapping("/check")
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public HttpResponseResult check(@RequestBody DegreeRegistrationActivityDto degreeRegistration) throws Exception {
        SysUser user = sysUserFeignService.queryUserInfo();
        if(Objects.isNull(user)){
            return failed(HttpStatus.FORBIDDEN,"请登录");
        }
        degreeRegistration.setUserId(user.getId());
        degreeRegistration.setActivityTag(DegreeRegistrationService.ACTIVITY_TAG);
        studentDao.getLocked(degreeRegistration.getUserId());
        List<DegreeRegistration> userLevelDegrees = degreeRegistrationDao.getUserLevelDegrees(degreeRegistration.getUserId(), DegreeRegistrationService.ACTIVITY_TAG);
        long levelNum = userLevelDegrees.stream().filter(d -> Objects.nonNull(d.getSporadicId())&&d.getStatus().equals(2)).count();
        long theoryLevelNum = userLevelDegrees.stream().filter(d -> StringUtils.isNotBlank(d.getTheoryLevel())&&d.getStatus().equals(2)).count();

        if(Objects.nonNull(degreeRegistration.getSporadicId())&&levelNum>0){
            return failed(HttpStatus.CREATED, "您已报考过选择的考级项目");
        }
        if(StringUtils.isNotBlank(degreeRegistration.getTheoryLevel())&&theoryLevelNum>0){
            return failed(HttpStatus.CREATED, "您已报考过选择的考级项目");
        }
        return succeed();
    }

    @ApiOperation(value = "查询收费列表")
    @GetMapping("/queryList")
    public HttpResponseResult queryPage(SporadicChargeInfoQueryInfo queryInfo) {
        queryInfo.setOrganId("42");
        queryInfo.setChargeType(SporadicChargeTypeEnum.LEVEL);
        queryInfo.setRows(99);
        queryInfo.setOpenFlag(0);
        queryInfo.setSort("amount_");
        queryInfo.setOrder("ASC");
        return succeed(sporadicChargeInfoService.queryDetailPage(queryInfo));
    }

    @ApiOperation(value = "获取活动参数")
    @GetMapping("/getParams")
    public HttpResponseResult getParams(){
        SysUser user = sysUserFeignService.queryUserInfo();
        if(Objects.isNull(user)||Objects.isNull(user.getId())){
            return failed(HttpStatus.FORBIDDEN,"请登录");
        }

        SporadicChargeInfoQueryInfo queryInfo = new SporadicChargeInfoQueryInfo();
        queryInfo.setOrganId("42");
        queryInfo.setChargeType(SporadicChargeTypeEnum.LEVEL);
        queryInfo.setRows(99);
        queryInfo.setOpenFlag(0);
        queryInfo.setSort("amount_");
        queryInfo.setOrder("ASC");

        Map<String, Object> result = new HashMap<>();

        Student student = studentDao.get(user.getId());
        result.put("userInfo", user);
        result.put("isNewUser", student.getIsNewUser());
        result.put("organs", organizationDao.getActivityOrgans());
        result.put("sporadicChargeInfo", sporadicChargeInfoService.queryDetailPage(queryInfo));

        List<DegreeRegistration> userLevelDegrees = degreeRegistrationDao.getUserLevelDegrees(user.getId(), DegreeRegistrationService.ACTIVITY_TAG);
        long levelNum = userLevelDegrees.stream().filter(d -> Objects.nonNull(d.getSporadicId())&&d.getStatus().equals(2)).count();
        long theoryLevelNum = userLevelDegrees.stream().filter(d -> StringUtils.isNotBlank(d.getTheoryLevel())&&d.getStatus().equals(2)).count();

        result.put("levelApplied", levelNum>0?1:0);
        result.put("theoryLevelApplied", theoryLevelNum>0?1:0);

        List<StudentPaymentOrderDetail> historyOrderDetails = studentPaymentOrderDetailDao.getWithUserAndOrderType(user.getId(), OrderTypeEnum.DEGREE_REGISTRATION);
        int historyVipNum = 0, historyPracticeNum = 0, historyHighNum = 0;
        for (StudentPaymentOrderDetail historyOrderDetail : historyOrderDetails) {
            if(StringUtils.isBlank(historyOrderDetail.getGoodsIdList())){
                continue;
            }
            Map<String, Integer> courseNumMap = JSON.parseObject(historyOrderDetail.getGoodsIdList(), Map.class);
            for (Map.Entry<String, Integer> stringIntegerEntry : courseNumMap.entrySet()) {
                switch (stringIntegerEntry.getKey()){
                    case "VIP":
                        historyVipNum = historyVipNum + stringIntegerEntry.getValue();
                        break;
                    case "PRACTICE":
                        historyPracticeNum = historyPracticeNum + stringIntegerEntry.getValue();
                        break;
                    case "HIGH":
                        historyHighNum = historyHighNum + stringIntegerEntry.getValue();
                        break;
                }
            }
        }
        Map<String, Integer> historyCourseInfo = new HashMap<>();
        historyCourseInfo.put(CourseSchedule.CourseScheduleType.VIP.getCode(), historyVipNum);
        historyCourseInfo.put(CourseSchedule.CourseScheduleType.PRACTICE.getCode(), historyPracticeNum);
        historyCourseInfo.put(CourseSchedule.CourseScheduleType.HIGH.getCode(), historyHighNum);
        result.put("historyCourseInfo", historyCourseInfo);

        return succeed(result);
    }
}
