package com.ym.mec.student.controller;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
import com.ym.mec.biz.dal.dao.StudentPreRegistrationDao;
import com.ym.mec.biz.dal.dto.MusicGroupSubjectGoodsAndInfoDto;
import com.ym.mec.biz.dal.dto.RegisterPayDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum;
import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.entity.HttpResponseResult;
import com.ym.mec.common.exception.BizException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
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.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RequestMapping("musicGroup")
@Api(tags = "乐团服务")
@RestController
public class MusicGroupController extends BaseController {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private MusicGroupService musicGroupService;
    @Autowired
    private MusicGroupSubjectPlanService musicGroupSubjectPlanService;
    @Autowired
    private StudentRegistrationService studentRegistrationService;
    @Autowired
    private StudentPaymentOrderService studentPaymentOrderService;
    @Autowired
    private StudentPaymentOrderDetailService studentPaymentOrderDetailService;
    @Autowired
    private MusicGroupPaymentCalenderDetailDao musicGroupPaymentCalenderDetailDao;
    @Autowired
    private MusicGroupPaymentCalenderService musicGroupPaymentCalenderService;
    @Autowired
    private StudentPreRegistrationDao studentPreRegistrationDao;
    @Autowired
    private OrganizationService organizationService;

    @ApiOperation("预报名")
    @PostMapping(value = "/preRegister")
    public Object preRegister(@RequestBody StudentPreRegistration studentPreRegistration) {
        return musicGroupService.preRegister(studentPreRegistration) ? succeed() : failed();
    }

    @ApiOperation("预报名信息查询")
    @GetMapping(value = "/queryPreRegister")
    public Object queryPreRegister(String musicGroupId) {
        return succeed(studentPreRegistrationDao.queryByMusicGroupIdAndUserId(sysUserService.getUserId(), musicGroupId));
    }

    @ApiOperation("获取学生所在乐团列表")
    @GetMapping(value = "/queryUserMusicGroups")
    public Object queryUserMusicGroups() {
        return succeed(musicGroupService.queryUserMusicGroups(sysUserService.getUserId()));
    }

    @ApiOperation("获取学生所在乐团列表")
    @GetMapping(value = "/queryStudentMusicGroupInfo")
    public Object queryStudentMusicGroupInfo(String musicGroupId) {
        return succeed(studentRegistrationService.queryStudentMusicGroupInfo(sysUserService.getUserId(),musicGroupId));
    }

    @ApiOperation("获取学生个人中心乐团信息")
    @GetMapping(value = "/queryPersonalMusicGroups")
    public Object queryPersonalMusicGroups() {
        return succeed(musicGroupService.queryPersonalMusicGroups(sysUserService.getUserId()));
    }

    @ApiOperation(value = "根据学员编号，获取有关联的老师列表，获取学员通讯录列表")
    @GetMapping("/findTeachersByStuId")
    public Object findTeachersByStuId(String search) {
        return succeed(musicGroupService.findTeachersByStuId(sysUserService.getUserId(), search));
    }


    @ApiOperation(value = "获取乐团声部费用信息及乐器和辅件")
    @GetMapping("/getSubjectGoodsAndInfo")
    @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "subjectId", value = "声部编号", required = true, dataType = "Integer")})
    public HttpResponseResult<MusicGroupSubjectGoodsAndInfoDto> getSubjectGoodsAndInfo(String musicGroupId, Integer subjectId) {
        return succeed(musicGroupSubjectPlanService.getSubjectGoodsAndInfo(musicGroupId, subjectId));
    }

    @ApiOperation(value = "乐团报名缴费状态查询")
    @GetMapping("/getMusicGroupStatus")
    @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "int")
    })
    public HttpResponseResult getMusicGroupStatus(String musicGroupId, Integer userId) throws Exception {
        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
        if (musicGroup == null) {
            return failed("乐团不存在");
        }
        SysUser sysUser = sysUserFeignService.queryUserInfo();

        if (sysUser != null && Objects.nonNull(sysUser.getId())) {
            userId = sysUser.getId();
        }
        StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
        if (studentRegistration == null) {
            return failed(HttpStatus.CONTINUE, "乐团报名信息不存在");
        }

        // 判断是否可以继续购买
        List<StudentPaymentOrderDetail> studentPaymentOrderDetailList = studentPaymentOrderDetailService.findUserApplyOrder(userId, musicGroupId, DealStatusEnum.SUCCESS);

        if(studentPaymentOrderDetailList != null && studentPaymentOrderDetailList.size() > 0){
            List<OrderDetailTypeEnum> typeList = studentPaymentOrderDetailList.stream().map(t -> t.getType()).collect(Collectors.toList());
            //如果乐器和辅件都买过/那么看是否购买过其他的缴费项
            if (typeList.contains(OrderDetailTypeEnum.MUSICAL) && typeList.contains(OrderDetailTypeEnum.ACCESSORIES)) {
                MusicGroupPaymentCalender paymentCalender = musicGroupPaymentCalenderService.getApplyCalenderByMusicId(musicGroupId);
                HashMap<String, Object> calenderDetail = new HashMap<>(5);
                musicGroupPaymentCalenderService.getCalenderDetail(calenderDetail,paymentCalender.getId());
                boolean flag = true;
                //是否购买乐团课
                if(Objects.nonNull(calenderDetail.get("course"))){
                    if(typeList.contains(OrderDetailTypeEnum.COURSE)
                            || typeList.contains(OrderDetailTypeEnum.HIGH_ONLINE_COURSE) || typeList.contains(OrderDetailTypeEnum.SINGLE)
                            || typeList.contains(OrderDetailTypeEnum.MIX) || typeList.contains(OrderDetailTypeEnum.HIGH)
                            || typeList.contains(OrderDetailTypeEnum.DEMO) || typeList.contains(OrderDetailTypeEnum.CLASSROOM)
                            || typeList.contains(OrderDetailTypeEnum.COMPREHENSIVE) || typeList.contains(OrderDetailTypeEnum.ENLIGHTENMENT)
                            || typeList.contains(OrderDetailTypeEnum.TRAINING_SINGLE) || typeList.contains(OrderDetailTypeEnum.TRAINING_MIX)
                            || typeList.contains(OrderDetailTypeEnum.HIGH_ONLINE) || typeList.contains(OrderDetailTypeEnum.MUSIC_NETWORK)){
                        flag = true;
                    }else {
                        flag = false;
                    }
                }

                if(flag){
                    //是否购买会员
                    if(Objects.nonNull(calenderDetail.get("member"))){
                        if(typeList.contains(OrderDetailTypeEnum.CLOUD_TEACHER) || typeList.contains(OrderDetailTypeEnum.CLOUD_TEACHER_PLUS)){
                            flag = true;
                        }else {
                            flag = false;
                        }
                    }
                }
                if(flag){
                    //是否购买活动包
                    if(Objects.nonNull(calenderDetail.get("activity"))){
                        if(typeList.contains(OrderDetailTypeEnum.VIP) || typeList.contains(OrderDetailTypeEnum.PRACTICE)){
                            flag = true;
                        }else {
                            flag = false;
                        }
                    }
                }
                if(flag){
                    return failed(HttpStatus.PROCESSING, "您已缴费,请等待乐团开启");
                }
            }
        }

        if (studentRegistration.getPaymentStatus() == PaymentStatusEnum.NO) {
            return failed("乐团还未开启缴费，请等待通知");
        }
        if (musicGroup.getStatus() != MusicGroupStatusEnum.APPLY &&
                musicGroup.getStatus() != MusicGroupStatusEnum.PAY &&
                musicGroup.getStatus() != MusicGroupStatusEnum.PREPARE &&
                musicGroup.getStatus() != MusicGroupStatusEnum.PROGRESS
        ) {
            return failed("乐团在" + musicGroup.getStatus().getMsg() + ",不能缴费");
        }
        String err = studentRegistrationService.checkRegOrPayStatus(musicGroupId);
        if (err != null) {
            return failed(err + "不能缴费");
        }
        studentRegistration.setOwnershipType(musicGroup.getOwnershipType());
        studentRegistration.setChargeTypeId(musicGroup.getChargeTypeId());
        if (sysUser != null) {
            studentRegistration.setGender(sysUser.getGender());
        }

        return succeed(studentRegistration);
    }

    @ApiOperation(value = "申请退团")
    @PostMapping("/quitMusicGroup")
    @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "reason", value = "原因", required = true, dataType = "String"),
            @ApiImplicitParam(name = "reasonEnum", value = "原因", required = true, dataType = "String")})
    public HttpResponseResult quitMusicGroup(String musicGroupId, String reason,MusicGroupQuit.ReasonEnum reasonEnum) throws Exception {
        Integer userId = sysUserService.getUserId();
		MusicGroupQuit musicGroupQuit = new MusicGroupQuit();
		musicGroupQuit.setUserId(userId);
		musicGroupQuit.setMusicGroupId(musicGroupId);
		musicGroupQuit.setUserComment(reason);
        musicGroupQuit.setReasonEnum(reasonEnum);
		musicGroupQuit.setStatus(ApprovalStatus.PROCESSING);
        return succeed(musicGroupService.applyQuitMusicGroup(null, musicGroupQuit, userId));
    }

    @ApiOperation(value = "取消退团申请")
    @PostMapping("/cancelQuitMusicGroup")
    @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "reason", value = "取消原因", required = true, dataType = "String")})
    public HttpResponseResult cancelQuitMusicGroup(String musicGroupId, String reason) throws Exception {
        return succeed(musicGroupService.cancelQuitMusicGroup(sysUserService.getUserId(), musicGroupId, reason));
    }

    @ApiOperation(value = "查询是否有待支付的报名订单")
    @GetMapping("/checkWaitPayApplyOrder")
    @ApiImplicitParams({@ApiImplicitParam(name = "registerId", value = "注册id", required = true, dataType = "int")})
    public HttpResponseResult<StudentPaymentOrder> checkWaitPayApplyOrder(Long registerId) throws Exception {
        StudentRegistration studentRegistration = studentRegistrationService.get(registerId);
        if (studentRegistration == null) {
            return failed("报名信息有误，请核查");
        }
        Integer userId = studentRegistration.getUserId();

        //判断用户是否已存在订单
        List<StudentPaymentOrder> applyOrderList = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.ING);
        
        if(applyOrderList != null && applyOrderList.size() > 0){
        	return succeed(applyOrderList.get(0));
        }
        return succeed(null);
    }

    @ApiOperation(value = "续费")
    @PostMapping("/renew")
    public HttpResponseResult renew(@RequestBody RegisterPayDto renewParamDto) throws Exception {
        Integer userId = sysUserService.getUserId();
        Long calenderId = renewParamDto.getCalenderId();
        if(calenderId == null){
            throw new BizException("参数校验失败");
        }
        MusicGroupPaymentCalender calender = musicGroupPaymentCalenderService.get(calenderId);
        MusicGroupPaymentCalenderDetail calenderDetail = musicGroupPaymentCalenderDetailDao.findByCalenderIdAndUserId(calenderId, userId);
        if (calenderDetail == null) {
            throw new BizException("缴费项不存在该学员，请联系教务老师");
        }
        if (calenderDetail.getPaymentStatus() == PaymentStatus.PAID_COMPLETED) {
            throw new BizException("您已缴费，请勿重复提交");
        }
        //缴费项目已开启或者单独开启
        if (calender.getStatus() == PaymentCalenderStatusEnum.OPEN || calenderDetail.getOpen() == 1) {
            renewParamDto.setUserId(userId);
            renewParamDto.setBatchNo(calender.getBatchNo());
            return musicGroupService.renew(renewParamDto);
        } else if (calender.getStatus() == PaymentCalenderStatusEnum.OVER) {
            throw new BizException("缴费已截止,如有问题请联系指导老师");
        } else {
            throw new BizException("缴费暂未开始,如有问题请联系指导老师");
        }
    }

    @ApiOperation(value = "乐团报名支付")
    @PostMapping("/pay")
    public HttpResponseResult pay(@RequestBody RegisterPayDto registerPayDto) throws Exception {
        StudentRegistration studentRegistration = studentRegistrationService.get(registerPayDto.getRegisterId().longValue());
        if (studentRegistration == null) {
            return failed("报名信息有误，请核查");
        }
        String err = studentRegistrationService.checkRegOrPayStatus(studentRegistration.getMusicGroupId());
        if (err != null) {
            return failed(err + "不可缴费，请联系教务老师");
        }
        registerPayDto.setUserId(studentRegistration.getUserId());
        registerPayDto.setMusicGroupId(studentRegistration.getMusicGroupId());
        return musicGroupService.pay(registerPayDto);
    }


    @ApiOperation(value = "订单状态查询")
    @GetMapping("/getOrderStatus")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "String")})
    public HttpResponseResult getOrderStatus(String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            return failed("请指定订单");
        }
        StudentPaymentOrder orderByOrderNo = studentPaymentOrderService.findOrderByOrderNo(orderNo);
        if (Objects.isNull(orderByOrderNo)) {
            return failed("未找到指定订单");
        }
        MusicGroup musicGroup = musicGroupService.get(orderByOrderNo.getMusicGroupId());
        List<Goods> goodsList = studentPaymentOrderDetailService.findApplyOrderGoods(orderByOrderNo.getId());
        HashMap<String, Object> orderDetail = new HashMap<>();
        orderDetail.put("order", orderByOrderNo);
        orderDetail.put("goods", goodsList);
        orderDetail.put("course", musicGroup.getCourseForm());

        return succeed(orderDetail);
    }

    @ApiOperation(value = "获取乐团的年级列表")
    @GetMapping("/getGradeList")
    @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String")})
    public HttpResponseResult<Map<Integer, String>> getGradeList(String musicGroupId) {
        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
        return succeed(organizationService.getGradeList(musicGroup.getOrganId()));
    }
}
