package org.jeecg.modules.system.app.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
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.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.app.vo.AppGameScheduleVO;
import org.jeecg.modules.app.vo.AppOrderProInfoVerifyVO;
import org.jeecg.modules.app.vo.ScanCodeQueryOrderVO;
import org.jeecg.modules.quartz.vo.JobClassNoticeVo;
import org.jeecg.modules.system.app.dto.AppOrderDTO;
import org.jeecg.modules.system.app.dto.IsinUserInfoDTO;
import org.jeecg.modules.system.app.dto.VerificationRecordDTO;
import org.jeecg.modules.system.app.entity.*;
import org.jeecg.modules.system.app.form.AppOrderPageForm;
import org.jeecg.modules.system.app.mapper.*;
import org.jeecg.modules.system.app.service.IAppOrderService;
import org.jeecg.modules.system.app.vo.AppIsinVO;
import org.jeecg.modules.system.app.vo.AppOrderInfoVO;
import org.jeecg.modules.system.app.vo.OrderPageVO;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 订单表
 * @Author: jeecg-boot
 * @Date: 2025-07-03
 * @Version: V1.0
 */
@Service
public class AppOrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> implements IAppOrderService {

    @Resource
    private AppOrderProInfoMapper appOrderProInfoMapper;

    @Resource
    private AppOrderMapper appOrderMapper;

    @Resource
    private AppSiteMapper appSiteMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private AppIsinMapper appIsinMapper;

    @Resource
    private AppCoursesVerificationRecordMapper appCoursesVerificationRecordMapper;

    @Resource
    private AppSitePriceRulesMapper appSitePriceRulesMapper;

    @Resource
    private AppSitePlaceMapper appSitePlaceMapper;

    @Resource
    private AppGameMapper appGameMapper;

    @Resource
    private AppGameScheduleMapper appGameScheduleMapper;

    @Resource
    private AppGamePriceRulesMapper appGamePriceRulesMapper;

    @Resource
    private AppCoursesMapper appCoursesMapper;
    @Resource
    private AppCoursesPriceRulesMapper appCoursesPriceRulesMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveWitchProduct(AppOrderDTO appOrderDTO) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        return Boolean.TRUE;
    }

    @Override
    public Boolean editWitchProduct(AppOrderDTO appOrderDTO) {
        return null;
    }

    @Override
    public Boolean deleteWitchProductById(String id) {
        return null;
    }

    @Override
    public AppOrderDTO queryWitchProductById(String id) {
        return null;
    }

    @Override
    public Page<OrderPageVO> queryPage(AppOrderPageForm appOrderPageForm) {
        Page<OrderPageVO> page = new Page<>(appOrderPageForm.getPageNum(), appOrderPageForm.getPageSize());

        Page<OrderPageVO> voPage = baseMapper.queryPage(page, appOrderPageForm);

        voPage.getRecords().forEach(vo -> {
            List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, vo.getId()));
            vo.setOrderProInfoList(proInfoList);
        });
        return voPage;
    }

    @Override
    public AppOrderInfoVO queryInfoById(String orderId) {
        //订单
        AppOrder appOrder = appOrderMapper.selectById(orderId);
        AppSite site = appSiteMapper.selectOne(Wrappers.lambdaQuery(AppSite.class).eq(AppSite::getOrgCode, appOrder.getOrgCode()));
        //构建返回对象
        AppOrderInfoVO appOrderInfoVO = new AppOrderInfoVO();
        //订单编号
        appOrderInfoVO.setOrderCode(appOrder.getOrderCode());
        //下单时间
        appOrderInfoVO.setCreateTime(appOrder.getCreateTime());
        //使用地信息
        appOrderInfoVO.setSiteName(site.getName());
        appOrderInfoVO.setAddress(site.getAddress());
        //付款信息
        if (appOrder.getOrderStatus() > 0) {
            appOrderInfoVO.setPayTime(appOrder.getPayTime());
            appOrderInfoVO.setPrice(appOrder.getPrice());
        }
        //子订单信息
        List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId));
        appOrderInfoVO.setProInfoList(proInfoList);
        //买家信息
        SysUser sysUser = sysUserMapper.selectById(appOrder.getUserId());
        appOrderInfoVO.setNikeName(sysUser.getUsername());
        appOrderInfoVO.setPhoneNumber(sysUser.getPhone());
        //费用信息
        appOrderInfoVO.setTotalPrice(appOrder.getOriginalPrice());
        appOrderInfoVO.setPrice(appOrder.getPrice());
        //使用记录
        List<AppIsinVO> appIsinVOList = new ArrayList<>();
        //核销记录
        List<VerificationRecordDTO> verificationRecordDTOList = new ArrayList<>();

        List<AppIsin> appIsinList = appIsinMapper.selectList(Wrappers.<AppIsin>lambdaQuery().eq(AppIsin::getOrderId, orderId).eq(AppIsin::getIsinStatus, 2));
        if (CollUtil.isNotEmpty(appIsinList)) {
            Map<IsinUserInfoDTO, List<AppIsin>> map =
                    appIsinList.stream()
                            .collect(Collectors.groupingBy(
                                    x -> new IsinUserInfoDTO(x.getFamilyId(), x.getFamilyUserName(), x.getUserPhone(), x.getTicketNo()),
                                    Collectors.mapping(AppIsin -> AppIsin, Collectors.toCollection(ArrayList::new))));
            map.keySet().forEach(p -> {
                AppIsinVO isinVO = new AppIsinVO();
                isinVO.setFamilyId(p.getFamilyId());
                isinVO.setFamilyUserName(p.getFamilyUserName());
                isinVO.setIsinCode(p.getIsinCode());
                isinVO.setIsinList(map.get(p));
                appIsinVOList.add(isinVO);
            });
            appOrderInfoVO.setIsinList(appIsinVOList);
        }
        //只有赛事有赛程
        if (appOrder.getType() == 2) {
            String gameId = appOrder.getProductIds();
            List<AppGameScheduleVO> gameScheduleVOList = appGameScheduleMapper.getListVo(gameId);
            appOrderInfoVO.setGameScheduleVOList(gameScheduleVOList);
        }
        //课程才有核销记录和优惠信息
        if (appOrder.getType() == 2) {
            BigDecimal sDiscounts = BigDecimal.ZERO;
            BigDecimal tDiscounts = BigDecimal.ZERO;
            for (AppOrderProInfo proInfo : proInfoList) {
                if (proInfo.getOrFreePro() == 1) {
                    sDiscounts = sDiscounts.add(proInfo.getOriginalPrice());
                }
                BigDecimal discounts = proInfo.getOriginalPrice().subtract(proInfo.getPrice());
                tDiscounts = tDiscounts.add(discounts);
            }
            //优惠信息
            if (sDiscounts.compareTo(BigDecimal.ZERO) != 0) {
                appOrderInfoVO.setSDiscounts(sDiscounts);
            }
            if (tDiscounts.compareTo(BigDecimal.ZERO) != 0) {
                appOrderInfoVO.setTDiscounts(tDiscounts);
            }
            //核销记录
            List<AppCoursesVerificationRecord> verificationRecords =
                    appCoursesVerificationRecordMapper.selectList(Wrappers.<AppCoursesVerificationRecord>lambdaQuery().eq(AppCoursesVerificationRecord::getOrderId, orderId));
            if (CollUtil.isNotEmpty(verificationRecords)) {
                Map<Integer, List<AppCoursesVerificationRecord>> listMap = verificationRecords.stream().collect(Collectors.groupingBy(AppCoursesVerificationRecord::getCoursesType));
                listMap.keySet().forEach(p -> {
                    VerificationRecordDTO verificationRecordDTO = new VerificationRecordDTO();
                    verificationRecordDTO.setCoursesType(p).setVerificationRecordList(listMap.get(p));
                    verificationRecordDTOList.add(new VerificationRecordDTO());
                });
                appOrderInfoVO.setVerificationRecordDTOList(verificationRecordDTOList);
            }
        }
        return appOrderInfoVO;
    }

    @Override
    public ScanCodeQueryOrderVO scanCodeQueryOrder(String orderId) {

        AppOrder appOrder = appOrderMapper.selectById(orderId);
        AppSite site = appSiteMapper.selectOne(Wrappers.<AppSite>lambdaQuery().eq(AppSite::getOrgCode, appOrder.getOrgCode()));

        ScanCodeQueryOrderVO scanCodeQueryOrderVO = new ScanCodeQueryOrderVO();
        scanCodeQueryOrderVO.setSiteName(site.getName());
        scanCodeQueryOrderVO.setAmount(appOrder.getAmount());

        List<AppOrderProInfoVerifyVO> orderProInfoVOList = new ArrayList<>();
        List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId));

        for (AppOrderProInfo appOrderProInfo : proInfoList) {

            AppIsin appIsin = appIsinMapper.selectOne(Wrappers.<AppIsin>lambdaQuery().eq(AppIsin::getOrderProInfoId, appOrderProInfo.getId()));

            AppOrderProInfoVerifyVO appOrderProInfoVerifyVO = new AppOrderProInfoVerifyVO();
            if (ObjectUtil.isNotEmpty(appIsin)) {
                appOrderProInfoVerifyVO.setIsinId(appIsin.getId());
                appOrderProInfoVerifyVO.setIsinStatus(appIsin.getIsinStatus());
            }
            appOrderProInfoVerifyVO.setAppOrderProInfo(appOrderProInfo);

            orderProInfoVOList.add(appOrderProInfoVerifyVO);
        }
        scanCodeQueryOrderVO.setAppOrderProInfoVerifyVOS(orderProInfoVOList);

        //0-学校 1-包场 2-无固定场 3-个人赛 4-团队赛 5-课程    学校及包场即为商品不用查
        if (appOrder.getType() == 0){
            if (appOrder.getOrderType() == 2) {
                String productIds = appOrder.getProductIds();
                AppSitePriceRules appSitePriceRules = appSitePriceRulesMapper.selectById(productIds);
                AppSitePlace appSitePlace = appSitePlaceMapper.selectById(appSitePriceRules.getSitePlaceId());
                scanCodeQueryOrderVO.setProductName(appSitePlace.getName());
                scanCodeQueryOrderVO.setProductImage(appSitePlace.getCover());
                scanCodeQueryOrderVO.setPrice(appSitePriceRules.getSellingPrice());
            }
        }
        if (appOrder.getType() == 1){
                AppGamePriceRules appGamePriceRules = appGamePriceRulesMapper.selectById(appOrder.getProductIds());
                AppGame appGame = appGameMapper.selectById(appGamePriceRules.getGameId());

                scanCodeQueryOrderVO.setProductName(appGame.getName());
                scanCodeQueryOrderVO.setProductImage(appGame.getCover());
                scanCodeQueryOrderVO.setGameType(appGamePriceRules.getType());
                scanCodeQueryOrderVO.setPrice(appGamePriceRules.getSellingPrice());
        }

        if (appOrder.getType() == 2) {
            AppCourses appCourses = appCoursesMapper.selectById(appOrder.getProductIds());
            scanCodeQueryOrderVO.setProductName(appCourses.getName());
            scanCodeQueryOrderVO.setProductImage(appCourses.getCover());
            scanCodeQueryOrderVO.setPrice(appCourses.getSellingPrice());
        }
        return scanCodeQueryOrderVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean scanCodeVerification(List<String> isinIds) {

        for (String isinId : isinIds) {
            //查询对应券号
            AppIsin appIsin = appIsinMapper.selectById(isinId);
            appIsin.setIsinStatus(CommonConstant.ISIN_STATUS_2);
            appIsinMapper.updateById(appIsin);
            //修改订单状态
            String orderProInfoId = appIsin.getOrderProInfoId();
            AppOrderProInfo appOrderProInfo = appOrderProInfoMapper.selectById(orderProInfoId);
            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_1);
            appOrderProInfoMapper.updateById(appOrderProInfo);
        }
        return Boolean.TRUE;
    }

    @Override
    public List<JobClassNoticeVo> findByJob(Integer hoursBefore,Date date, int maxRetry) {
        return appOrderMapper.findByJob(hoursBefore,date,maxRetry);
    }

}
