package com.ruoyi.ss.store.service.impl;

import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.device.domain.DeviceQuery;
import com.ruoyi.ss.device.service.DeviceService;
import com.ruoyi.ss.order.domain.OrderQuery;
import com.ruoyi.ss.order.service.IOrderService;
import com.ruoyi.ss.room.domain.RoomQuery;
import com.ruoyi.ss.room.service.IRoomService;
import com.ruoyi.ss.store.domain.StoreVO;
import com.ruoyi.ss.store.service.IStoreAssembler;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.ss.user.domain.UserVO;
import com.ruoyi.ss.user.service.IUserService;
import com.ruoyi.system.domain.vo.InCome;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;

import static com.ruoyi.common.constant.ServiceConstants.*;

/**
 * @author qzz
 * 2024/4/29
 */
@Service
public class StoreAssemblerImpl implements IStoreAssembler {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IStoreService storeService;


    /**
     * 拼接设备数量
     *
     * @param list 店铺列表
     */
    @Override
    public void assembleDeviceCount(List<StoreVO> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return;
        }
        for (StoreVO vo : list) {
            // 统计设备数量，设备表中的store_id，投放状态
            deviceNum(vo);
        }
    }

    /**
     * 拼接设备数量
     *
     * @param list 店铺列表
     */
    @Override
    public void assembleRuleInfo(List<StoreVO> list) {
//        if (CollectionUtils.isEmptyElement(list)) {
//            return;
//        }
//        Map<Long, Integer> countMap = deviceService.selectCountMapByStoreIds(list.stream().map(StoreVo::getStoreId).collect(Collectors.toList()));
    }

    /**
     * 拼接距离
     * @param list 店铺列表
     * @param lon 经度
     * @param lat 纬度
     */
    @Override
    public void assembleDistance(List<StoreVO> list, String lon, String lat) {
        if (list.isEmpty()) {
            return;
        }
        for (StoreVO eStoreVO : list) {
            eStoreVO.setDistance(CommonUtil.getDistance(lon, lat, eStoreVO.getLng(), eStoreVO.getLat()));
        }
        // 按距离升序排序
        list.sort(Comparator.comparingDouble(StoreVO::getDistance));
    }

    /**
     * 拼接统计数据
     * @param vo 店铺对象
     *
     */
    @Override
    public void assembleStatisticalData(StoreVO vo,LocalDate payStartTime, LocalDate payEndTime) {
        if (vo == null) {
            return;
        }

        // 拼接今日营收、本月营收、总营收
        setIncome(vo);

        // 房间总数、正在使用中的房间数、设施总数、正在使用中的设施数
        roomNum(vo);

        // 统计设备数量，设备表中的store_id，投放状态
        deviceNum(vo);

        // 近7天/30天的收入
        getIncomeList(vo,payStartTime,payEndTime);
    }

    @Override
    public void assembleRevenue(List<StoreVO> list) {
        for (StoreVO vo : list){
            // 拼接今日营收、总营收
            OrderQuery orderQuery = new OrderQuery();
            orderQuery.setStoreId(vo.getStoreId());
            vo.setTotalIncome(orderService.getOrderFee(orderQuery));// 总营收
            vo.setTodayIncome(orderService.getRevenueByTimeType(TIME_LIMIT_TODAY,orderQuery));//今日营收

            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            orderQuery.setStartTime(now.with(LocalTime.MIN).format(formatter));
            orderQuery.setEndTime(now.format(formatter));
            vo.setTodayOrderNum(orderService.getCount(orderQuery));
        }
    }

    @Override
    public void assembleBelongStore(List<StoreVO> list, Long userId) {
        UserVO userVO = userService.selectUserById(userId);
        if (userVO == null) {
            return;
        }
        StoreVO storeVO = storeService.selectEStoreByStoreId(userVO.getStoreId());
        if(storeVO != null){
            list.add(storeVO);
        }
    }


    private void getIncomeList(StoreVO vo, LocalDate payStartTime, LocalDate payEndTime) {
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setStoreId(vo.getStoreId());

        orderQuery.setPayStartTime(payStartTime);
        orderQuery.setPayEndTime(payEndTime);
        List<InCome> inComeList = orderService.getInComeList(orderQuery);

        if (payStartTime != null && payEndTime!= null) {
            inComeList = CollectionUtils.fillVoids(inComeList, InCome::getDay, (date) -> {
                InCome co = new InCome();
                co.setDay(date);
                co.setOrderIncome(BigDecimal.ZERO);
                co.setOrderNum(0);
                return co;
            }, payStartTime, payEndTime);
        }
        vo.setInComeList(inComeList);
    }

    private void setIncome(StoreVO vo) {
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setStoreId(vo.getStoreId());
        BigDecimal totalRevenue = orderService.getOrderFee(orderQuery);
        vo.setTotalIncome(totalRevenue);// 总营收
        vo.setTodayIncome(orderService.getRevenueByTimeType(TIME_LIMIT_TODAY,orderQuery));
        vo.setMonthIncome(orderService.getRevenueByTimeType(TIME_LIMIT_MONTH,orderQuery));
    }

    private void roomNum(StoreVO vo) {
        RoomQuery query = new RoomQuery();
        query.setStoreId(vo.getStoreId());
        query.setType2(ROOM_TYPE2_PRIVATE_ROOM);
        vo.setTotalRoomNum(roomService.getCount(query));
        query.setStatus(ROOM_STATUS_INUSE);
        vo.setUsingRoomNum(roomService.getCount(query));
        query.setType2(ROOM_TYPE2_LOBBY_DEVICE);
        vo.setUsingFacilityNum(roomService.getCount(query));
        query.setStatus(null);
        vo.setTotalFacilities(roomService.getCount(query));
    }

    private void deviceNum(StoreVO vo) {
        DeviceQuery query1 = new DeviceQuery();
        query1.setStoreId(vo.getStoreId());
        int i = deviceService.selectCount(query1);
        vo.setTotalDeviceNum(i);
    }


}
