package shop.alien.store.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import shop.alien.entity.store.LifeNotice;
import shop.alien.entity.store.StoreBookingTable;
import shop.alien.entity.store.StoreUser;
import shop.alien.entity.store.UserReservation;
import shop.alien.entity.store.UserReservationOrder;
import shop.alien.entity.store.UserReservationTable;
import shop.alien.mapper.LifeNoticeMapper;
import shop.alien.mapper.StoreUserMapper;
import shop.alien.mapper.UserReservationMapper;
import shop.alien.mapper.UserReservationOrderMapper;
import shop.alien.mapper.UserReservationTableMapper;
import shop.alien.store.service.ReservationNoticeAsyncService;
import shop.alien.store.service.StoreBookingTableService;
import shop.alien.util.type.LifeNoticeUtil;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 预约相关通知异步发送实现：查询通知参数 + 落库均在异步中执行
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReservationNoticeAsyncServiceImpl implements ReservationNoticeAsyncService {

    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;
    private final UserReservationOrderMapper userReservationOrderMapper;
    private final UserReservationMapper userReservationMapper;
    private final StoreUserMapper storeUserMapper;
    private final UserReservationTableMapper userReservationTableMapper;
    private final StoreBookingTableService storeBookingTableService;

    @Async("taskExecutor")
    @Override
    public void sendCancelReminderToStore(Integer orderId) {
        if (orderId == null) {
            return;
        }
        try {
            UserReservationOrder order = userReservationOrderMapper.selectById(orderId);
            if (order == null || order.getReservationId() == null) {
                return;
            }
            Integer reservationId = order.getReservationId();
            UserReservation reservation = userReservationMapper.selectById(reservationId);
            if (reservation == null) {
                return;
            }
            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>()
                    .eq(StoreUser::getStoreId, reservation.getStoreId())
                    .eq(StoreUser::getDeleteFlag, 0)
                    .last("LIMIT 1"));
            if (storeUser == null || storeUser.getPhone() == null || storeUser.getPhone().trim().isEmpty()) {
                return;
            }
            String storePhone = storeUser.getPhone().trim();
            String dateTime = reservation.getStartTime() != null && !reservation.getStartTime().trim().isEmpty()
                    ? reservation.getStartTime().trim() : "未知时间";
            List<UserReservationTable> reservationTables = userReservationTableMapper.selectList(
                    new LambdaQueryWrapper<UserReservationTable>()
                            .eq(UserReservationTable::getReservationId, reservationId)
                            .eq(UserReservationTable::getDeleteFlag, 0)
                            .orderByAsc(UserReservationTable::getSort));
            String tableNumber = "未知桌号";
            if (reservationTables != null && !reservationTables.isEmpty()) {
                List<String> tableNumbers = reservationTables.stream()
                        .map(rt -> {
                            StoreBookingTable table = storeBookingTableService.getById(rt.getTableId());
                            return table != null && table.getTableNumber() != null ? table.getTableNumber() : null;
                        })
                        .filter(tn -> tn != null && !tn.trim().isEmpty())
                        .collect(Collectors.toList());
                if (!tableNumbers.isEmpty()) {
                    tableNumber = String.join(",", tableNumbers);
                }
            }
            String message = "用户取消了" + dateTime + "预订的" + tableNumber + "的桌位";

            JSONObject contextJson = new JSONObject();
            contextJson.put("message", message);
            contextJson.put("reservationId", reservationId);
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setSenderId("system");
            lifeNotice.setReceiverId("store_" + storePhone);
            lifeNotice.setBusinessId(reservationId);
            lifeNotice.setTitle("订单取消提醒");
            lifeNotice.setContext(contextJson.toJSONString());
            lifeNotice.setNoticeType(2);
            lifeNotice.setIsRead(0);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);
            log.info("用户取消预订已通知商家，reservationId={}, receiverId=store_{}", reservationId, storePhone);
        } catch (Exception e) {
            log.error("发送订单取消提醒通知异常，orderId={}", orderId, e);
        }
    }

    @Async("taskExecutor")
    @Override
    public void sendUpdateReminderToStore(Integer reservationId, String oldDateTime, String oldTableNumber, String newDateTime, String newTableNumber) {
        if (reservationId == null) {
            return;
        }
        try {
            UserReservation reservation = userReservationMapper.selectById(reservationId);
            if (reservation == null) {
                return;
            }
            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>()
                    .eq(StoreUser::getStoreId, reservation.getStoreId())
                    .eq(StoreUser::getDeleteFlag, 0)
                    .last("LIMIT 1"));
            if (storeUser == null || storeUser.getPhone() == null || storeUser.getPhone().trim().isEmpty()) {
                return;
            }
            String storePhone = storeUser.getPhone().trim();
            String oTime = oldDateTime != null && !oldDateTime.trim().isEmpty() ? oldDateTime.trim() : "未知时间";
            String oTable = oldTableNumber != null && !oldTableNumber.trim().isEmpty() ? oldTableNumber.trim() : "未知桌号";
            String nTime = newDateTime != null && !newDateTime.trim().isEmpty() ? newDateTime.trim() : "未知时间";
            String nTable = newTableNumber != null && !newTableNumber.trim().isEmpty() ? newTableNumber.trim() : "未知桌号";
            String message = "用户修改了预订信息,原预订信息为:" + oTime + "," + oTable + "桌位,修改后为:" + nTime + "," + nTable + "桌位";

            JSONObject contextJson = new JSONObject();
            contextJson.put("message", message);
            contextJson.put("reservationId", reservationId);
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setSenderId("system");
            lifeNotice.setReceiverId("store_" + storePhone);
            lifeNotice.setBusinessId(reservationId);
            lifeNotice.setTitle("订单修改提醒");
            lifeNotice.setContext(contextJson.toJSONString());
            lifeNotice.setNoticeType(2);
            lifeNotice.setIsRead(0);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);
            log.info("用户修改预订已通知商家，reservationId={}, receiverId=store_{}", reservationId, storePhone);
        } catch (Exception e) {
            log.error("发送订单修改提醒通知异常，reservationId={}", reservationId, e);
        }
    }

    @Async("taskExecutor")
    @Override
    public void sendExpiredReminderToStore(Integer reservationId) {
        if (reservationId == null) {
            return;
        }
        try {
            UserReservation reservation = userReservationMapper.selectById(reservationId);
            if (reservation == null) {
                return;
            }
            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>()
                    .eq(StoreUser::getStoreId, reservation.getStoreId())
                    .eq(StoreUser::getDeleteFlag, 0)
                    .last("LIMIT 1"));
            if (storeUser == null || storeUser.getPhone() == null || storeUser.getPhone().trim().isEmpty()) {
                return;
            }
            String storePhone = storeUser.getPhone().trim();
            String dateTime = reservation.getStartTime() != null && !reservation.getStartTime().trim().isEmpty()
                    ? reservation.getStartTime().trim() : "未知时间";
            List<UserReservationTable> reservationTables = userReservationTableMapper.selectList(
                    new LambdaQueryWrapper<UserReservationTable>()
                            .eq(UserReservationTable::getReservationId, reservationId)
                            .eq(UserReservationTable::getDeleteFlag, 0)
                            .orderByAsc(UserReservationTable::getSort));
            String tableNumber = "未知桌号";
            if (reservationTables != null && !reservationTables.isEmpty()) {
                List<String> tableNumbers = reservationTables.stream()
                        .map(rt -> {
                            StoreBookingTable table = storeBookingTableService.getById(rt.getTableId());
                            return table != null && table.getTableNumber() != null ? table.getTableNumber() : null;
                        })
                        .filter(tn -> tn != null && !tn.trim().isEmpty())
                        .collect(Collectors.toList());
                if (!tableNumbers.isEmpty()) {
                    tableNumber = String.join(",", tableNumbers);
                }
            }
            String message = "用户预订了" + dateTime + "的" + tableNumber + "的桌位,已超过预订时间";

            JSONObject contextJson = new JSONObject();
            contextJson.put("message", message);
            contextJson.put("reservationId", reservationId);
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setSenderId("system");
            lifeNotice.setReceiverId("store_" + storePhone);
            lifeNotice.setBusinessId(reservationId);
            lifeNotice.setTitle("订单过期提醒");
            lifeNotice.setContext(contextJson.toJSONString());
            lifeNotice.setNoticeType(2);
            lifeNotice.setIsRead(0);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);
            log.info("订单过期已通知商家，reservationId={}, receiverId=store_{}", reservationId, storePhone);
        } catch (Exception e) {
            log.error("发送订单过期提醒通知异常，reservationId={}", reservationId, e);
        }
    }
}
