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

import com.ruoyi.common.core.domain.BaseValidator;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServiceUtil;
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.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.domain.enums.StoreStatus;
import com.ruoyi.ss.store.service.StoreService;
import com.ruoyi.ss.store.service.StoreValidator;
import com.ruoyi.ss.storeStaff.domain.enums.StoreStaffPermissions;
import com.ruoyi.ss.storeStaff.service.StoreStaffValidator;
import com.ruoyi.ss.user.service.UserValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 2024/4/27
 *
 * @author wjh
 */
@Service
public class StoreValidatorImpl extends BaseValidator implements StoreValidator {

    @Autowired
    private StoreService storeService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private UserValidator userValidator;

    @Autowired
    private StoreStaffValidator storeStaffValidator;

    /**
     * 逻辑删除前校验
     * @param ids 店铺id列表
     */
    @Override
    public ValidateResult preLogicDel(List<Long> ids) {
        if (CollectionUtils.isEmptyElement(ids)) {
            return error("id列表不能为空");
        }

        // 判断是否存在设备
        if (this.hasDevice(ids)) {
            return error("当前店铺存在设备，不能删除");
        }

        // 判断是否正在审核中
        if (this.hasApproving(ids)) {
            return error("当前有店铺正在审核中，请稍后重试");
        }

        return success();
    }

    /**
     * 前台逻辑删除前校验
     *
     * @param storeIds 店铺id列表
     */
    @Override
    public ValidateResult preLogicDelByApp(List<Long> storeIds) {
        // 基础校验
        ValidateResult result = this.preLogicDel(storeIds);
        if (result.isError()) {
            return result;
        }

        return success();
    }

    /**
     * 更新前校验
     *
     * @param data 数据
     */
    @Override
    public ValidateResult preUpdate(Store data) {
        if (data == null) {
            return error("数据不能为空");
        }

        // 判断营业时间是否符合条件
        ValidateResult validateBusinessTimeResult = this.validateBusinessTime(data.getBusinessTimeStart(), data.getBusinessTimeEnd());
        if (validateBusinessTimeResult.isError()) {
            return validateBusinessTimeResult;
        }

        if (!this.isExist(Collections.singletonList(data.getStoreId()))) {
            return error("店铺不存在");
        }

        if (data.getUserId() != null && !userValidator.isExist(Collections.singletonList(data.getUserId()))) {
            return error("用户不存在");
        }

        return success();
    }

    /**
     * 创建前校验
     *
     * @param data 数据
     */
    @Override
    public ValidateResult preCreate(Store data) {
        if (data == null) {
            return error("数据不能为空");
        }

        // 判断营业时间是否符合条件
        ValidateResult validateBusinessTimeResult = this.validateBusinessTime(data.getBusinessTimeStart(), data.getBusinessTimeEnd());
        if (validateBusinessTimeResult.isError()) {
            return validateBusinessTimeResult;
        }

        if (!userValidator.isExist(Collections.singletonList(data.getUserId()))) {
            return error("用户不存在");
        }

        return success();
    }

    /**
     * 前台创建前校验
     *
     * @param data 数据
     */
    @Override
    public ValidateResult preCreateByApp(Store data) {
        ValidateResult result = this.preCreate(data);
        if (result.isError()) {
            return result;
        }

        return success();
    }

    /**
     * 前台更新前校验
     *
     * @param data
     * @return
     */
    @Override
    public ValidateResult preUpdateByApp(Store data) {
        // 公共更新校验
        ValidateResult result = this.preUpdate(data);
        if (result.isError()) {
            return result;
        }

        StoreVo old = storeService.selectSmStoreById(data.getStoreId());
        if (old == null) {
            return error("待修改的店铺不存在");
        }

        // 判断店铺是否正在变更中
        if (this.isApproving(old)) {
            return error("当前店铺正在变更中，请稍后重试");
        }

        return success();
    }

    /**
     * 排序前校验
     * @param list 排序列表
     */
    @Override
    public ValidateResult preChangeSortByApp(List<Store> list) {
        if (CollectionUtils.isEmptyElement(list)) {
            return error("数据不能为空");
        }

        return success();
    }

    /**
     * 判断店铺是否存在设备
     * @param ids 店铺id列表
     */
    @Override
    public boolean hasDevice(List<Long> ids) {
        if (CollectionUtils.isEmptyElement(ids)) {
            return false;
        }
        DeviceQuery query = new DeviceQuery();
        query.setStoreIds(ids);
        return deviceService.selectCount(query) > 0;
    }

    /**
     * 判断店铺是否属于用户
     */
    @Override
    public boolean isMch(List<Long> storeIds, Long userId) {
        List<StoreVo> stores = storeService.selectStoreByIds(storeIds);
        for (StoreVo item : stores) {
            if (!this.isMch(item, userId)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断店铺是否属于用户
     *
     */
    @Override
    public boolean isMch(Store store, Long userId) {
        return store != null && store.getUserId() != null && store.getUserId().equals(userId);
    }


    /**
     * 判断店铺是否存在
     *
     * @param storeIds
     */
    @Override
    public boolean isExist(List<Long> storeIds) {
        if (CollectionUtils.isEmptyElement(storeIds)) {
            return true;
        }
        StoreQuery query = new StoreQuery();
        query.setStoreIds(storeIds);
        int count = storeService.selectCount(query);
        return count == new HashSet<Long>(storeIds).size();
    }

    /**
     * 设置默认店铺前校验
     *
     * @param userId
     * @param storeId
     */
    @Override
    public ValidateResult preSetDefaultByApp(Long userId, Long storeId) {
        if (userId == null || storeId == null) {
            return error("参数错误：userId 与 storeId 不允许为空");
        }

        return success();
    }

    /**
     * 是否正在变更中
     */
    @Override
    public boolean isApproving(Store store) {
        return store != null && StoreStatus.APPROVING.getStatus().equals(store.getStatus());
    }

    /**
     * 是否正在审核中
     *
     * @param ids
     */
    @Override
    public boolean hasApproving(List<Long> ids) {
        List<StoreVo> list = storeService.selectStoreByIds(ids);
        for (StoreVo store : list) {
            if (this.isApproving(store)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否营业时间
     * @param store
     * @param time
     * @return
     */
    @Override
    public boolean isBusinessTime(StoreVo store, LocalTime time) {
        if (store.getUseOutTime() == null || store.getUseOutTime()) {
            return true;
        }
        // 验证时间不为null
        LocalTime start = store.getBusinessTimeStart();
        LocalTime end = store.getBusinessTimeEnd();
        if (start == null || end == null) {
            return false;
        }
        // 正常时间
        if (end.isAfter(start)) {
            return time.isAfter(start) && time.isBefore(end);
        }
        // 隔天
        else {
            return time.isAfter(start) || time.isBefore(end);
        }
    }

    @Override
    public void afterCheck(StoreVo vo) {
        if (vo == null) {
            return;
        }

        ServiceUtil.assertion(this.validateBusinessTime(vo.getBusinessTimeStart(), vo.getBusinessTimeEnd()));

    }

    @Override
    public boolean canOperaStore(StoreVo store, Long userId) {
        if (store == null || userId == null) {
            return false;
        }
        return this.isMch(store, userId)
                || storeStaffValidator.hasStorePermission(store.getStoreId(), userId, StoreStaffPermissions.STORE_OPERA);
    }

    @Override
    public boolean canOperaStore(Long storeId, Long userId) {
        StoreVo store = storeService.selectSmStoreById(storeId);
        return this.canOperaStore(store, userId);
    }

    @Override
    public boolean canViewStore(Long storeId, Long userId) {
        StoreVo store = storeService.selectSmStoreById(storeId);
        return this.canViewStore(store, userId);
    }

    @Override
    public boolean canViewStore(StoreVo store, Long userId) {
        if (store == null || userId == null) {
            return false;
        }
        return isMch(store, userId)
                || storeStaffValidator.hasStorePermission(store.getStoreId(), userId, StoreStaffPermissions.STORE_VIEW);
    }

    @Override
    public boolean canOperaAllStore(List<Long> storeIds, Long userId) {
        if (CollectionUtils.isEmptyElement(storeIds)) {
            return true;
        }

        List<StoreVo> storeList = storeService.selectStoreByIds(storeIds);
        for (StoreVo store : storeList) {
            if (!this.canOperaStore(store, userId)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 校验时间是符合规则
     */
    private ValidateResult validateBusinessTime(LocalTime start, LocalTime end) {
        if (start != null || end != null) {
            // 不允许只传入一个值，要么都有，要么都没有
            if (start == null || end == null) {
                return error("不允许单独设置营业时间的起始或结束");
            }
            // 判断起始时间是否在结束时间前
//            if (start.isAfter(end)) {
//                return error("营业时间（起始）不允许晚于营业时间（结束）");
//            }
        }
        return success();
    }
}
