package com.wzj.soopin.member.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.member.convert.MemberConvert;
import com.wzj.soopin.member.domain.bo.MemberBO;
import com.wzj.soopin.member.domain.form.ChangeMemberStatusForm;
import com.wzj.soopin.member.domain.po.Fans;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.po.MemberAccount;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.mapper.MemberAccountMapper;
import com.wzj.soopin.member.mapper.MemberCartMapper;
import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.member.service.IFansService;
import com.wzj.soopin.member.service.IMemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.constant.CachePrefix;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.constant.ResultCode;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.YesOrNo;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.redis.redis.RedisCache;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 会员信息Service业务层处理
 *
 *
 * @author zcc
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class MemberServiceImpl extends ServiceImpl<MemberMapper,Member> implements IMemberService {

    private final MemberCartMapper memberCartMapper;

    private final RedisCache redisCache;

    private final MemberAccountMapper memberAccountMapper;

    private final MemberConvert memberConvert;

    private final MemberMapper memberMapper;
    private final IFansService fansService;

    @Override
    public boolean usernameExists(String username) {
        return baseMapper.countByUsername(username) > 0; // 确保实现
    }


    @Override
    public boolean save(Member entity) {
        super.save(entity);

        MemberAccount account=MemberAccount.builder().memberId(entity.getId()).build();
        memberAccountMapper.insert(account);

        return  true;
    }

    @Override
    public Member findByUsername(String userName) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userName);
        return this.baseMapper.selectOne(queryWrapper);
    }
    @Override
    @Cacheable(value = GlobalConstants.MEMBER_KEY, key = "#mobile")
    public Member findByMobile( String mobile) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobile);
        return this.baseMapper.selectOne(queryWrapper);
    }

    @CacheEvict(value = GlobalConstants.MEMBER_KEY, key = "#id")
    public int updateMark(MemberBO member) {
        UpdateWrapper<Member> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("mark",member.getMark())
                .set("update_time",LocalDateTime.now())
                .eq("id",member.getId());
        return baseMapper.update(null,updateWrapper);
    }



    @CacheEvict(value = GlobalConstants.MEMBER_KEY, key = "#id")
    public Integer changeStatus(MemberBO bo) {
        UpdateWrapper<Member> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", bo.getId());
        wrapper.set("status", bo.getStatus());
        return baseMapper.update(null, wrapper);
    }



    @Override
    public Member modifyPass(String oldPassword, String newPassword) {
        LoginUser tokenUser = LoginHelper.getLoginUser();
        if (tokenUser == null) {
            throw new ServiceException(ResultCode.USER_NOT_LOGIN);
        }
        Member member = this.getById(tokenUser.getUserId());
        // 判断旧密码输入是否正确
        if (!BCrypt.checkpw(member.getPassword(),oldPassword)) {
            throw new ServiceException(ResultCode.USER_OLD_PASSWORD_ERROR);
        }
        // 修改会员密码
        LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        lambdaUpdateWrapper.eq(Member::getId, member.getId());
        lambdaUpdateWrapper.set(Member::getPassword, BCrypt.hashpw(newPassword));
        this.update(lambdaUpdateWrapper);
        return member;
    }

    @Override
    public boolean changeMobile(String mobile) {
        LoginUser tokenUser = LoginHelper.getLoginUser();
        Member member = this.getById(tokenUser.getUserId());

        // 修改会员手机号
        LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        lambdaUpdateWrapper.eq(Member::getId, member.getId());
        lambdaUpdateWrapper.set(Member::getPhoneEncrypted, mobile);
        return this.update(lambdaUpdateWrapper);
    }
    /**
     * 更新会员状态
     * 支持设置封禁时长
     *
     * @param memberIds 会员ID列表
     * @param disabled  是否禁用
     * @param banDays   封禁天数，null表示永久封禁
     * @return 操作结果代码
     */
    @Override
    public ResultCode updateMemberStatus(List<String> memberIds, Boolean disabled, Integer banDays) {
        if (memberIds == null || memberIds.isEmpty()) {
            return ResultCode.USER_NOT_EXIST;
        }

        try {
            UpdateWrapper<Member> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("id", memberIds);

            if (Boolean.TRUE.equals(disabled)) {
                // 计算解封时间
                Date banEndTime = null;
                if (banDays != null && banDays > 0) {
                    // 使用 Calendar 设置解封日期
                    Calendar calendar = Calendar.getInstance();
                    calendar.add(Calendar.DAY_OF_MONTH, banDays);
                    banEndTime = calendar.getTime();
                }
                // 设置封禁状态和解封时间
                updateWrapper.set("delete_flag", true);
                updateWrapper.set("ban_end_time", banEndTime);

                // 记录操作日志
                log.info("封禁会员: memberIds={}, banDays={}, banEndTime={}",
                    memberIds, banDays, banEndTime);
            } else {
                // 解除封禁
                updateWrapper.set("delete_flag", false);
                updateWrapper.set("ban_end_time", null);

                // 记录操作日志
                log.info("解封会员: memberIds={}", memberIds);
            }

            boolean result = this.update(updateWrapper);

            // 如果更新失败，检查记录是否存在
            if (!result) {
                long count = this.count(new QueryWrapper<Member>().in("id", memberIds));
                if (count == 0) {
                    log.warn("更新会员状态失败: 未找到指定会员, memberIds={}", memberIds);
                    return ResultCode.USER_NOT_EXIST;
                } else {
                    log.warn("更新会员状态失败: 更新操作失败, memberIds={}", memberIds);
                    return ResultCode.ERROR;
                }
            }

            return ResultCode.SUCCESS;
        } catch (Exception e) {
            log.error("更新会员状态异常", e);
            return ResultCode.ERROR;
        }
    }

    /**
     * 定时任务：检查并解除到期的封禁账号
     * 每天凌晨执行
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void checkAndUnbanMembers() {
        log.info("开始执行会员自动解封任务");
        Date now = new Date();

        // 查找到期需要解封的会员数量
        QueryWrapper<Member> countWrapper = new QueryWrapper<>();
        countWrapper.eq("disabled", true)
            .isNotNull("ban_end_time")
            .le("ban_end_time", now);
        long count = this.count(countWrapper);

        if (count > 0) {
            // 解除封禁
            UpdateWrapper<Member> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("disabled", false)
                .set("ban_end_time", null)
                .eq("disabled", true)
                .isNotNull("ban_end_time")
                .le("ban_end_time", now);

            boolean result = this.update(updateWrapper);
            log.info("会员自动解封任务完成，解封会员数量：{}，处理结果：{}", count, result);
        } else {
            log.info("会员自动解封任务完成，无需要解封的会员");
        }
    }


    @Override
    public String getPhoneDecrypted(String phoneEncrypted) {
        return phoneEncrypted;
    }


    @Override

    public Member getById(Serializable id) {
        return super.getById(id);
    }


    @Override
    @Cacheable (cacheNames = GlobalConstants.MEMBER_KEY , key = "#id")
    public MemberVO getMemberInfo(Serializable id) {
        return memberConvert.toVO(getById(id));
    }


    @Override
    public MemberVO getLoginMemberInfo() {
        LoginUser tokenUser = LoginHelper.getLoginUser();
        return this.getMemberInfo(tokenUser.getUserId());
    }
    @Override
    public String updateWechat(MemberBO bo) {

        String openId=bo.getAvatar();
        //到微信去验证
        String token=bo.getPassword();

        return openId;
    }

    /**
     * 不带租户的获取会员信息
     *
     * @param query
     * @param page
     * @return
     */
    @Override
    public IPage<MemberVO> getMemberPageList(MemberBO query, Page<Member> page) {
        IPage<MemberVO> memeberPage= memberMapper.getMember(page, query);
        //检查是否是朋友
        LoginUser tokenUser = LoginHelper.getLoginUser();
        if (tokenUser != null) {
            List<MemberVO> records = memeberPage.getRecords();
            for (MemberVO memberVO : records) {
//
//                boolean followFlag = fansService.queryDoIFollowVloger(tokenUser.getUserId(), memberVO.getId());
//                if(followFlag){
//                    memberVO.setFollowFlag(YesOrNo.YES.type);
//                }else{
//                    memberVO.setFollowFlag(YesOrNo.NO.type);
//                }
                memberVO.setDoIFollowVloger(fansService.queryDoIFollowVloger(tokenUser.getUserId(), memberVO.getId()));

            }
        }
        return memeberPage;
    }

    @Override
    public void syncInfo() {
        //分页拉取用户信息



        return;
    }
}
