package com.cool.store.service.store.impl;

import com.cool.store.dao.config.ConfigOptionDAO;
import com.cool.store.dao.store.StoreTypeDAO;
import com.cool.store.dao.store.StoreTypeOptionDAO;
import com.cool.store.entity.config.ConfigOptionDO;
import com.cool.store.entity.store.StoreTypeDO;
import com.cool.store.entity.store.StoreTypeOptionDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.store.StoreTypeOptionSaveRequest;
import com.cool.store.request.store.StoreTypeQueryRequest;
import com.cool.store.request.store.StoreTypeUpdateRequest;
import com.cool.store.service.store.StoreTypeService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.store.StoreTypeOptionVO;
import com.cool.store.vo.store.StoreTypeVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 店型 Service impl
 */
@Service
@RequiredArgsConstructor
public class StoreTypeServiceImpl implements StoreTypeService {

    private final StoreTypeDAO storeTypeDAO;
    private final StoreTypeOptionDAO storeTypeOptionDAO;
    private final ConfigOptionDAO configOptionDAO;

    @Override
    public Boolean add(StoreTypeUpdateRequest request) {
        if (request.getSortOrder() != null && storeTypeDAO.existsSortOrder(request.getSortOrder(), null)) {
            throw new ServiceException(ErrorCodeEnum.CURRENT_BRAND_SORT_NUMBER_EXIST);
        }
        if (request.getId()!=null){
            throw new ServiceException(ErrorCodeEnum.CURRENT_STORE_TYPE_EXIST);
        }
        StoreTypeDO entity = BeanUtil.toBean(request, StoreTypeDO.class);
        entity.setStoreTypeCode(UUIDUtils.get8UUID());
        entity.setDeleted(false);
        return storeTypeDAO.insertSelective(entity);
    }

    @Override
    public Boolean update(StoreTypeUpdateRequest request) {
        if (request.getSortOrder() != null && storeTypeDAO.existsSortOrder(request.getSortOrder(), request.getId())) {
            throw new ServiceException(ErrorCodeEnum.CURRENT_BRAND_SORT_NUMBER_EXIST);
        }
        if (request.getId()==null){
            throw new ServiceException(ErrorCodeEnum.CURRENT_STORE_TYPE_NOT_EXIST);
        }
        StoreTypeDO entity = BeanUtil.toBean(request, StoreTypeDO.class);
        return storeTypeDAO.updateSelective(entity);
    }

    @Override
    public PageInfo<StoreTypeVO> queryPage(StoreTypeQueryRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<StoreTypeDO> list = storeTypeDAO.queryByCondition(request.getKeyword(), request.getActive(), request.getBrand());
        return BeanUtil.toPage(new PageInfo<>(list), StoreTypeVO.class);
    }

    @Override
    public Boolean deleteByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        //目前没有批量
        for (Long id : ids) {
            StoreTypeDO storeType = storeTypeDAO.getById(id);
            if (storeType == null) {
                continue;
            }
            if (Boolean.TRUE.equals(storeType.getActive())) {
                throw new ServiceException(ErrorCodeEnum.STORE_TYPE_MUST_DISABLE_BEFORE_DELETE);
            }
        }
        //将配置改为不可以状态
        storeTypeOptionDAO.softDeleteByStoreTypeId(ids);
        return storeTypeDAO.softDeleteByIds(ids);
    }

    @Override
    public Boolean changeActive(Long id, Boolean active) {
        if (id == null || active == null) {
            return false;
        }
        StoreTypeDO storeType = storeTypeDAO.getById(id);
        if (storeType == null) {
            return false;
        }
        return storeTypeDAO.updateActiveById(id, active);
    }

    @Override
    public Boolean saveStoreTypeOptions(StoreTypeOptionSaveRequest request) {
        if (request == null || request.getStoreTypeId() == null) {
            return false;
        }

        if (CollectionUtils.isEmpty(request.getOptions())) {
            // 没有传配置项，清空即可
            storeTypeOptionDAO.deleteByStoreTypeId(request.getStoreTypeId());
            return true;
        }

        // 校验：相同 itemCode 下只能有一个默认
//        Map<String, Integer> defaultCountMap = new HashMap<>();
//        for (StoreTypeOptionSaveRequest.StoreTypeOptionItemRequest item : request.getOptions()) {
//            if (item == null || item.getItemCode() == null||item.getCategoryCode()==null) {
//                continue;
//            }
//            if (item.getIsDefault() != null && item.getIsDefault() == 1) {
//                String key = item.getCategoryCode() + item.getItemCode();
//                defaultCountMap.merge(key, 1, Integer::sum);
//            }
//        }
//        for (Map.Entry<String, Integer> e : defaultCountMap.entrySet()) {
//            if (e.getValue() != null && e.getValue() > 1) {
//                throw new ServiceException(ErrorCodeEnum.STORE_TYPE_OPTION_DEFAULT_DUPLICATE);
//            }
//        }

        // 先删除旧绑定
        storeTypeOptionDAO.deleteByStoreTypeId(request.getStoreTypeId());

        Date now = new Date();
        List<StoreTypeOptionDO> list = new ArrayList<>(request.getOptions().size());

        List<Long> optionIds = request.getOptions().stream()
                .filter(Objects::nonNull)
                .map(StoreTypeOptionSaveRequest.StoreTypeOptionItemRequest::getOptionId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, ConfigOptionDO> configOptionMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(optionIds)) {
            List<ConfigOptionDO> optionList = configOptionDAO.listActiveByIds(optionIds);
            configOptionMap = optionList.stream().collect(Collectors.toMap(ConfigOptionDO::getId, Function.identity(), (a, b) -> a));
        }

        for (StoreTypeOptionSaveRequest.StoreTypeOptionItemRequest item : request.getOptions()) {
            ConfigOptionDO configOption = configOptionMap.get(item.getOptionId());
            StoreTypeOptionDO entity = StoreTypeOptionDO.builder()
                    .storeTypeId(request.getStoreTypeId())
                    .optionId(item.getOptionId())
                    .categoryCode(item.getCategoryCode())
                    .itemCode(item.getItemCode())
                    .isDefault(item.getIsDefault())
                    .defaultQuantity(item.getDefaultQuantity())
                    .allowQuantityEdit(item.getAllowQuantityEdit())
                    .sortOrder(item.getSortOrder())
                    .optionPrice(item.getOptionPrice()==null?configOption.getOptionPrice():item.getOptionPrice())
                    .topPreviewImage(item.getTopPreviewImage())
                    .createTime(now)
                    .updateTime(now)
                    .build();
            list.add(entity);
        }
        return storeTypeOptionDAO.insertBatchSelective(list);
    }

    @Override
    public List<StoreTypeOptionVO> listStoreTypeOptions(Long storeTypeId) {
        if (storeTypeId == null) {
            return new ArrayList<>();
        }

        List<StoreTypeOptionDO> list = storeTypeOptionDAO.listByStoreTypeId(storeTypeId);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }

        List<Long> optionIds = list.stream()
                .map(StoreTypeOptionDO::getOptionId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Long, ConfigOptionDO> optionMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(optionIds)) {
            List<ConfigOptionDO> options = configOptionDAO.listActiveByIds(optionIds);
            optionMap = options.stream()
                    .collect(Collectors.toMap(ConfigOptionDO::getId, Function.identity(), (a, b) -> a));
        }

        List<StoreTypeOptionVO> vos = BeanUtil.toList(list, StoreTypeOptionVO.class);
        for (StoreTypeOptionVO vo : vos) {
            if (vo == null || vo.getOptionId() == null) {
                continue;
            }
            ConfigOptionDO opt = optionMap.get(vo.getOptionId());
            if (opt == null) {
                continue;
            }
            vo.setOptionImageUrl(opt.getImageUrl());
            vo.setOptionPrice(vo.getOptionPrice());
            vo.setOriginalOptionPrice(opt.getOriginalOptionPrice());
            vo.setOptionRemark(opt.getOptionRemark());
            vo.setOptionName(opt.getOptionName());
            vo.setOptionDescription(opt.getOptionDescription());
            vo.setOptionUnit(opt.getOptionUnit());
        }
        return vos;
    }

    @Override
    public List<StoreTypeVO> listActiveByStoreType(Integer storeType) {
        if (storeType == null) {
            return new ArrayList<>();
        }
        List<StoreTypeDO> list = storeTypeDAO.listActiveByStoreType(storeType);
        return BeanUtil.toList(list, StoreTypeVO.class);
    }
}
