package beilv.quartz.task;

import beilv.admissionticket.domain.AdmissionTicket;
import beilv.admissionticket.service.IAdmissionTicketService;
import beilv.bootacourse.domain.BootACourse;
import beilv.bootacourse.mapper.BootACourseMapper;
import beilv.common.utils.uuid.IdUtils;
import beilv.session.domain.BeilvSession;
import beilv.session.service.IBeilvSessionService;
import beilv.site.domain.BeilvSite;
import beilv.site.service.IBeilvSiteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Component("siteTask")
public class SiteTask {

    @Autowired
    private IBeilvSessionService sessionService;

    @Autowired
    private IBeilvSiteService siteService;

    @Autowired
    private IAdmissionTicketService ticketService;

    @Autowired
    private BootACourseMapper courseMapper;

    /**
     * 门票定时任务
     * 定时将日期下的各类型场地 + 时段写入到数据表中
     *
     * @param day 天数
     */
    public void addAdmissionTicket(Integer day) {
        // 计算写入日期 = 当前日期 + 传入的day天数
        Date writeDate = addDaysToDate(new Date(), day);

        // 获取场地信息
        List<BeilvSite> siteList = siteService.getAllToList();
        // 获取时段信息
        List<BeilvSession> sessionList = sessionService.getAllToList();

        // 创建写入集合, 用于批量新增
        List<AdmissionTicket> ticketList = new ArrayList<>();
        siteList.forEach(site -> sessionList.forEach(session -> {
            // 判断场馆相同, 并且场地类型相同
            if (session.getVenueId().equals(site.getVenueId()) && session.getSiteType().equals(site.getSiteType())) {
                // 创建门票实体
                AdmissionTicket admissionTicket = new AdmissionTicket(
                        IdUtils.fastSimpleUUID(),
                        String.valueOf(session.getVenueId()),
                        site.getId().toString(),
                        session.getSiteType(),
                        session.getSession(),
                        session.getPrice(),
                        writeDate,
                        "0".equals(site.getSiteStatus()) ? "0" : "1",
                        session.getSort()
                );
                ticketList.add(admissionTicket);
            }
        }));
        // 批量写入门票信息
        ticketService.insertAdmissionTicketToList(ticketList);
    }

    /**
     * 定时更新门票状态
     * 将超过当前时间的门票信息都更新为锁定状态
     *
     * @param millisecond
     */
    public void updateTicketStatus(Long millisecond) {
        AdmissionTicket admissionTicket = new AdmissionTicket();
        admissionTicket.setAdmissionTicketStatus("0");

        List<AdmissionTicket> admissionTickets = ticketService.selectBeilvAdmissionTicketList(admissionTicket);

        List<String> ids = new ArrayList<>();

        // 获取当前日期和时间
        Date currentDate = new Date();

        // 解析ticketDate
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        // 解析session的开始时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");

        admissionTickets.forEach(ticket -> {
            try {
                // 将ticketDate和startTime合并为一个Date对象
                Date ticketDateTime = combineDateAndTime(dateFormat.parse(dateFormat.format(ticket.getTicketDate())), timeFormat.parse(ticket.getSession().split("-")[0]));

//                long tenMinutesInMillis = 10 * 60 * 1000;
                if (ticketDateTime != null) {
                    Date ticketDateTimeMinusTenMinutes = new Date(ticketDateTime.getTime() - millisecond);
                    // 判断条件
                    if (ticketDateTimeMinusTenMinutes.before(currentDate)) {
                        // 获取ticket的id并放入ids中
                        ids.add(ticket.getId());
                    }
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        if (!ids.isEmpty()) {
            ticketService.updateTicketStatus(ids, "3");
        }
    }

    /**
     * 定时更新订单状态为已核销
     */
    public void updateOrderStatusToVerification() {
        // 查询支付成功的订单
        List<BootACourse> paidOrders = courseMapper.selectPaidOrders();
        // 获取当前时间
        Date now = new Date();
        // 筛选出需要更新的订单
//        List<String> orderIdsToUpdate = paidOrders.stream()
//                .filter(order -> now.after(order.getRefund()))  // 当前时间大于refund时间
//                .map(BootACourse::getOrderId)  // 获取订单ID
//                .collect(Collectors.toList());


        Map<Boolean, List<BootACourse>> partitionedOrders = paidOrders.stream()
                .collect(Collectors.partitioningBy(order -> now.after(order.getRefund())));

        List<String> orderIdsToUpdate = partitionedOrders.get(true).stream()
                .map(BootACourse::getOrderId)
                .collect(Collectors.toList());

        List<String> ticketIdsToUpdate = partitionedOrders.get(true).stream()
                .map(BootACourse::getTicketId)
                .collect(Collectors.toList());

        // 批量更新订单状态为已核销
        if (!orderIdsToUpdate.isEmpty()) {
            courseMapper.updateOrderStatusToVerification(orderIdsToUpdate, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now));
        }
        // 批量更新门票状态为已核销
        if (!orderIdsToUpdate.isEmpty()) {
            //核销订单的同时, 更新门票信息状态
            ticketService.updateTicketStatus(ticketIdsToUpdate, "4");
        }
    }


    // 将Date类型加上指定天数的方法
    private Date addDaysToDate(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, days);
        return calendar.getTime();
    }

    // 合并日期和时间的辅助方法
    private static Date combineDateAndTime(Date date, Date time) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");

        try {
            Date parsedDate = dateFormat.parse(dateFormat.format(date));
            Date parsedTime = timeFormat.parse(timeFormat.format(time));

            long dateMillis = parsedDate.getTime();
            long timeMillis = parsedTime.getTime() - timeFormat.parse("00:00").getTime();

            return new Date(dateMillis + timeMillis);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

}
