package com.ym.mec.student.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
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 com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
import com.ym.mec.biz.dal.dao.StudentPreRegistrationDao;
import com.ym.mec.biz.dal.dto.RegisterPayDto;
import com.ym.mec.biz.dal.entity.Goods;
import com.ym.mec.biz.dal.entity.MusicGroup;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderDetail;
import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
import com.ym.mec.biz.dal.entity.StudentPreRegistration;
import com.ym.mec.biz.dal.entity.StudentRegistration;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
import com.ym.mec.biz.dal.enums.OrderTypeEnum;
import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
import com.ym.mec.biz.service.MusicGroupService;
import com.ym.mec.biz.service.MusicGroupSubjectPlanService;
import com.ym.mec.biz.service.StudentPaymentOrderDetailService;
import com.ym.mec.biz.service.StudentPaymentOrderService;
import com.ym.mec.biz.service.StudentRegistrationService;
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.date.DateUtil;

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

    @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 MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
    
    @Autowired
    private StudentPreRegistrationDao studentPreRegistrationDao;
    
    @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) {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null) {
			return failed(HttpStatus.FORBIDDEN, "请登录");
		}

		return succeed(studentPreRegistrationDao.queryByMusicGroupIdAndUserId(sysUser.getId(), musicGroupId));
	}

    @ApiOperation("获取学生所在乐团列表")
    @GetMapping(value = "/queryUserMusicGroups")
    public Object queryUserMusicGroups() {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            return failed(HttpStatus.FORBIDDEN, "请登录");
        }
        return succeed(musicGroupService.queryUserMusicGroups(sysUser.getId()));
    }
    
    @ApiOperation("获取学生所在乐团列表")
    @GetMapping(value = "/queryStudentMusicGroupInfo")
    public Object queryStudentMusicGroupInfo() {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            return failed(HttpStatus.FORBIDDEN, "请登录");
        }
        return succeed(studentRegistrationService.queryStudentMusicGroupInfo(sysUser.getId()));
    }

    @ApiOperation("获取学生个人中心乐团信息")
    @GetMapping(value = "/queryPersonalMusicGroups")
    public Object queryPersonalMusicGroups() {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            return failed(HttpStatus.FORBIDDEN, "请登录");
        }
        return succeed(musicGroupService.queryPersonalMusicGroups(sysUser.getId()));
    }

    @ApiOperation(value = "根据学员编号，获取有关联的老师列表，获取学员通讯录列表")
    @GetMapping("/findTeachersByStuId")
    public Object findTeachersByStuId(String search) {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser == null) {
            return failed(HttpStatus.FORBIDDEN, "请登录");
        }
        return succeed(musicGroupService.findTeachersByStuId(sysUser.getId(), search));
    }


    @ApiOperation(value = "获取乐团声部费用信息及乐器和辅件")
    @GetMapping("/getSubjectGoodsAndInfo")
    @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "subjectId", value = "声部编号", required = true, dataType = "Integer")})
    public HttpResponseResult getSubjectGoodsAndInfo(String musicGroupId, Integer subjectId) {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        if (sysUser != null && sysUser.getId() > 0) {
            Integer userId = sysUser.getId();
            StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
            if (studentRegistration != null && studentRegistration.getTemporaryCourseFee() != null) {
                return succeed(musicGroupSubjectPlanService.getStudentGoodsAndInfo(musicGroupId, subjectId, studentRegistration));
            }
        }
        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("乐团不存在");
        }

        if (userId == null) {
            SysUser sysUser = sysUserFeignService.queryUserInfo();
            userId = sysUser.getId();
        }

        StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
        if (studentRegistration == null) {
            return failed(HttpStatus.CONTINUE, "乐团报名信息不存在");
        }
        if (studentRegistration.getPaymentStatus() != null && studentRegistration.getPaymentStatus() == PaymentStatusEnum.YES) {
            return failed(HttpStatus.PROCESSING,"您已缴费,请等待乐团开启");
        }

        if (studentRegistration.getPaymentStatus() != PaymentStatusEnum.OPEN) {
            return failed("乐团还未开启缴费，请等待通知");
        }
        if (studentRegistration.getTemporaryCourseFee() == null) {
            if (musicGroup.getStatus() != MusicGroupStatusEnum.APPLY && musicGroup.getStatus() != MusicGroupStatusEnum.PAY) {
                return failed("乐团在" + musicGroup.getStatus().getMsg() + ",不能缴费");
            }

            if (musicGroup.getStatus() == MusicGroupStatusEnum.PAY) {
                Date now = new Date();
                MusicGroupPaymentCalender regCalender = musicGroupPaymentCalenderDao.findByMusicGroupRegCalender(musicGroupId);
                if (regCalender != null && regCalender.getDeadlinePaymentDate() != null) {
                    musicGroup.setPaymentExpireDate(regCalender.getDeadlinePaymentDate());
                }
                if (musicGroup.getPaymentExpireDate() != null && DateUtil.daysBetween(musicGroup.getPaymentExpireDate(), now) > 1) {
                    return failed("乐团缴费时间已截止");
                }
            }
        }
        studentRegistration.setOwnershipType(musicGroup.getOwnershipType());
        studentRegistration.setChargeTypeId(musicGroup.getChargeTypeId());

        return succeed(studentRegistration);
    }

    @ApiOperation(value = "续费")
    @GetMapping("/renew")
    @ApiImplicitParams({@ApiImplicitParam(name = "calenderId", value = "缴费项目编号", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "isUseBalancePayment", value = "是否使用余额付款", required = true, dataType = "Boolean")})
    public HttpResponseResult renew(Long calenderId, Boolean isUseBalancePayment, boolean isRepeatPay) throws Exception {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        Integer userId = sysUser.getId();

        if (isUseBalancePayment == null) {
            isUseBalancePayment = false;
        }
        MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.get(calenderId);
        if (isRepeatPay == false) {
            // 判断是否存在支付中的记录
            List<StudentPaymentOrder> list = studentPaymentOrderService.queryByCondition(GroupType.MUSIC, calender.getMusicGroupId(), userId, DealStatusEnum.ING,
                    OrderTypeEnum.RENEW);
            if (list.size() > 0) {
                return failed(HttpStatus.CONTINUE, "您有待支付的订单");
            }
        }
        MusicGroupPaymentCalenderDetail calenderDetail = musicGroupPaymentCalenderDetailDao.findByCalenderIdAndUserId(calenderId, userId);
        if (calenderDetail == null) {
            throw new BizException("缴费项不存在该学员，请联系教务老师");
        }
        if (calenderDetail.getPaymentStatus() == PaymentStatus.PAID_COMPLETED) {
            throw new BizException("您已缴费，请勿重复提交");
        } else if (calenderDetail.getPaymentStatus() == PaymentStatus.PROCESSING) {
            throw new BizException("存在待处理的订单，请稍候尝试");
        }
        //缴费项目已开启或者单独开启
        Map renew;
        if (calender.getStatus() == PaymentCalenderStatusEnum.OPEN || calenderDetail.getOpen() == 1) {
            renew = musicGroupService.renew(calenderId, userId, isUseBalancePayment);
        } else if (calender.getStatus() == PaymentCalenderStatusEnum.OVER) {
            throw new BizException("缴费已截止,如有问题请联系指导老师");
        } else {
            throw new BizException("缴费暂未开始,如有问题请联系指导老师");
        }
        if (renew.containsKey("tradeState")) {
            return failed(HttpStatus.CREATED, "恭喜您,缴费成功!");
        }
        return succeed(renew);
    }

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

    @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 {
    	SysUser sysUser = sysUserFeignService.queryUserInfo();
        Integer userId = sysUser.getId();
        
        return succeed(musicGroupService.cancelQuitMusicGroup(userId, 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();

        //判断用户是否已存在订单
        StudentPaymentOrder applyOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.ING);
        return succeed(applyOrder);
    }

    @ApiOperation(value = "乐团报名支付")
    @PostMapping("/pay")
    @ApiImplicitParams({@ApiImplicitParam(name = "registerPayDto", value = "支付信息", required = true, dataType = "RegisterPayDto")})
    public HttpResponseResult pay(@RequestBody RegisterPayDto registerPayDto) throws Exception {

        StudentRegistration studentRegistration = studentRegistrationService.get(registerPayDto.getRegisterId().longValue());
        if (studentRegistration == null) {
            return failed("报名信息有误，请核查");
        }

        Integer userId = studentRegistration.getUserId();

        StudentPaymentOrder ApplyOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.SUCCESS);
        StudentPaymentOrder waitPay = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.WAIT_PAY);
        if (ApplyOrder != null && waitPay == null) {
            return failed("您已支付成功，请勿重复支付");
        }
        //判断用户是否已存在订单
        ApplyOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.ING);
        if (ApplyOrder != null) {
            return failed(HttpStatus.CONTINUE, "您有待支付的订单");
        }
        Map payMap = musicGroupService.pay(registerPayDto);
        if (payMap.containsKey("tradeState")) {
            return failed(HttpStatus.CREATED, "恭喜您,报名成功!");
        }
        return succeed(payMap);
    }

    @ApiOperation(value = "乐团报名重新支付")
    @PostMapping("/rePay")
    @ApiImplicitParams({@ApiImplicitParam(name = "registerPayDto", value = "支付信息", required = true, dataType = "RegisterPayDto")})
    public HttpResponseResult rePay(@RequestBody RegisterPayDto registerPayDto) throws Exception {
        StudentRegistration studentRegistration = studentRegistrationService.get(registerPayDto.getRegisterId().longValue());
        if (studentRegistration == null) {
            return failed("报名信息有误，请核查");
        }
        Integer userId = studentRegistration.getUserId();
        StudentPaymentOrder ApplyOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.SUCCESS);
        StudentPaymentOrder waitPay = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, studentRegistration.getMusicGroupId(), DealStatusEnum.WAIT_PAY);
        if (ApplyOrder != null && waitPay == null) {
            return failed("您已支付成功，请勿重复支付");
        }
        Map payMap = musicGroupService.rePay(registerPayDto);
        if (payMap.containsKey("tradeState")) {
            return failed(HttpStatus.CREATED, "恭喜您,报名成功!");
        }
        return succeed(payMap);
    }

    @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);
    }
}
