package cn.ysk.cashier.mybatis.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.cons.TableConstant;
import cn.ysk.cashier.dto.shoptable.ShopEatTypeInfoDTO;
import cn.ysk.cashier.enums.*;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.mapper.MpShopInfoMapper;
import cn.ysk.cashier.mybatis.mapper.MpShopTableMapper;
import cn.ysk.cashier.mybatis.mapper.TbCashierCartMapper;
import cn.ysk.cashier.mybatis.service.MpCashierCartService;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.pojo.shop.TbShopTable;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * (TbShopPermission)表服务实现类
 *
 * @author makejava
 * @since 2024-09-14 17:08:49
 */
@Service
public class MpCashierCartServiceImpl extends ServiceImpl<TbCashierCartMapper, TbCashierCart> implements MpCashierCartService {
    private final MpShopInfoMapper mpShopInfoMapper;

    private final MpShopTableMapper shopTableMapper;

    public MpCashierCartServiceImpl(MpShopInfoMapper mpShopInfoMapper, MpShopTableMapper shopTableMapper) {
        this.mpShopInfoMapper = mpShopInfoMapper;
        this.shopTableMapper = shopTableMapper;
    }

    @Override
    public List<TbCashierCart> selectTakeoutCart(String masterId, Integer shopId) {
        return list(new LambdaQueryWrapper<TbCashierCart>()
                .eq(TbCashierCart::getShopId, shopId)
                .eq(TbCashierCart::getMasterId, masterId)
                .eq(TbCashierCart::getUseType, OrderUseTypeEnum.TAKEOUT.getValue())
                .gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime()));
    }

    @Override
    public List<TbCashierCart> selectUnTableCart(String masterId, Integer shopId) {
        TbShopInfo shopInfo = mpShopInfoMapper.selectOne(new LambdaQueryWrapper<TbShopInfo>()
                .eq(TbShopInfo::getId, shopId)
                .eq(TbShopInfo::getStatus, 1));
        if (shopInfo == null) {
            throw new BadRequestException("店铺信息不存在");
        }

        return list(new LambdaQueryWrapper<TbCashierCart>()
                .eq(TbCashierCart::getShopId, shopId)
                .eq(TbCashierCart::getMasterId, masterId)
                .eq(TbCashierCart::getUseType, TableConstant.OrderInfo.UseType.NONE_TABLE.getValue())
                .gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime()));
    }

    @Override
    public long countByTableId(Integer shopId, String tableId, OrderStatusEnums... statusEnums) {
        LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
                .eq(TbCashierCart::getShopId, shopId)
                .gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime())
                .eq(TbCashierCart::getTableId, tableId);
        if (statusEnums.length > 0) {
            ArrayList<String> stateList = new ArrayList<>();
            for (OrderStatusEnums statusEnum : statusEnums) {
                stateList.add(statusEnum.getValue());
            }
            queryWrapper.in(TbCashierCart::getStatus, stateList);
        }
        return count(queryWrapper);
    }

    @Override
    public boolean clearCartByTableIdAndUseType(String tableId, String useType, Integer shopId) {
        return remove(new LambdaQueryWrapper<TbCashierCart>()
                .in(TbCashierCart::getStatus, OrderStatusEnums.CREATE.getValue(), OrderStatusEnums.RETURN.getValue())
                .gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime())
                .eq(TbCashierCart::getShopId, shopId)
                .eq(TbCashierCart::getTableId, tableId)
                .eq(TbCashierCart::getUseType, useType));
    }

    @Override
    public boolean updateStateByOrderId(TableConstant.OrderInfo.Status status, Integer orderId) {
        return update(new LambdaUpdateWrapper<TbCashierCart>()
                .eq(TbCashierCart::getOrderId, orderId)
                .set(TbCashierCart::getStatus, status.getValue()));
    }

    @Override
    public boolean updateMemberAndAmountByOrderId(Integer orderId, boolean isMember) {
        return update(new LambdaUpdateWrapper<TbCashierCart>()
                .eq(TbCashierCart::getOrderId, orderId)
                .setSql(StrUtil.format("total_amount=total_number*{}", isMember ? "member_price" : "sale_price"))
                .set(TbCashierCart::getIsMember, isMember ? 1 : 0));
    }

    @Override
    public List<TbCashierCart> selectByShopEatType(ShopEatTypeInfoDTO shopEatTypeInfoDTO, String masterId, TableConstant.OrderInfo.Status... statuses) {
        LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
                .eq(TbCashierCart::getShopId, shopEatTypeInfoDTO.getShopId())
                .eq(TbCashierCart::getUseType, shopEatTypeInfoDTO.getUseType())
                .gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime())
                .and(q -> q.eq(TbCashierCart::getMasterId, masterId).or().isNull(TbCashierCart::getMasterId));

        if (statuses.length == 0) {
            queryWrapper.in(TbCashierCart::getStatus, "create", "return");
        }else {
            queryWrapper.in(TbCashierCart::getStatus, CollUtil.newArrayList(statuses));
        }

        // 非堂食校验台桌状态
        if (shopEatTypeInfoDTO.isTakeout()) {
            queryWrapper.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""))
                    .in(TbCashierCart::getPlatformType, OrderPlatformTypeEnum.PC.getValue(), OrderPlatformTypeEnum.CASH.getValue());
        } else {
            if (StrUtil.isNotBlank(shopEatTypeInfoDTO.getTableId())) {
                queryWrapper.eq(TbCashierCart::getTableId, shopEatTypeInfoDTO.getTableId());
            } else {
                queryWrapper.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""));
            }

        }
        return list(queryWrapper);
    }

    @Override
    public List<TbCashierCart> selectByOrderIdAndState(Integer orderId, TableConstant.OrderInfo.Status... status) {
        LambdaQueryChainWrapper<TbCashierCart> queryChainWrapper = lambdaQuery().eq(TbCashierCart::getOrderId, orderId);
        if (status != null && status.length > 0) {
            queryChainWrapper.in(TbCashierCart::getStatus, CollUtil.newArrayList(status));
        }
        return queryChainWrapper.list();
    }

    @Override
    public TbCashierCart selectOneCartByShopEatType(ShopEatTypeInfoDTO shopEatTypeInfoDTO, String masterId, Integer productId, Integer skuId, boolean isGift, boolean isTemp) {
        LambdaQueryWrapper<TbCashierCart> query = new LambdaQueryWrapper<TbCashierCart>()
                .eq(TbCashierCart::getShopId, shopEatTypeInfoDTO.getShopId())
                .gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime())
                .isNull(TbCashierCart::getPlaceNum)
                .eq(TbCashierCart::getUseType, shopEatTypeInfoDTO.getUseType())
                .eq(TbCashierCart::getStatus, "create")
                .eq(TbCashierCart::getIsGift, isGift)
                .and(q -> q.eq(TbCashierCart::getMasterId, masterId).or().isNull(TbCashierCart::getMasterId));
        if (isTemp) {
            query.isNull(TbCashierCart::getProductId).isNull(TbCashierCart::getSkuId).eq(TbCashierCart::getIsTemporary, 1);
        }else {
            query.eq(TbCashierCart::getProductId, productId)
                    .eq(TbCashierCart::getSkuId, skuId);
        }

        // 外带只查询pc和收银机商品
        if (shopEatTypeInfoDTO.isTakeout()) {
            query.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""))
                    .in(TbCashierCart::getPlatformType, "pc", "cash");
        } else {
            query.eq(TbCashierCart::getTableId, shopEatTypeInfoDTO.getTableId());
        }

        return getOne(query);
    }

    @Override
    public TbCashierCart selectByShopIdAndId(Integer shopId, Integer cartId, TableConstant.OrderInfo.Status... statuses) {
        LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
                .eq(TbCashierCart::getShopId, shopId)
                .eq(TbCashierCart::getId, cartId);
        if (statuses.length != 0) {
            queryWrapper.in(TbCashierCart::getStatus, CollUtil.newArrayList(statuses));
        }
        return getOne(queryWrapper);
    }
}

