package cn.iocoder.yudao.module.course.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.base.constant.SchoolBaseConstants;
import cn.iocoder.yudao.module.base.service.SchoolNotifyMessageSendService;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseOrderMapper;
import cn.iocoder.yudao.module.course.service.ProcessService;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.vo.SchoolCommissionVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 驾照报名订单 Service 实现类
 *
 * @author 若依
 */
@Service
@Validated
public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderMapper, SchoolCourseOrder> implements SchoolCourseOrderService {

    @Resource
    private SchoolCourseOrderMapper schoolCourseOrderMapper;

    @Resource
    private ProcessService processService;

    @Autowired
    private SchoolNotifyMessageSendService schoolNotifyMessageSendService;

    @Resource
    private AdminUserApi userApi;
    @Resource
    @Lazy
    private RoleApi roleApi;

    @Override
    public String createSchoolCourseOrder(SchoolCourseOrderVO createReqVO) {
        // 插入
        SchoolCourseOrder schoolCourseOrder = BeanUtils.toBean(createReqVO, SchoolCourseOrder.class);
        schoolCourseOrderMapper.insert(schoolCourseOrder);
        // 返回
        return schoolCourseOrder.getId();
    }

    @Override
    public void updateSchoolCourseOrder(SchoolCourseOrderVO updateReqVO) {
        // 更新
        SchoolCourseOrder updateObj = BeanUtils.toBean(updateReqVO, SchoolCourseOrder.class);
        schoolCourseOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteSchoolCourseOrder(String id) {
        // 删除
        schoolCourseOrderMapper.deleteById(id);
    }


    @Override
    public SchoolCourseOrder getSchoolCourseOrder(String id) {
        return schoolCourseOrderMapper.selectById(id);
    }


    /**
     * 获得驾照报名订单分页
     *
     * @param page      分页参数
     * @param pageReqVO SchoolCourseOrderVO
     * @return com.baomidou.mybatisplus.core.metadata.IPage<cn.iocoder.yudao.module.course.vo.SchoolCommissionVO>
     * @author PQZ
     * @date 10:10 2025/2/25
     **/
    @Override
    public IPage<SchoolCourseOrderVO> queryPage(Page<SchoolCommissionVO> page, SchoolCourseOrderVO pageReqVO) {
        return schoolCourseOrderMapper.queryPage(pageReqVO, page);
    }
    @Override
        public IPage<SchoolCourseOrderVO> queryPageNew(Page<SchoolCommissionVO> page, SchoolCourseOrderVO pageReqVO) {
            return schoolCourseOrderMapper.queryPageNew(pageReqVO,page);
        }

    /**
     * 终止订单
     *
     * @param orderNo   订单号
     * @param endReason 终止原因
     * @param endTime   终止时间
     */
    @Override
    @Transactional
    public void endOrder(String orderNo, String endReason, LocalDateTime endTime) {
        // 修改订单表
        baseMapper.update(Wrappers.lambdaUpdate(SchoolCourseOrder.class)
                .eq(SchoolCourseOrder::getOrderNo, orderNo)
                .set(SchoolCourseOrder::getEndReason, endReason)
                .set(SchoolCourseOrder::getEndTime, endTime)
                .set(SchoolCourseOrder::getIfEnd, SchoolBaseConstants.COMMON_YES));

        // 查询学员信息
        SchoolCourseOrder schoolCourseOrder = baseMapper.selectOne(Wrappers.lambdaQuery(SchoolCourseOrder.class)
                .eq(SchoolCourseOrder::getOrderNo, orderNo));

        // 删除学员未开始和训练中的科目
        processService.remove(Wrappers.lambdaQuery(Process.class)
                .eq(Process::getUserId, schoolCourseOrder.getUserId())
                .eq(Process::getCourseId, schoolCourseOrder.getCourseId())
                .and(q -> q.eq(Process::getStatus, SchoolBaseConstants.PROCESS_STATUS_NOT_START)
                        .or()
                        .eq(Process::getStatus, SchoolBaseConstants.PROCESS_STATUS_IN_PROGRESS))
        );

        // 准备消息内容
        String message = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_COURSE_END, schoolCourseOrder.getCourseName());

        // 发送消息给学员
        schoolNotifyMessageSendService.sendMessage(Long.valueOf(schoolCourseOrder.getUserId()), message, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_MEMBER, null);

    }

    /**
     * 快速创建订单
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    @Override
    public String fastCreateSchoolCourseOrder(SchoolCourseOrderVO createReqVO) {
        // 根据订单id查询旧订单信息
        SchoolCourseOrder oldOrder = baseMapper.selectById(createReqVO.getId());

        if (oldOrder == null) {
            throw new RuntimeException("订单不存在");
        }

        //判断新订单课程与旧订单课程是否一致
        if (!oldOrder.getCourseId().equals(createReqVO.getCourseId())) {
            // 删除学习记录表中的课程记录
            processService.remove(Wrappers.lambdaQuery(Process.class)
                    .eq(Process::getUserId, oldOrder.getUserId())
                    .eq(Process::getCourseId, oldOrder.getCourseId()));
        }

        SchoolCourseOrder schoolCourseOrder = BeanUtil.copyProperties(oldOrder, SchoolCourseOrder.class);
        schoolCourseOrder.setOldOrderId(oldOrder.getId());
        //生成订单号
        schoolCourseOrder.setOrderNo(generateOrderNumber());
        schoolCourseOrder.setCourseId(createReqVO.getCourseId());
        schoolCourseOrder.setCourseName(createReqVO.getCourseName());
        schoolCourseOrder.setCourseType(createReqVO.getCourseType());
        schoolCourseOrder.setCoachUserId(createReqVO.getCoachUserId());
        schoolCourseOrder.setCoachUserName(createReqVO.getCoachUserName());

        schoolCourseOrder.setId(null);
        schoolCourseOrder.setCreateTime(null);
        schoolCourseOrder.setUpdateTime(null);
        schoolCourseOrder.setDeleted(SchoolBaseConstants.COMMON_NO);
        schoolCourseOrder.setIfAssignmentCoach(SchoolBaseConstants.SCHOOL_COURSE_ORDER_IS_NOT_ASSIGN_COACH);
        schoolCourseOrder.setIfEnd(SchoolBaseConstants.COMMON_NO);
        schoolCourseOrder.setEndReason(null);
        schoolCourseOrder.setEndTime(null);
        schoolCourseOrderMapper.insert(schoolCourseOrder);
        return null;
    }

    /**
     * 根据用户id获取订单信息
     *
     * @param loginUserId 用户id
     * @return List<SchoolCourseOrderVO>
     */
    @Override
    public List<SchoolCourseOrderVO> getCourseByLoginUser(Long loginUserId) {
        List<SchoolCourseOrder> list = list(Wrappers.lambdaQuery(SchoolCourseOrder.class)
                .eq(SchoolCourseOrder::getUserId, loginUserId)
                .eq(SchoolCourseOrder::getIfEnd, SchoolBaseConstants.COMMON_NO)
                .eq(SchoolCourseOrder::getIfAssignmentCoach, SchoolBaseConstants.SCHOOL_COURSE_ORDER_IS_ASSIGN_COACH));
        return BeanUtil.copyToList(list, SchoolCourseOrderVO.class);
    }

    /**
     * 根据获取订单信息
     *
     * @param userId 用户id
     * @return List<SchoolCourseOrderVO>
     */
    @Override
    public List<SchoolCourseOrderVO> getCourseByInfo(Long userId, String courseId) {
        List<SchoolCourseOrder> list = list(Wrappers.lambdaQuery(SchoolCourseOrder.class)
                .eq(SchoolCourseOrder::getUserId, userId)
                .eq(SchoolCourseOrder::getCourseId, courseId)
                .eq(SchoolCourseOrder::getIfEnd, SchoolBaseConstants.COMMON_NO)
                .eq(SchoolCourseOrder::getIfAssignmentCoach, SchoolBaseConstants.SCHOOL_COURSE_ORDER_IS_ASSIGN_COACH));
        return BeanUtil.copyToList(list, SchoolCourseOrderVO.class);
    }

    /**
     * 报名之后发送对应消息
     */
    @Override
    public Boolean sendOrderMessage(String studentName, String courseName, Long coachId) {

        if(coachId != null){
            // 准备消息内容
            String message = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_ENROLL, studentName, courseName);

            // 发送消息给教练
            schoolNotifyMessageSendService.sendMessage(coachId, message, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN, null);
        }


        // 发送消息给所有办公室人员
        Long tenantId = TenantContextHolder.getTenantId();
        List<UserDTO> officeStaffList = roleApi.selectUserListByRoleCode(tenantId, "bgs");

        if (officeStaffList != null && !officeStaffList.isEmpty()) {
            String officeMessage = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_ENROLL_TO_OFFICE, studentName, courseName);

            for (UserDTO staff : officeStaffList) {
                schoolNotifyMessageSendService.sendMessage(staff.getId(), officeMessage, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN, null);
            }
        }

        return Boolean.TRUE;
    }

    /**
     * 教练修改学员毕业时间
     */
    @Override
    public void updateStudentGradTime(String studentId, String gradTime) {
        Long coachId = SecurityFrameworkUtils.getLoginUserId();
        List<SchoolCourseOrder> students = schoolCourseOrderMapper.selectList(new LambdaQueryWrapper<SchoolCourseOrder>()
                .eq(SchoolCourseOrder::getUserId, studentId)
                .eq(SchoolCourseOrder::getCoachUserId, coachId)
                .orderByDesc(SchoolCourseOrder::getUpdateTime)
        );
        if (students != null && !students.isEmpty()) {
            SchoolCourseOrder latestStudent = students.get(0);

            // 字符串转 Date
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date gradTimeDate;
            try {
                gradTimeDate = sdf.parse(gradTime);
            } catch (ParseException e) {
                throw new RuntimeException("毕业时间格式错误，应为 yyyy-MM-dd", e);
            }

            SchoolCourseOrder updateEntity = new SchoolCourseOrder();
            updateEntity.setId(latestStudent.getId());
            updateEntity.setGradTime(gradTimeDate);

            schoolCourseOrderMapper.updateById(updateEntity);
        }
    }

    /**
     * 教练修改学员拿证时间
     */
    @Override
    public void updateStudentPassTime(String studentId, String passTime) {
        Long coachId = SecurityFrameworkUtils.getLoginUserId();
        List<SchoolCourseOrder> students = schoolCourseOrderMapper.selectList(new LambdaQueryWrapper<SchoolCourseOrder>()
                .eq(SchoolCourseOrder::getUserId, studentId)
                .eq(SchoolCourseOrder::getCoachUserId, coachId)
                .orderByDesc(SchoolCourseOrder::getUpdateTime)
        );
        if (students != null && !students.isEmpty()) {
            SchoolCourseOrder latestStudent = students.get(0);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date passTimeDate;
            try {
                passTimeDate = sdf.parse(passTime);
            } catch (ParseException e) {
                throw new RuntimeException("毕业时间格式错误，应为 yyyy-MM-dd", e);
            }

            SchoolCourseOrder updateEntity = new SchoolCourseOrder();
            updateEntity.setId(latestStudent.getId());
            updateEntity.setPassTime(passTimeDate);

            schoolCourseOrderMapper.updateById(updateEntity);
        }
    }

    public String generateOrderNumber() {
        return "ORDER" + UUID.randomUUID().toString().replace("-", "").substring(0, 10);
    }

}
