package com.ruoyi.web.modules.account.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.account.constant.MemberConstants;
import com.ruoyi.web.modules.account.domain.BizMember;
import com.ruoyi.web.modules.account.dto.MemberLoginDTO;
import com.ruoyi.web.modules.account.dto.MemberRegisterDTO;
import com.ruoyi.web.modules.account.mapper.BizMemberMapper;
import com.ruoyi.web.modules.account.service.IMemberAppService;
import com.ruoyi.web.modules.account.service.IMemberSmsService;
import com.ruoyi.web.modules.account.service.IMemberTokenService;
import com.ruoyi.web.modules.account.util.UserNameGenerator;
import com.ruoyi.web.modules.content.facade.IMallServiceAgreementFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * C 端会员 Service 实现
 */
@Service
public class MemberAppServiceImpl implements IMemberAppService
{
    @Autowired
    private BizMemberMapper memberMapper;

    @Autowired
    private IMemberSmsService smsService;

    @Autowired
    private IMemberTokenService tokenService;

    @Autowired
    private IMallServiceAgreementFacade mallServiceAgreementFacade;

    @Override
    public void sendSms(String mobile)
    {
        smsService.sendCode(mobile);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long register(MemberRegisterDTO dto)
    {
        validateRegister(dto);
        mallServiceAgreementFacade.assertAcceptedForRegister(Boolean.TRUE.equals(dto.getAgreementAccepted()));
        if (memberMapper.countByMobile(dto.getMobile(), null) > 0)
        {
            throw new ServiceException("手机号已注册");
        }
        if (!smsService.verifyCode(dto.getMobile(), dto.getSmsCode()))
        {
            throw new ServiceException("验证码错误或已过期");
        }
        String memberName = generateUniqueMemberName();
        BizMember member = new BizMember();
        member.setMobile(dto.getMobile());
        member.setMemberCode(memberName);
        member.setNickName(StringUtils.isEmpty(dto.getNickName()) ? memberName : dto.getNickName());
        member.setPassword(SecurityUtils.encryptPassword(dto.getPassword()));
        member.setStatus(MemberConstants.STATUS_ENABLED);
        member.setOrderCount(0);
        member.setTotalAmount(BigDecimal.ZERO);
        member.setRegisterTime(new Date());
        memberMapper.insert(member);
        return member.getMemberId();
    }

    @Override
    public Map<String, Object> login(MemberLoginDTO dto)
    {
        if (dto == null || StringUtils.isEmpty(dto.getMobile()) || StringUtils.isEmpty(dto.getPassword()))
        {
            throw new ServiceException("请输入手机号和密码");
        }
        mallServiceAgreementFacade.assertAcceptedForLogin(Boolean.TRUE.equals(dto.getAgreementAccepted()));
        BizMember member = memberMapper.selectByMobile(dto.getMobile());
        if (member == null)
        {
            throw new ServiceException("手机号或密码错误");
        }
        if (!MemberConstants.STATUS_ENABLED.equals(member.getStatus()))
        {
            throw new ServiceException("账号已禁用，请联系客服");
        }
        if (!SecurityUtils.matchesPassword(dto.getPassword(), member.getPassword()))
        {
            throw new ServiceException("手机号或密码错误");
        }
        String token = tokenService.createToken(member.getMemberId());
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("memberId", member.getMemberId());
        return result;
    }

    @Override
    public BizMember getProfile(Long memberId)
    {
        BizMember member = memberMapper.selectById(memberId);
        if (member == null)
        {
            throw new ServiceException("会员不存在");
        }
        member.setPassword(null);
        return member;
    }

    @Override
    public void updateProfile(Long memberId, BizMember profile)
    {
        BizMember existing = memberMapper.selectById(memberId);
        if (existing == null)
        {
            throw new ServiceException("会员不存在");
        }
        BizMember update = new BizMember();
        update.setMemberId(memberId);
        if (StringUtils.isNotEmpty(profile.getMemberCode()))
        {
            if (profile.getMemberCode().length() > 64)
            {
                throw new ServiceException("会员名称过长");
            }
            update.setMemberCode(profile.getMemberCode());
        }
        update.setNickName(profile.getNickName());
        update.setAvatar(profile.getAvatar());
        if (StringUtils.isNotEmpty(profile.getPassword()))
        {
            update.setPassword(SecurityUtils.encryptPassword(profile.getPassword()));
        }
        memberMapper.update(update);
    }

    private void validateRegister(MemberRegisterDTO dto)
    {
        if (dto == null || StringUtils.isEmpty(dto.getMobile()))
        {
            throw new ServiceException("请输入手机号");
        }
        if (StringUtils.isEmpty(dto.getPassword()))
        {
            throw new ServiceException("请输入密码");
        }
        if (StringUtils.isEmpty(dto.getSmsCode()))
        {
            throw new ServiceException("请输入验证码");
        }
        if (!dto.getMobile().matches("^1\\d{10}$"))
        {
            throw new ServiceException("手机号格式不正确");
        }
        String name = StringUtils.isNotEmpty(dto.getMemberCode()) ? dto.getMemberCode() : dto.getNickName();
        if (StringUtils.isNotEmpty(name) && name.length() > 64)
        {
            throw new ServiceException("会员名称过长");
        }
    }

    /**
     * 生成并保证唯一的用户名
     */
    public String generateUniqueMemberName() {
        String memberName;
        do {
            memberName = UserNameGenerator.generateUniqueName();
            // 查数据库是否已存在
        } while (memberMapper.countByByMemberName(memberName) > 0);
        return memberName;
    }
}
