package shop.alien.store.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import shop.alien.entity.store.LifeFans;
import shop.alien.entity.store.LifeNotice;
import shop.alien.entity.store.LifeUser;
import shop.alien.entity.store.vo.LifeMessageVo;
import shop.alien.entity.store.vo.LifeUserVo;
import shop.alien.store.config.BaseRedisService;
import shop.alien.mapper.LifeFansMapper;
import shop.alien.mapper.LifeMessageMapper;
import shop.alien.mapper.LifeNoticeMapper;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.store.util.FunctionMagic;
import shop.alien.util.common.JwtUtil;

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

/**
 * 用户
 */
@Service
@RequiredArgsConstructor
public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {

    private final LifeUserMapper lifeUserMapper;

    private final LifeFansMapper lifeFansMapper;

    private final BaseRedisService baseRedisService;

    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeMessageMapper messageMapper;

    @Value("${jwt.expiration-time}")
    private String effectiveTime;

    public IPage<LifeUser> getStoresPage(int page, int size, String realName, String userPhone) {
        IPage<LifeUser> storePage = new Page<>(page, size);
        QueryWrapper<LifeUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!realName.isEmpty(), "real_name", realName);
        queryWrapper.like(!userPhone.isEmpty(), "user_phone", userPhone);
        queryWrapper.orderByDesc("created_time");
        return lifeUserMapper.selectPage(storePage, queryWrapper);
    }

    public int modifyUser(LifeUser user) {
        return lifeUserMapper.updateById(user);
    }

    public int addOrUpdateUser(LifeUser user) {
        user.setCreatedTime(new Date());
        return lifeUserMapper.insert(user);
    }

    public LifeUser getUserById(String id) {
        return lifeUserMapper.selectById(id);
    }

    public int addFans(LifeFans fans) {
        fans.setCreatedTime(new Date());
        int num = lifeFansMapper.insert(fans);

        if (num == 1) {
            LifeNotice notice = new LifeNotice();
            notice.setTitle("关注通知");
            notice.setContext("关注了你");
            notice.setNoticeType(0);
            notice.setReceiverId(fans.getFollowedId());
            notice.setSenderId(fans.getFansId());

            // 根据手机号查询发送人信息
            String storePhones = "''";
            String userPhones = "''";
            if (fans.getFansId().split("_")[0].equals("store")) {
                storePhones = "'" + fans.getFansId().split("_")[1] + "'";
            } else {
                userPhones = "'" + fans.getFansId().split("_")[1] + "'";
            }
            List<LifeMessageVo> userList = messageMapper.getLifeUserAndStoreUserByPhone(storePhones, userPhones);
            if (!CollectionUtils.isEmpty(userList)) {
                notice.setBusinessId(userList.get(0).getId());
            }
            lifeNoticeMapper.insert(notice);
        }

        return num;
    }

    public int cancelFans(LifeFans fans) {
        LambdaUpdateWrapper<LifeFans> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(LifeFans::getFansId, fans.getFansId());
        wrapper.eq(LifeFans::getFollowedId, fans.getFollowedId());
        return lifeFansMapper.delete(wrapper);
    }

    public IPage<LifeUserVo> getStoreAndUserByName(LifeUserVo vo) {
        QueryWrapper<LifeUserVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(vo.getSearchName()), "a.storeUserName", vo.getSearchName());
        IPage<LifeUserVo> voList = lifeUserMapper.getStoreAndUserByName(new Page<>(vo.getPage(), vo.getSize()), queryWrapper);

        // 查询我的关注
        LambdaQueryWrapper<LifeFans> lifeFansWrapper = new LambdaQueryWrapper<>();
        lifeFansWrapper.eq(LifeFans::getFansId, vo.getPhoneId());
        List<LifeFans> lifeFansList = lifeFansMapper.selectList(lifeFansWrapper);
        List<String> followList = lifeFansList.stream().map(LifeFans::getFollowedId).collect(Collectors.toList());

        voList.getRecords().forEach(item -> {
            if (followList.contains(item.getPhoneId())) {
                item.setIsFollowThis("1");
            } else {
                item.setIsFollowThis("0");
            }
        });
        return voList;
    }

    public LifeUserVo userLogin(String phoneNum) {
        LifeUser user = getUserByPhone(phoneNum);
        if (user == null) {
            LifeUser lifeUser = new LifeUser();
            lifeUser.setUserPhone(phoneNum);
            lifeUser.setUserName(phoneNum);
            lifeUser.setRealName(phoneNum);
            lifeUser.setCreatedTime(new Date());
            int ret = lifeUserMapper.insert(lifeUser);
            if (ret == 1) {
                LifeUser user2 = getUserByPhone(phoneNum);
                LifeUserVo userVo = new LifeUserVo();
                BeanUtils.copyProperties(user2, userVo);
                Map<String, String> tokenMap = new HashMap<>();
                tokenMap.put("phone", phoneNum);
                tokenMap.put("userName", lifeUser.getUserName());
                tokenMap.put("userId", lifeUser.getId().toString());
                tokenMap.put("userType", "user");
//                userVo.setToken(JWTUtils1.createToken(tokenMap));
                baseRedisService.setString("user_" + phoneNum, userVo.getToken());
                return userVo;
            } else {
                return null;
            }
        } else {
            LifeUserVo userVo = new LifeUserVo();
            BeanUtils.copyProperties(user, userVo);
            Map<String, String> tokenMap = new HashMap<>();
            tokenMap.put("phone", phoneNum);
            tokenMap.put("userName", user.getUserName());
            tokenMap.put("userId", user.getId().toString());
            tokenMap.put("userType", "user");
            int effectiveTimeInt = Integer.parseInt(effectiveTime.substring(0, effectiveTime.length() - 1));
            String effectiveTimeUnit = effectiveTime.substring(effectiveTime.length() - 1);
            long effectiveTimeIntLong = 0L;
            switch (effectiveTimeUnit) {
                case "s": {
                    effectiveTimeIntLong = effectiveTimeInt * 1000L;
                    break;
                }
                case "m": {
                    effectiveTimeIntLong = effectiveTimeInt * 60L * 1000L;
                    break;
                }
                case "h": {
                    effectiveTimeIntLong = effectiveTimeInt * 60L * 60L * 1000L;
                    break;
                }
                case "d": {
                    effectiveTimeIntLong = effectiveTimeInt * 24L * 60L * 60L * 1000L;
                    break;
                }
            }
            String token = JwtUtil.createJWT("user_" + phoneNum, user.getUserName(), JSONObject.toJSONString(tokenMap), effectiveTimeIntLong);
            userVo.setToken(token);
            baseRedisService.setString("user_" + phoneNum, token);
            return userVo;
        }
    }

    public LifeUser getUserByPhone(String phoneNum) {
        LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LifeUser::getUserPhone, phoneNum);
        return this.getOne(lambdaQueryWrapper);
    }

    public void liftCancelAccount(LifeUser user) {
        // 通过id获取当前用户账号信息
        LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LifeUser::getId, user.getId());
        LifeUser lifeUser = lifeUserMapper.selectOne(lambdaQueryWrapper);
        // 修改注销标记为1
        lifeUser.setLogoutFlag(1);
        // 添加注销原因
        lifeUser.setLogoutReason(user.getLogoutReason());
        // 添加注销申请时间
        lifeUser.setLogoutTime(new Date());
        lifeUserMapper.updateById(lifeUser);
    }

    public void liftCancelAccountUn(Integer id) {
        LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LifeUser::getId, id);
        LifeUser lifeUser = lifeUserMapper.selectOne(lambdaQueryWrapper);
        // 修改注销标记为0
        lifeUser.setLogoutFlag(0);
        // 清空注销原因
        lifeUser.setLogoutReason(null);
        // 清空注销申请时间
        lifeUser.setLogoutTime(null);
        lifeUserMapper.updateById(lifeUser);
    }

    public List<String> getIds(String name, String phone) {
        if (Objects.isNull(name) && Objects.isNull(phone)) return Arrays.asList("");
        LambdaQueryWrapper<LifeUser> wrapper = new LambdaQueryWrapper<>();
        List<Triple<Boolean, SFunction<LifeUser, ?>, Object>> conditions = new ArrayList<>();
        conditions.add(Triple.of(StringUtils.isNotEmpty(name), LifeUser::getUserName, name));
        conditions.add(Triple.of(StringUtils.isNotEmpty(phone), LifeUser::getUserPhone, phone));
        FunctionMagic.buildLikeConditions(wrapper, conditions);
        List<String> res = FunctionMagic.convertToIds(lifeUserMapper.selectList(wrapper), LifeUser::getId);
        return CollectionUtils.isEmpty(res) ? Arrays.asList("") : res;
    }
}
