package com.czg.service.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.czg.account.dto.BkOrderDTO;
import com.czg.account.entity.BkOrder;
import com.czg.account.entity.BkOrderTable;
import com.czg.account.service.BkOrderService;
import com.czg.account.vo.BkTableVO;
import com.czg.account.vo.BookingOrderStatisticsVO;
import com.czg.enums.OrderNoPrefixEnum;
import com.czg.exception.CzgException;
import com.czg.service.account.mapper.BkOrderMapper;
import com.czg.service.account.mapper.BkOrderTableMapper;
import com.czg.utils.CzgRandomUtils;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 预约单 服务层实现。
 *
 * @author ww
 * @since 2025-11-27
 */
@Service
public class BkOrderServiceImpl extends ServiceImpl<BkOrderMapper, BkOrder> implements BkOrderService {

    @Resource
    private BkOrderTableMapper tableMapper;

    @Override
    public BookingOrderStatisticsVO bookingOrderStatistics(Long shopId, String search, LocalDate start, LocalDate end, String status) {
        return mapper.bookingOrderStatistics(shopId, search, start, end, status);
    }

    /**
     * 预约端-预约单：列表
     */
    @Override
    public List<BkOrder> bookings(Long shopId, String search, LocalDate start, LocalDate end, String status) {
        return mapper.bookings(shopId, search, start, end, status);
    }

    @Override
    public List<BkOrderTable> bookingTables(Long shopId, Long bkOrderId) {
        return tableMapper.selectListByQuery(QueryWrapper.create().eq(BkOrderTable::getBookOrderId, bkOrderId).eq(BkOrderTable::getShopId, shopId));
    }


    @Override
    @Transactional
    public void booking(Long shopId, BkOrderDTO bkOrder) {
        BkOrder bkOrderEntity = BeanUtil.copyProperties(bkOrder, BkOrder.class);
        bkOrderEntity.setShopId(shopId);
        if (bkOrder.getId() != null) {
            bkOrderEntity.setUpBookingTime(LocalDateTime.now());
            tableMapper.deleteByQuery(QueryWrapper.create().eq(BkOrderTable::getBookOrderId, bkOrderEntity.getId()));
            tableMapper.customInsertBatch(shopId, bkOrderEntity.getId(), bkOrder.getBookingTables());
        } else {
            bkOrderEntity.setBookingOrderNo(CzgRandomUtils.randomNumber(OrderNoPrefixEnum.BK, 12, false));
        }

        bkOrderEntity.setStatus("待到店");
        bkOrderEntity.setStandardPricePerson(BigDecimal.ZERO);
        if (bkOrderEntity.getStandardPrice() != null && bkOrderEntity.getStandardPrice().compareTo(BigDecimal.ZERO) > 0) {
            if (bkOrderEntity.getStandardPriceType().contains("桌")) {
                BigDecimal seatNumBd = new BigDecimal(bkOrderEntity.getSeatNum());
                BigDecimal bookingTableNumBd = new BigDecimal(bkOrderEntity.getBookingTableNum());
                BigDecimal seatPerTable = seatNumBd.divide(bookingTableNumBd, 2, RoundingMode.HALF_UP);
                BigDecimal divide = bkOrderEntity.getStandardPrice().divide(seatPerTable, 2, RoundingMode.HALF_UP);
                bkOrderEntity.setStandardPricePerson(divide);
            } else {
                bkOrderEntity.setStandardPricePerson(bkOrderEntity.getStandardPrice());
            }
        }
        saveOrUpdate(bkOrderEntity);
        if (bkOrder.getId() == null) {
            tableMapper.customInsertBatch(shopId, bkOrderEntity.getId(), bkOrder.getBookingTables());
        }
    }

    @Override
    public void upStatus(Long shopId, String status, Long bkOrderId, String cancelReason) {
        BkOrder upBkOrder = new BkOrder();
        if ("已取消".equals(status)) {
            upBkOrder.setStatus(status);
            upBkOrder.setCancelReason(cancelReason);
            upBkOrder.setCancelTime(LocalDateTime.now());
        } else if ("已到店".equals(status)) {
            upBkOrder.setStatus(status);
            upBkOrder.setArrivalTime(LocalDateTime.now());
        }
        boolean update = update(upBkOrder, QueryWrapper.create().eq(BkOrder::getId, bkOrderId).eq(BkOrder::getShopId, shopId));
        if (!update) {
            throw new CzgException("修改失败");
        }
    }

    @Override
    public List<BkTableVO> table(Long shopId, Long areaId, LocalDate day, String seatTimeType) {
        return tableMapper.table(shopId, areaId, day, seatTimeType);
    }
}
