package co.yixiang.yshop.module.shop.service.shopassistant;

import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.service.user.UserService;
import co.yixiang.yshop.module.shop.controller.admin.shopassistant.vo.*;
import co.yixiang.yshop.module.shop.convert.shopassistant.ShopAssistantConvert;
import co.yixiang.yshop.module.shop.dal.dataobject.shop.ShopDO;
import co.yixiang.yshop.module.shop.dal.dataobject.shopassistant.ShopAssistantDO;
import co.yixiang.yshop.module.shop.dal.mysql.shopassistant.ShopAssistantMapper;
import co.yixiang.yshop.module.shop.service.shop.ShopService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static co.yixiang.yshop.module.shop.enums.ErrorCodeConstants.*;


/**
 * 门店店员 Service 实现类
 *
 * @author admin
 */
@Service
@Validated
public class ShopAssistantServiceImpl implements ShopAssistantService {

    @Resource
    private ShopAssistantMapper shopAssistantMapper;
    @Resource
    private ShopService shopService;
    @Resource
    private UserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createShopAssistant(ShopAssistantCreateReqVO createReqVO) {
        //校验参数是否合法
        verifyParam(createReqVO.getStoreId(), createReqVO.getUserId(), null);

        if (createReqVO.getStatus()) {
            userService.updateWriteOffAuthority(createReqVO.getUserId(), createReqVO.getStatus());
        }
        // 插入
        ShopAssistantDO shopAssistant = ShopAssistantConvert.INSTANCE.convert(createReqVO);
        shopAssistantMapper.insert(shopAssistant);
        // 返回
        return shopAssistant.getId();
    }

    /**
     * 校验参数
     *
     * @param storeId         /
     * @param userId          /
     * @param shopAssistantId 店员id 用于区分新增/更新时校验
     */
    private void verifyParam(Long storeId, Long userId, Long shopAssistantId) {
        //校验门店是否存在
        ShopDO shop = shopService.getShop(storeId);
        if (Objects.isNull(shop)) {
            throw exception(SHOP_NOT_EXISTS);
        }
        //查询用户
        MemberUserDO user = userService.getUser(userId);
        if (Objects.isNull(user)) {
            throw exception(USER_NOT_EXISTS);
        }
        //校验当前用户是否是店员
        ShopAssistantDO shopAssistantDO = this.selectByUserId(userId);
        if (Objects.nonNull(shopAssistantDO)) {
            //更新时校验
            if (Objects.nonNull(shopAssistantId)) {
                if (!shopAssistantDO.getId().equals(shopAssistantId)) {
                    throw exception(SHOP_ASSISTANT_EXIST);
                }
            } else {
                throw exception(SHOP_ASSISTANT_EXIST);
            }

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateShopAssistant(ShopAssistantUpdateReqVO updateReqVO) {
        // 校验存在
        validateShopAssistantExists(updateReqVO.getId());
        //校验参数是否合法
        verifyParam(updateReqVO.getStoreId(), updateReqVO.getUserId(), updateReqVO.getId());
        // 更新
        ShopAssistantDO updateObj = ShopAssistantConvert.INSTANCE.convert(updateReqVO);
        shopAssistantMapper.updateById(updateObj);
        //更新用户核销状态
        userService.updateWriteOffAuthority(updateReqVO.getUserId(), updateReqVO.getStatus());
    }

    @Override
    public void deleteShopAssistant(Long id) {
        // 校验存在
        validateShopAssistantExists(id);
        // 删除
        shopAssistantMapper.deleteById(id);
    }

    private void validateShopAssistantExists(Long id) {
        if (shopAssistantMapper.selectById(id) == null) {
            throw exception(SHOP_ASSISTANT_NOT_EXISTS);
        }
    }

    @Override
    public ShopAssistantDO getShopAssistant(Long id) {
        return shopAssistantMapper.selectById(id);
    }

    @Override
    public List<ShopAssistantDO> getShopAssistantList(Collection<Long> ids) {
        return shopAssistantMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ShopAssistantRespVO> getShopAssistantPage(ShopAssistantPageReqVO pageReqVO) {
        PageResult<ShopAssistantDO> page = shopAssistantMapper.selectPage(pageReqVO);
        PageResult<ShopAssistantRespVO> resPage = ShopAssistantConvert.INSTANCE.convertPage(page);
        //填充数据
        fillData(resPage);
        return resPage;
    }

    private void fillData(PageResult<ShopAssistantRespVO> resPage) {
        List<Long> userIds = resPage.getList().stream().map(ShopAssistantRespVO::getUserId).distinct().collect(Collectors.toList());
        List<Long> storeIds = resPage.getList().stream().map(ShopAssistantRespVO::getStoreId).distinct().collect(Collectors.toList());
        Map<Long, MemberUserDO> userMap = userService.getUserList(userIds).stream().collect(Collectors.toMap(MemberUserDO::getId, Function.identity()));
        Map<Long, ShopDO> storeMap = shopService.getShopList(storeIds).stream().collect(Collectors.toMap(ShopDO::getId, Function.identity()));

        resPage.getList().forEach(item -> {
            MemberUserDO user = userMap.getOrDefault(item.getUserId(), new MemberUserDO());
            ShopDO shop = storeMap.getOrDefault(item.getStoreId(), new ShopDO());
            item.setAvatar(user.getAvatar());
            item.setNickname(user.getNickname());
            item.setStoreName(shop.getStoreName());
        });
    }

    @Override
    public List<ShopAssistantDO> getShopAssistantList(ShopAssistantExportReqVO exportReqVO) {
        return shopAssistantMapper.selectList(exportReqVO);
    }


    @Override
    public ShopAssistantDO selectByUserId(Long userId) {
        return shopAssistantMapper.selectOne(ShopAssistantDO::getUserId, userId);
    }

}
