package com.slodon.b2b2c.model.video;

import com.slodon.b2b2c.core.constant.VideoConst;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.dao.read.video.AuthorFollowReadMapper;
import com.slodon.b2b2c.dao.read.video.AuthorReadMapper;
import com.slodon.b2b2c.dao.write.video.AuthorFollowWriteMapper;
import com.slodon.b2b2c.dao.write.video.AuthorWriteMapper;
import com.slodon.b2b2c.video.example.AuthorExample;
import com.slodon.b2b2c.video.example.AuthorFollowExample;
import com.slodon.b2b2c.video.pojo.Author;
import com.slodon.b2b2c.video.pojo.AuthorFollow;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * 作者表model
 */
@Component
@Slf4j
public class AuthorModel {

    @Resource
    private AuthorReadMapper authorReadMapper;
    @Resource
    private AuthorWriteMapper authorWriteMapper;
    @Resource
    private AuthorFollowReadMapper authorFollowReadMapper;
    @Resource
    private AuthorFollowWriteMapper authorFollowWriteMapper;

    /**
     * 新增作者表
     *
     * @param author
     * @return
     */
    public Author saveAuthor(Author author) {
        int count = authorWriteMapper.insert(author);
        if (count == 0) {
            throw new MallException("添加作者表失败，请重试");
        }
        return author;
    }

    /**
     * 根据authorId删除作者表
     *
     * @param authorId authorId
     * @return
     */
    public Integer deleteAuthor(Integer authorId) {
        if (StringUtils.isEmpty(authorId)) {
            throw new MallException("请选择要删除的数据");
        }
        int count = authorWriteMapper.deleteByPrimaryKey(authorId);
        if (count == 0) {
            log.error("根据authorId：" + authorId + "删除作者表失败");
            throw new MallException("删除作者表失败,请重试");
        }
        return count;
    }

    /**
     * 根据authorId更新作者表
     *
     * @param author
     * @return
     */
    public Integer updateAuthor(Author author) {
        if (StringUtils.isEmpty(author.getAuthorId())) {
            throw new MallException("请选择要修改的数据");
        }
        int count = authorWriteMapper.updateByPrimaryKeySelective(author);
        if (count == 0) {
            log.error("根据authorId：" + author.getAuthorId() + "更新作者表失败");
            throw new MallException("更新作者表失败,请重试");
        }
        return count;
    }

    /**
     * 根据条件更新作者表
     *
     * @param author
     * @param example
     * @return
     */
    public Integer updateAuthorByExample(Author author, AuthorExample example) {
        return authorWriteMapper.updateByExampleSelective(author, example);
    }

    /**
     * 根据authorId获取作者表详情
     *
     * @param authorId authorId
     * @return
     */
    public Author getAuthorByAuthorId(Integer authorId) {
        return authorReadMapper.getByPrimaryKey(authorId);
    }

    /**
     * 根据memberId获取作者表详情
     *
     * @param memberId memberId
     * @return
     */
    public Author getAuthorByMemberId(Integer memberId) {
        AuthorExample example = new AuthorExample();
        example.setMemberId(memberId);
        List<Author> list = authorReadMapper.listByExample(example);
        AssertUtil.notEmpty(list, "作者信息不存在");
        return list.get(0);
    }

    /**
     * 根据vendorId获取作者表详情
     *
     * @param vendorId vendorId
     * @return
     */
    public Author getAuthorByVendorId(Long vendorId) {
        AuthorExample example = new AuthorExample();
        example.setVendorId(vendorId);
        List<Author> list = authorReadMapper.listByExample(example);
        AssertUtil.notEmpty(list, "作者信息不存在");
        return list.get(0);
    }

    /**
     * 根据条件获取作者表列表
     *
     * @param example 查询条件信息
     * @param pager   分页信息
     * @return
     */
    public List<Author> getAuthorList(AuthorExample example, PagerInfo pager) {
        List<Author> authorList;
        if (pager != null) {
            pager.setRowsCount(authorReadMapper.countByExample(example));
            authorList = authorReadMapper.listPageByExample(example, pager.getStart(), pager.getPageSize());
        } else {
            authorList = authorReadMapper.listByExample(example);
        }
        return authorList;
    }

    /**
     * 关注作者
     *
     * @param authorId
     * @param author
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String followAuthor(Integer authorId, Author author) {
        //判断是否关注过作者
        AuthorFollowExample example = new AuthorFollowExample();
        example.setQueryIsFollow("notNull");
        example.setFromAuthorId(author.getAuthorId());
        example.setToAuthorId(authorId);
        List<AuthorFollow> list = authorFollowReadMapper.listByExample(example);
        AuthorFollow follow = new AuthorFollow();
        Integer count = 0;
        // 如果查询结果是空，则新增加一条数据
        if (CollectionUtils.isEmpty(list)) {
            follow.setFromAuthorId(author.getAuthorId());
            follow.setToAuthorId(authorId);
            follow.setType(VideoConst.FOLLOW_TYPE_1);
            //1、保存信息
            count = authorFollowWriteMapper.insert(follow);
        } else {
            follow.setFollowId(list.get(0).getFollowId());
            follow.setType(VideoConst.FOLLOW_TYPE_3);
            //1、更新信息
            count = authorFollowWriteMapper.updateByPrimaryKeySelective(follow);
        }
        AssertUtil.isTrue(count == 0, "关注作者失败，请重试！");

        //更新关注数
        Author authorFollow = new Author();
        authorFollow.setAuthorId(author.getAuthorId());
        authorFollow.setFollowNum(author.getFollowNum() + 1);
        authorFollow.setUpdateTime(new Date());
        count = authorWriteMapper.updateByPrimaryKeySelective(authorFollow);
        AssertUtil.isTrue(count == 0, "更新关注数失败，请重试！");
        //更新粉丝数
        Author ortherAuthor = authorReadMapper.getByPrimaryKey(authorId);
        AssertUtil.notNull(ortherAuthor, "查询的作者信息为空");
        Author authorFans = new Author();
        authorFans.setAuthorId(authorId);
        authorFans.setFansNum(ortherAuthor.getFansNum() + 1);
        authorFans.setUpdateTime(new Date());
        count = authorWriteMapper.updateByPrimaryKeySelective(authorFans);
        AssertUtil.isTrue(count == 0, "更新粉丝数失败，请重试！");
        return authorFans.getFansNum() < 10000 ? authorFans.getFansNum().toString()
                : new BigDecimal(authorFans.getFansNum()).divide(new BigDecimal(10000), 1, RoundingMode.FLOOR) + "w";
    }

    /**
     * 取消关注
     *
     * @param authorId
     * @param author
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String cancelFollow(Integer authorId, Author author) {
        //判断是否关注过作者
        AuthorFollowExample example = new AuthorFollowExample();
        example.setQueryAuthorId("notNull");
        example.setFromAuthorId(author.getAuthorId());
        example.setToAuthorId(authorId);
        List<AuthorFollow> list = authorFollowReadMapper.listByExample(example);
        AssertUtil.notEmpty(list, "获取关注信息为空");
        AuthorFollow follow = list.get(0);
        AuthorFollow followNew = new AuthorFollow();
        Integer count = 0;
        // 如果是互相关注，修改关注类型
        if (follow.getType() == VideoConst.FOLLOW_TYPE_3) {
            followNew.setFollowId(follow.getFollowId());
            if (follow.getFromAuthorId().equals(author.getAuthorId())) {
                followNew.setType(VideoConst.FOLLOW_TYPE_2);
                count = authorFollowWriteMapper.updateByPrimaryKeySelective(followNew);
            } else {
                followNew.setType(VideoConst.FOLLOW_TYPE_1);
                count = authorFollowWriteMapper.updateByPrimaryKeySelective(followNew);
            }
        } else {
            count = authorFollowWriteMapper.deleteByPrimaryKey(follow.getFollowId());
        }
        AssertUtil.isTrue(count == 0, "取消关注失败，请重试！");

        //更新关注数
        Author authorFollow = new Author();
        authorFollow.setAuthorId(author.getAuthorId());
        authorFollow.setFollowNum(Integer.max(author.getFollowNum() - 1, 0));
        authorFollow.setUpdateTime(new Date());
        count = authorWriteMapper.updateByPrimaryKeySelective(authorFollow);
        AssertUtil.isTrue(count == 0, "更新关注数失败，请重试！");
        //更新粉丝数
        Author ortherAuthor = authorReadMapper.getByPrimaryKey(authorId);
        AssertUtil.notNull(ortherAuthor, "查询的作者信息为空");
        Author authorFans = new Author();
        authorFans.setAuthorId(authorId);
        authorFans.setFansNum(Integer.max(ortherAuthor.getFansNum() - 1, 0));
        authorFans.setUpdateTime(new Date());
        count = authorWriteMapper.updateByPrimaryKeySelective(authorFans);
        AssertUtil.isTrue(count == 0, "更新粉丝数失败，请重试！");
        return authorFans.getFansNum() < 10000 ? authorFans.getFansNum().toString()
                : new BigDecimal(authorFans.getFansNum()).divide(new BigDecimal(10000), 1, RoundingMode.FLOOR) + "w";
    }

    /**
     * 关注会员
     *
     * @param memberId
     * @param vendorId
     * @return
     */
    public Integer followMember(Integer memberId, Long vendorId) {
        //查询当前主播信息
        Author author = this.getAuthorByVendorId(vendorId);
        //更新当前登录会员关注数
        Author authorNew = new Author();
        authorNew.setAuthorId(author.getAuthorId());
        authorNew.setFollowNum(author.getFollowNum() + 1);
        int count = authorWriteMapper.updateByPrimaryKeySelective(authorNew);
        AssertUtil.isTrue(count == 0, "更新当前登录主播关注数失败，请重试！");

        //查询关注会员信息
        Author liveAuthor = this.getAuthorByMemberId(memberId);
        AssertUtil.notNull(liveAuthor, "获取关注会员信息为空，请重试！");

        //更新关注会员粉丝数
        Author liveAuthorNew = new Author();
        liveAuthorNew.setAuthorId(liveAuthor.getAuthorId());
        liveAuthorNew.setFansNum(liveAuthor.getFansNum() + 1);
        count = authorWriteMapper.updateByPrimaryKeySelective(liveAuthorNew);
        AssertUtil.isTrue(count == 0, "更新关注会员粉丝数失败，请重试！");
        return count;
    }
}