package com.app.service.order;

import com.app.constant.OrderConstant;
import com.app.constant.SystemConstant;
import com.app.dto.PageResult;
import com.app.entity.basics.OpenCourse;
import com.app.entity.basics.YearSemester;
import com.app.entity.guardian.Guardian;
import com.app.entity.order.OpenCourseOrder;
import com.app.entity.order.OpenCourseOrderItem;
import com.app.entity.order.OpenCourseRefund;
import com.app.mapper.basics.OpenCourseMapper;
import com.app.mapper.order.OpenCourseRefundMapper;
import com.app.service.basics.OpenCourseService;
import com.app.service.basics.YearSemesterService;
import com.app.service.guardian.GuardianService;
import com.app.service.wx.WXTemplateService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class OpenCourseRefundService {

    @Autowired
    private OpenCourseRefundMapper mapper;

    @Resource
    private OpenCourseMapper openCourseMapper;

    @Resource
    private OpenCourseService openCourseService;

    @Autowired
    private GuardianService guardianService;

    @Autowired
    private OpenCourseOrderService openCourseOrderService;

    @Autowired
    private OpenCourseOrderItemService openCourseOrderItemService;

    @Autowired
    private YearSemesterService schoolYearSemesterService;

    @Autowired
    private WXTemplateService wXTemplateService;

    /**
     * 功能描述：开课退费申请
     *
     * @param childName
     * @param phoneNumber
     * @param openCourseName
     * @param guardianId
     * @param transactionId
     * @param state
     * @param schoolYear
     * @param semester
     * @param schoolId
     * @param gradeName
     * @param className
     * @param page
     * @param size
     * @return
     */
    public PageResult<OpenCourseRefund> page(String childName, String phoneNumber, String openCourseName,
                                             String guardianId, String transactionId, Integer state,
                                             Integer schoolYear, Integer semester,
                                             String schoolId, String gradeName, String className, List<String> organIds,
                                             Integer page, Integer size) {
        LambdaQueryWrapper<OpenCourseRefund> wrapper = new QueryWrapper().lambda();
        if (!StringUtils.isEmpty(childName)) { // 小孩姓名
            wrapper.like(OpenCourseRefund::getChildName, childName);
        }
        if (!StringUtils.isEmpty(phoneNumber)) { // 手机号码
            wrapper.like(OpenCourseRefund::getPhoneNumber, phoneNumber);
        }
        if (!StringUtils.isEmpty(openCourseName)) { // 课程名称
            wrapper.like(OpenCourseRefund::getOpenCourseName, openCourseName);
        }
        if (!StringUtils.isEmpty(guardianId)) {
            wrapper.eq(OpenCourseRefund::getGuardianId, guardianId);
        }
        if (!StringUtils.isEmpty(transactionId)) {
            wrapper.eq(OpenCourseRefund::getTransactionId, transactionId);
        }
        if (!StringUtils.isEmpty(state)) {
            wrapper.eq(OpenCourseRefund::getState, state);
        }
        if (!StringUtils.isEmpty(schoolYear)) { // 学年
            wrapper.eq(OpenCourseRefund::getSchoolYear, schoolYear);
        }
        if (!StringUtils.isEmpty(semester)) { // 学期
            wrapper.eq(OpenCourseRefund::getSemester, semester);
        }
        if (!StringUtils.isEmpty(schoolId)) { // 学校标识
            wrapper.eq(OpenCourseRefund::getSchoolId, schoolId);
        }
        if (!StringUtils.isEmpty(gradeName)) { // 年级名称
            wrapper.eq(OpenCourseRefund::getGradeName, gradeName);
        }
        if (!StringUtils.isEmpty(className)) { // 年级名称
            wrapper.eq(OpenCourseRefund::getClassName, className);
        }
        if(organIds!=null && !organIds.isEmpty()){
            wrapper.and(w ->{
                for (String organId : organIds) {
                    if(!StringUtils.isEmpty(organId)){
                        w.eq(OpenCourseRefund::getOrganId,organId).or();
                    }
                }
            });
        }
        wrapper.eq(OpenCourseRefund::getIsDel, Boolean.FALSE);

        IPage<OpenCourseRefund> _page = new Page<>(page, size);
        wrapper.orderByDesc(OpenCourseRefund::getCreateAt);
        IPage<OpenCourseRefund> refundPage = mapper.selectPage(_page, wrapper);

        return new PageResult(page, size, refundPage.getTotal(), refundPage.getRecords());
    }

    /**
     * 功能描述：申请退费
     *
     * @param organId               机构标识
     * @param openCourseOrderItemId 开课订单项
     * @param remarks               退费备注
     * @param guardianId             账号
     * @param wxmpFormId            申请退费formId
     * @return
     */
    public OpenCourseRefund apply(String organId, String openCourseOrderItemId, String remarks, String guardianId, String wxmpFormId) {
        /* 判断是否已经申请过 */
        OpenCourseRefund _openCourseRefund = mapper.selectOne(new QueryWrapper<OpenCourseRefund>().lambda()
                .eq(OpenCourseRefund::getOpenCourseOrderItemId, openCourseOrderItemId)
                .eq(OpenCourseRefund::getGuardianId, guardianId)
        );
        if (Optional.ofNullable(_openCourseRefund).isPresent()) {
            throw new RuntimeException("本课程已经申请退费，请耐心等待审核结果");
        }

        Optional<OpenCourseOrderItem> OrderItemOptional = openCourseOrderItemService.findById(openCourseOrderItemId);
        if (!OrderItemOptional.isPresent()) {
            return null;
        }

        /* 只允许本学期申请退费 */
        OpenCourseOrderItem item = OrderItemOptional.get();
        YearSemester schoolYearSemester = schoolYearSemesterService.find(organId);
        if (!schoolYearSemester.getSchoolYear().equals(item.getSchoolYear()) || !schoolYearSemester.getSemester().equals(item.getSemester())) {
            // throw new RuntimeException("只允许本学期的课程进行退费申请");
        }
        /* add by 梁展鹏 20200914 假如订单项已经退款，那么不能重复申请 */
        if (OrderConstant.OrderItemState.REFUND == item.getState()) {
            throw new RuntimeException("该课程已经退款，不能重复申请！");
        }

        OpenCourseRefund refund = new OpenCourseRefund();
        refund.setOpenCourseOrderId(item.getOpenCourseOrderId()); // 开课订单标识
        refund.setOpenCourseOrderItemId(item.getId()); // 开课订单项标识
        refund.setOpenCourseId(item.getOpenCourseId()); // 开课标识
        refund.setGuardianId(guardianId); // 家长标识
        refund.setSchoolYear(item.getSchoolYear()); // 学年
        refund.setSemester(item.getSemester()); // 学期
        refund.setSchoolId(item.getSchoolId()); // 学校标识
        refund.setSchoolName(item.getSchoolName()); // 学校名称
        refund.setGradeName(item.getGradeName()); // 年级名称
        refund.setClassName(item.getClassName()); // 班级名称
        refund.setChildName(item.getChildName()); // 小孩姓名
        refund.setPhoneNumber(item.getPhoneNumber()); // 手机号码
        refund.setOpenCourseName(item.getName()); // 开课名称
        refund.setOpenCoursePrice(item.getPrice()); // 开课价格
        refund.setOpenCourseCycle(item.getCycle()); // 开课星期
        refund.setOpenCourseHours(item.getHours()); // 开课时间

        Optional<OpenCourseOrder> openCourseOrderOptional = openCourseOrderService.findById(item.getOpenCourseOrderId());
        if (openCourseOrderOptional.isPresent()) {
            refund.setTransactionId(openCourseOrderOptional.get().getTransactionId()); // 微信支付订单号
        }

        refund.setWxmpFormId(wxmpFormId);
        refund.setApplyRemarks(remarks); // 备注
        refund.setState(OrderConstant.RefundState.TO_BE_APPLY); // 状态
        mapper.insert(refund);

        return refund;
    }

    /**
     * 功能描述：审核退费
     *
     * @param organId            机构标识
     * @param openCourseRefundId 退费申请标识
     * @param state              状态
     * @param remarks            退费申请备注
     * @param refundId           退款单号
     */
    @Transactional
    public void auditRefund(String organId, String openCourseRefundId, Integer state, String remarks, String refundId) {
        OpenCourseRefund _openCourseRefund = mapper.selectById(openCourseRefundId);
        if (Optional.ofNullable(_openCourseRefund).isPresent()) {
            Optional<OpenCourseOrderItem> optionalOpenCourseOrderItem = openCourseOrderItemService.findById(_openCourseRefund.getOpenCourseOrderItemId());
            if (optionalOpenCourseOrderItem.isPresent()) {
                OpenCourseOrderItem openCourseOrderItem = optionalOpenCourseOrderItem.get();
                YearSemester schoolYearSemester = schoolYearSemesterService.find(organId);
                if (!schoolYearSemester.getSchoolYear().equals(openCourseOrderItem.getSchoolYear()) || !schoolYearSemester.getSemester().equals(openCourseOrderItem.getSemester())) {
                    // throw new RuntimeException("只允许本学期的课程进行退费申请审核");
                }
            }

            _openCourseRefund.setRefundId(refundId); // 微信退款单号 add by 梁展鹏 假如是一笔订单，多次退款。没有考虑...
            _openCourseRefund.setPassedRemarks(remarks);
            _openCourseRefund.setState(state);
            _openCourseRefund.setPassedBy(SystemConstant.ADMIN_ID);
            _openCourseRefund.setPassedAt(new Date());
            mapper.updateById(_openCourseRefund);

            /* 审核通过 */
            if (OrderConstant.RefundState.PASSED.intValue() == state) {
                /* 更改订单金额 */
                Optional<OpenCourseOrder> openCourseOrderOptional = openCourseOrderService.findById(_openCourseRefund.getOpenCourseOrderId());
                if (openCourseOrderOptional.isPresent()) {
                    OpenCourseOrder openCourseOrder = openCourseOrderOptional.get();
                    openCourseOrder.setRefund(_openCourseRefund.getOpenCoursePrice()); // 退款金额
                    openCourseOrderService.saveOrUpdate(openCourseOrder, SystemConstant.ADMIN_ID);
                }

                /* 更改我的课程 */
                Optional<OpenCourseOrderItem> openCourseOrderItemOptional = openCourseOrderItemService.find(_openCourseRefund.getOpenCourseOrderId(), _openCourseRefund.getOpenCourseId(), _openCourseRefund.getGuardianId());
                if (openCourseOrderItemOptional.isPresent()) {
                    OpenCourseOrderItem openCourseOrderItem = openCourseOrderItemOptional.get();
                    openCourseOrderItem.setState(OrderConstant.OrderItemState.REFUND);
                    openCourseOrderItemService.saveOrUpdate(openCourseOrderItem, SystemConstant.ADMIN_ID);
                }

                /* 增加课程空闲名额 */
                Optional<OpenCourse> optionalOpenCourse = openCourseService.findById(_openCourseRefund.getOpenCourseId());
                if (optionalOpenCourse.isPresent()) {
                    OpenCourse openCourse = optionalOpenCourse.get();
                    openCourse.setFreeCourseNumber(openCourse.getFreeCourseNumber() + 1);
                    openCourseMapper.updateById(openCourse);
                }
            }

            /* 订阅消息通知 */
            try {
                Optional<Guardian> optional = guardianService.findById(_openCourseRefund.getGuardianId());
                if (optional.isPresent()) {
                    wXTemplateService.sendRefundTemplate(optional.get().getOpenId(), _openCourseRefund.getOpenCourseOrderId(), _openCourseRefund.getOpenCourseName(), _openCourseRefund.getState(), _openCourseRefund.getOpenCoursePrice());
                }
            } catch (Exception e) {
                log.error("发送订阅消息失败，[{}]", e);
            }
        }
    }

}
