/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.distribution.comment.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponse;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.distribution.comment.dao.DistributionUserBindMapper;
import com.yami.shop.distribution.comment.dto.BindUserInfoDto;
import com.yami.shop.distribution.comment.model.DistributionBasicSet;
import com.yami.shop.distribution.comment.model.DistributionBindSet;
import com.yami.shop.distribution.comment.model.DistributionUser;
import com.yami.shop.distribution.comment.model.DistributionUserBind;
import com.yami.shop.distribution.comment.service.DistributionBasicSetService;
import com.yami.shop.distribution.comment.service.DistributionBindSetService;
import com.yami.shop.distribution.comment.service.DistributionBindUserService;
import com.yami.shop.distribution.comment.service.DistributionUserService;
import com.yami.shop.distribution.comment.vo.DistributionBindSceneVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

@Slf4j
@Service
@AllArgsConstructor
public class DistributionBindUserServiceImpl implements DistributionBindUserService {

    private final DistributionUserService distributionUserService;

    private final DistributionBindSetService distributionBindSetService;

    private final DistributionBasicSetService distributionBasicSetService;

    private final DistributionUserBindMapper distributionUserBindMapper;



    @Override
    public ServerResponse<DistributionUser> bindDistribution(DistributionUser shareUser, String userId, int type) {
        //分享员信息
        if (shareUser == null) {
            return ServerResponseEntity.fail("获取推广员信息失败");
        }
        if (shareUser.getState() != 1) {
            log.info("推广员状态异常");
            return ServerResponseEntity.fail("推广员状态异常");
        }
        Long shopId = shareUser.getShopId();
        DistributionBindSet distributionBindSet = distributionBindSetService.getByShopId();
        if (!verifyType(distributionBindSet, type)) {
            log.info("商户未开启该绑定用户方式,type:{}",type);
            return ServerResponseEntity.fail("商户未开启该绑定用户方式");
        }

        // 店铺基本设置
        DistributionBasicSet basicSet = distributionBasicSetService.getByShopId();

        // 没有开启分销员自购，也就是自己推广自己的东西没有收益
        if (Objects.equals(shareUser.getUserId(), userId) && !Objects.equals(basicSet.getOwnBuyAward(), 1)) {
            log.info("没有开启分销员自购，推广人不能自己哟");
            return ServerResponseEntity.fail("推广人不能自己哟");
        } else {
            // 看看自己是不是分销员，如果没有开启分销员互购，自己是分销员推广人也没有收益
            DistributionUser distributionUser = distributionUserService.getByUserIdAndShopId(userId, shopId);
            // 下单的用户以前申请过分销员，但现在又不是了，所以就将分销员信息置空
            if (distributionUser != null && !Objects.equals(distributionUser.getState(), 1)) {
                distributionUser = null;
            }

            // 没有开启互购
            if (!Objects.equals(basicSet.getParallelDeal(), 1) && distributionUser != null) {
                log.info("店铺没有开启互购，您已成为该店铺的推广员，无法被推广");
                return ServerResponseEntity.fail("您已成为该店铺的推广员，无法被推广");
            }
        }

        // 查询该用户以前绑定的分享人
        DistributionUserBind distributionUserBind = distributionUserBindMapper.selectOne(new LambdaQueryWrapper<DistributionUserBind>()
                .eq(DistributionUserBind::getShopId, Constant.PLATFORM_SHOP_ID)
                .eq(DistributionUserBind::getState, 1)
                .eq(DistributionUserBind::getUserId, userId)
        );

        // 没有绑定分享人，或分享人已被冻结，可以与该用户进行绑定
        if (distributionUserBind == null) {
            bindUser(userId, shareUser);
            return ServerResponseEntity.success(shareUser);
        }

        // 如果现在的分享人就是以前的分享人
        if (Objects.equals(distributionUserBind.getUserId(),shareUser.getUserId())) {
            // 如果绑定人相同 延长绑定时间
            updateBindTime(distributionUserBind.getBindId());
            return ServerResponseEntity.success(shareUser);
        }

        // 查询以前的绑定的用户信息
        DistributionUser oldDistributionUser = distributionUserService.getById(distributionUserBind.getDistributionUserId());

        // 永久保护，不处理
        if (distributionBindSet.getProtectDay() == -1) {
            log.info("永久保护，不处理，您还在推广期内，无法被新推广员推广");
            return ServerResponseEntity.fail(200, "您还在推广期内，无法被新推广员推广", oldDistributionUser);
        }

        //判断抢客方式是否有扫码抢客
        if (!distributionBindSet.getRob().getSweepCode() && type == 0) {
            //没有扫码抢客则不处理
            log.info("没有扫码抢客则不处理");
            return ServerResponseEntity.fail(200, "您还在推广期内，无法被新推广员推广", oldDistributionUser);
        }

        //判断抢客方式是否有下单抢客
        if (!distributionBindSet.getRob().getBuy() && type == 1) {
            //没有下单抢客则不处理
            log.info("没有下单抢客则不处理");
            return ServerResponseEntity.fail(200, "您还在推广期内，无法被新推广员推广", oldDistributionUser);
        }

        // 如果不在保护期内，可以将用户与新的推广员进行绑定
        if (DateUtil.offsetDay(distributionUserBind.getUpdateTime(), distributionBindSet.getProtectDay()).getTime() < System.currentTimeMillis()) {
            unBindUser(distributionUserBind.getBindId());
            bindUser(userId, shareUser);
            return ServerResponseEntity.success(shareUser);
        }
        log.info("用户在保护期内，绑定失败");
        return ServerResponseEntity.fail(200, "用户在保护期内，绑定失败", oldDistributionUser);
    }

    @Override
    public IPage<BindUserInfoDto> bindUserList(Page page, Long shopId, String userId) {
        return distributionUserBindMapper.bindUserList(page,shopId,userId);
    }

    private boolean verifyType(DistributionBindSet distributionBindSet, int type) {
        DistributionBindSceneVO bindScene = distributionBindSet.getBindScene();
        if (bindScene.getSweepCode() && type == 0) {
            return true;
        }
        if (bindScene.getBuy() && type == 1) {
            return true;
        }
        if (bindScene.getFollow() && type == 2) {
            return true;
        }
        return false;
    }

    private void bindUser(String userId, DistributionUser sharerUser) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindTime(new Date());
        distributionUserBind.setUserId(userId);
        distributionUserBind.setState(1);
        distributionUserBind.setShopId(sharerUser.getShopId());
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBind.setDistributionUserId(sharerUser.getDistributionUserId());
        distributionUserBindMapper.insert(distributionUserBind);
    }

    private void updateBindTime(Long bindId) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindId(bindId);
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBindMapper.updateById(distributionUserBind);
    }

    private void unBindUser(Long bindId) {
        DistributionUserBind distributionUserBind = new DistributionUserBind();
        distributionUserBind.setBindId(bindId);
        distributionUserBind.setUpdateTime(new Date());
        distributionUserBind.setInvalidReason(2);
        distributionUserBind.setState(-1);
        distributionUserBindMapper.updateById(distributionUserBind);
    }
}
