package com.ssm.manage.service.impl;

import com.ssm.core.service.impl.BaseServiceImpl;
import com.ssm.core.utils.AESUtils;
import com.ssm.core.utils.ChuangLanBeanSmsUtil;
import com.ssm.core.utils.SnowflakeUtil;
import com.ssm.manage.dao.*;
import com.ssm.manage.entity.*;
import com.ssm.manage.query.MemberRequest;
import com.ssm.manage.query.StaffRequest;
import com.ssm.manage.response.MemberResponse;
import com.ssm.manage.response.ResponseCode;
import com.ssm.manage.response.UserResponse;
import com.ssm.manage.service.SsmBaseStoreService;
import com.ssm.manage.service.SsmMemberLoginService;
import com.ssm.manage.utils.Constant;
import com.ssm.util.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SsmMemberLoginServiceImpl extends BaseServiceImpl<StoreMemberList> implements SsmMemberLoginService {
    @Autowired
    private RedisClient<MemberResponse> redisClient;

    @Autowired
    private SsmBaseStoreService ssmBaseStoreService;
    @Autowired
    private BlackListDao blackListDao;

    @Autowired
    private MemberLoginImageDao memberLoginImageDao;

    @Autowired
    private MemberLoginRecordingDao memberLoginRecordingDao;

    @Autowired
    private SsmMemberAgreementDao ssmMemberAgreementDao;

    @Autowired
    private ChuangLanBeanSmsUtil chuangLanBeanSmsUtil;

    @Autowired
    private SsmMemberLoginDao dao;

    @Override
    public SsmMemberLoginDao getDao() {
        return dao;
    }


    @Override
    public MemberResponse phoneLogin(MemberRequest memberRequest) throws SmsException {
        String mobilePhone = AESUtils.encrypt(memberRequest.getMobilePhone());

        StoreMemberList memberList = new StoreMemberList();
        memberList.setState(1);
        memberList.setMobilePhone(mobilePhone);
        memberList.setMemberNum(memberRequest.getMemberNum());
        //查询数据库
        memberList = dao.selectOne(memberList);
        if (memberList == null){
            throw new SmsException(ResponseCode.NO_USER);
        }
        //获取redis codeKey值
        String codeKey = getPasscodeKey(memberRequest.getMobilePhone());
        String key = Constant.memberKey;
//                getKey(memberRequest.getMobilePhone());
        MemberResponse memberResponse = new MemberResponse();
        String token = "";
        String passCode = memberRequest.getPassCode();
        //从redis查询
        if (redisClient.hasKey(codeKey)){
            //校验验证码
            if (passCode.equals(redisClient.get(codeKey).getPassCode())) {
                //存在 将redis数据删除 重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                BeanUtils.copyProperties(memberList,memberResponse);
                memberResponse.setToken(token);
                memberResponse.setMobilePhone(memberRequest.getMobilePhone());
//                //查询当前登录用户的菜单权限
//                List list = ssmSysUserService.userHasPower(sysUser.getId());
//                userResponse.setList(list);
                key = key+memberRequest.getMobilePhone();
                redisClient.set(key, memberResponse, RedisClient.EXPIRE_TIME_ONE_DAY);

            }
        }else {
            //redis不存在 验证码已过期
            throw new SmsException(ResponseCode.SMS_CODE_IS_OVER);
        }
        return memberResponse;
    }

    @Override
    public MemberResponse phonePassLogin(MemberRequest memberRequest) throws SmsException {
        String mobilePhone = AESUtils.encrypt(memberRequest.getMobilePhone());

        StoreMemberList memberList = new StoreMemberList();
        memberList.setState(1);
        memberList.setMobilePhone(mobilePhone);
//        memberList.setMemberNum(memberRequest.getMemberNum());
        MemberResponse memberResponse = new MemberResponse();
        String token = "";
        String password = null;
        try {
            password = AESUtils.encrypt(memberRequest.getPassword());
        } catch (Exception e) {
            throw new SmsException(ResponseCode.DECRYPT_FAILED);
        }
        //查询数据库
        memberList = dao.selectOne(memberList);
        if (memberList == null){
            throw new SmsException(ResponseCode.NO_USER);
        }else {
            //获取redis key值
            String key = Constant.memberKey;
//                    getKey(memberRequest.getMobilePhone());
            //对比密码是否一致
            if (password.equals(memberList.getPassword())){
                //从redis查询
                if (redisClient.hasKey(key)){
                    //存在 将redis数据删除
                    memberResponse = redisClient.get(key);
                    redisClient.delete(key);
                }else {
                    //redis不存在 将数据库查询到的数据返回
                    BeanUtils.copyProperties(memberList,memberResponse);
                    memberResponse.setMobilePhone(memberRequest.getMobilePhone());
                }
                //重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                memberResponse.setToken(token);
//                //查询当前登录用户的菜单权限
//                List list = ssmSysUserService.userHasPower(sysUser.getId());
//                userResponse.setList(list);
                //将登陆用户数据放入redis中
                redisClient.set(key, memberResponse, RedisClient.EXPIRE_TIME_ONE_DAY);
            }else {
                throw  new SmsException(ResponseCode.ACCOUNT_OR_PW_ERROR);
            }
        }
        return memberResponse;
    }

    @Override
    public MemberResponse getSmsCode(MemberRequest memberRequest) throws SmsException, IOException {
        MemberResponse memberResponse = new MemberResponse();
        String code = ObjectUtils.toString((int)((Math.random()*9+1)*1000));//生成验证码
        //先判断手机也没有注册
        StoreMemberList memberList = new StoreMemberList();
        memberList.setState(1);
        if (StringUtils.isNotBlank(memberRequest.getMobilePhone())){
            String mobilePhone = AESUtils.encrypt(memberRequest.getMobilePhone());
            memberList.setMobilePhone(mobilePhone);
        }

        //查询数据库
        memberList = dao.selectOne(memberList);
        if(Objects.isNull(memberList)){
            throw new SmsException(ResponseCode.MSG,"手机号尚未注册！");
        }

//        String msg = code+"(登录验证码，请完成验证)，如非本人操作，请忽略本短信。";
//        UserResponse userResponse = chuangLanBeanSmsUtil.sendSmsCode(Constant.smsUrl, Constant.smsAccount,
//                Constant.smsPassword, memberRequest.getMobilePhone(), msg);
        BaseStore baseStore = ssmBaseStoreService.selectByPrimaryKey(memberList.getStoreId());
//        try {

        UserResponse userResponse = chuangLanBeanSmsUtil.sendCheckSmsNew(baseStore,memberRequest.getMobilePhone(),Integer.parseInt(code));
        /*UserResponse userResponse = new UserResponse();
        userResponse.setSendSmsStatus(true);
        log.info("Verify code: {}", code);*/
//        }catch (SmsException e){
//            throw new SmsException(ResponseCode.MSG,"平台短信异常，门店联系电话："+baseStore.getTelephone());
//        }
//        String msg = "您的验证码是:" + code + ",请确认是您本人在操作,并注意保管,10分钟内有效";
//        UserResponse userResponse = chuangLanBeanSmsUtil.sendSmsCode(Constant.smsUrl, Constant.smsAccount,
//                Constant.smsPassword, memberRequest.getMobilePhone(), msg);
        if (userResponse.getSendSmsStatus()) {
            memberResponse.setPassCode(code);
            //将验证码放入redis中
            redisClient.set(getPasscodeKey(memberRequest.getMobilePhone()), memberResponse,RedisClient.EXPIRE_TIME_TEN_MINUTES);
        }
        return memberResponse;
    }

    @Override
    public int changePassword(MemberRequest memberRequest) throws SmsException {
        String mobilePhone = "";
//        try {
//            mobilePhone = AESUtils.encrypt(memberRequest.getMobilePhone());
//        } catch (Exception e) {
//            throw new SmsException(ResponseCode.DECRYPT_FAILED);
//        }
        StoreMemberList memberList = new StoreMemberList();
        memberList.setId(memberRequest.getId());
        memberList = dao.selectByPrimaryKey(memberRequest.getId());
        try {
            mobilePhone =   AESUtils.decrypt(memberList.getMobilePhone()).replaceAll("\u0000","");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(!AESUtils.encrypt(memberRequest.getPassword()).equals(memberList.getPassword())){
            throw new SmsException(ResponseCode.MSG,"原始密码错误");
        }
        String newPassword = "";
        try {
            newPassword = AESUtils.encrypt(memberRequest.getNewPassword());
        } catch (Exception e) {
            throw new SmsException(ResponseCode.DECRYPT_FAILED);
        }
        memberList.setPassword(newPassword);
        int i = dao.updateByPrimaryKey(memberList);
        if (i <= 0){
            throw new SmsException(ResponseCode.FAILED);
        }else {
            //修改成功 删除redis缓存
//            String key = Constant.memberKey;
//            String key = getKey(mobilePhone);
            redisClient.delete(memberRequest.getOldToken());
        }
        return i;
    }

    @Override
    public void logout(MemberRequest memberRequest, HttpSession session) {
        //清除redis
        if (redisClient.hasKey(Constant.memberKey
//                getKey(memberRequest.getMobilePhone())
                )){
            redisClient.delete(Constant.memberKey
//                    getKey(memberRequest.getMobilePhone())
            );
        }
        //清除session
        session.invalidate();
    }

    @Override
    public void uniLogout(MemberRequest memberRequest) {
        //清除redis
        String key = getKey(memberRequest.getOldToken());

        Set<String> s =  redisClient.keys(key + "*");
        if (s.size() > 0){
            //存在 将redis数据删除
            redisClient.delete(s);
        }
    }

    @Override
    public MemberResponse uniPhoneLogin(MemberRequest memberRequest) throws SmsException {
        String mobilePhone = AESUtils.encrypt(memberRequest.getMobilePhone());

        StoreMemberList memberList = new StoreMemberList();
        memberList.setState(1);
        memberList.setMobilePhone(mobilePhone);
        //memberList.setMemberNum(memberRequest.getMemberNum());
        //查询数据库
        memberList = dao.selectOne(memberList);
        if (memberList == null){
            throw new SmsException(ResponseCode.NO_USER);
        }
        //获取redis codeKey值
        String codeKey = getPasscodeKey(memberRequest.getMobilePhone());
        MemberResponse memberResponse = new MemberResponse();
        String token = "";
        String passCode = memberRequest.getPassCode();
        //从redis查询
        if (redisClient.hasKey(codeKey)){
            //校验验证码
            if (passCode.equals(redisClient.get(codeKey).getPassCode())) {
                //存在 将redis数据删除 重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                BeanUtils.copyProperties(memberList,memberResponse);
                memberResponse.setToken(token);
                memberResponse.setMobilePhone(memberRequest.getMobilePhone());
//                //查询当前登录用户的菜单权限
//                List list = ssmSysUserService.userHasPower(sysUser.getId());
//                userResponse.setList(list);
                String key =
//                        getKey(memberRequest.getMobilePhone())
                        Constant.memberKey
                                + token;
                redisClient.set(key, memberResponse, RedisClient.EXPIRE_TIME_ONE_DAY*7);

            }
        }else {
            //redis不存在 验证码已过期
            throw new SmsException(ResponseCode.SMS_CODE_IS_OVER);
        }


        //查询当前门第是否是总店
        BaseStore baseStore = ssmBaseStoreService.selectByPrimaryKey(memberList.getStoreId());
        Long storeId;
        if(baseStore.getParentId()==null){
            storeId = baseStore.getId();
        }else {
            storeId = baseStore.getParentId();
        }
        //查询当前已审核的协议
        MemberAgreement memberAgreement = new MemberAgreement();
        memberAgreement.setStoreId(storeId);
        memberAgreement.setStartState(1);
        List<MemberAgreement> select = ssmMemberAgreementDao.select(memberAgreement);
        if(select!=null && select.size()>0){
            memberAgreement = select.get(0);
        }
        //进行保存用户登录
        MemberLoginRecording memberLoginRecording = new MemberLoginRecording();
        memberLoginRecording.setId(new SnowflakeUtil(new Random().nextInt(1023)).nextId());
        memberLoginRecording.setLoginTime(new Date());
        memberLoginRecording.setLoginType(1);
        memberLoginRecording.setMemberName(memberList.getMemberName());
        memberLoginRecording.setMemberNum(memberList.getMemberNum());
        memberLoginRecording.setAgreementId(memberAgreement.getId());
        memberLoginRecording.setAgreementName(memberAgreement.getAgreementName());
        memberLoginRecording.setContent(memberAgreement.getContent());
        memberLoginRecording.setMemberId(memberList.getId());
        memberLoginRecordingDao.addMemberLogin(memberLoginRecording);
        //判断会员当前协议有没有签字确认
        MemberLoginImage memberLoginImage = new MemberLoginImage();
        memberLoginImage.setMemberId(memberList.getId());
        memberLoginImage.setAgreementId(memberAgreement.getId());
        List<MemberLoginImage> select1 = memberLoginImageDao.select(memberLoginImage);
        memberResponse.setIsSignature(1);
        if (select1==null || select1.size()==0){
            memberResponse.setIsSignature(0);
        }
        return memberResponse;
    }

    @Override
    public MemberResponse uniPhonePassLogin(MemberRequest memberRequest) throws SmsException {


        StoreMemberList memberList = new StoreMemberList();
        memberList.setState(1);
        if (StringUtils.isNotBlank(memberRequest.getMobilePhone())){
            String mobilePhone = AESUtils.encrypt(memberRequest.getMobilePhone());
            memberList.setMobilePhone(mobilePhone);
//            memberList.setStoreId(memberRequest.getStoreId());
        }
        if (StringUtils.isNotBlank(memberRequest.getMemberNum())){
            memberList.setMemberNum(memberRequest.getMemberNum());
        }

        MemberResponse memberResponse = new MemberResponse();
        String token = "";
        String password = null;
        try {
            password = AESUtils.encrypt(memberRequest.getPassword());
        } catch (Exception e) {
            throw new SmsException(ResponseCode.DECRYPT_FAILED);
        }
        //查询数据库
        List<StoreMemberList> storeMemberLists = dao.select(memberList);
        if(storeMemberLists!=null && storeMemberLists.size()>0){
            memberList = storeMemberLists.get(0);
        }else {
            memberList = null;
        }
        if (memberList == null){
            throw new SmsException(ResponseCode.NO_USER);
        }else {
            //对比密码是否一致
            if (password.equals(memberList.getPassword())){
//                String key = getKey(memberRequest.getMobilePhone());
                //从redis查询
//                Set<String> s =  redisClient.keys(key + "*");
//                if (s.size() > 0){
//                    //存在 将redis数据删除
//                    redisClient.delete(s);
//                }
                //redis不存在 将数据库查询到的数据返回
                BeanUtils.copyProperties(memberList, memberResponse);
                try {
                    memberResponse.setMobilePhone(AESUtils.decrypt(memberList.getMobilePhone()).replaceAll("\u0000",""));
                } catch (Exception e) {
                    throw new SmsException(ResponseCode.DECRYPT_FAILED);
                }

                //重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                memberResponse.setToken(token);

//                //查询当前登录用户的菜单权限
//                List list = ssmSysUserService.userHasPower(sysUser.getId());
//                userResponse.setList(list);
                //将登陆用户数据放入redis中
                //获取redis key值
//                key = key + memberResponse.getMobilePhone();
                String key = Constant.memberKey + token;
                redisClient.set(key, memberResponse, RedisClient.EXPIRE_TIME_ONE_DAY*7);
            }else {
                throw  new SmsException(ResponseCode.ACCOUNT_OR_PW_ERROR);
            }
        }
        //查询当前门第是否是总店
        BaseStore baseStore = ssmBaseStoreService.selectByPrimaryKey(memberList.getStoreId());
        Long storeId;
        if(baseStore.getParentId()==null){
            storeId = baseStore.getId();
        }else {
            storeId = baseStore.getParentId();
        }
        //查询当前已审核的协议
        MemberAgreement memberAgreement = new MemberAgreement();
        memberAgreement.setStoreId(storeId);
        memberAgreement.setStartState(1);
        List<MemberAgreement> select = ssmMemberAgreementDao.select(memberAgreement);
        if(select!=null && select.size()>0){
            memberAgreement = select.get(0);
        }
        //进行保存用户登录
        MemberLoginRecording memberLoginRecording = new MemberLoginRecording();
        memberLoginRecording.setId(new SnowflakeUtil(new Random().nextInt(1023)).nextId());
        memberLoginRecording.setLoginTime(new Date());
        memberLoginRecording.setLoginType(1);
        memberLoginRecording.setMemberName(memberList.getMemberName());
        memberLoginRecording.setMemberNum(memberList.getMemberNum());
        memberLoginRecording.setAgreementId(memberAgreement.getId());
        memberLoginRecording.setAgreementName(memberAgreement.getAgreementName());
        memberLoginRecording.setContent(memberAgreement.getContent());
        memberLoginRecording.setMemberId(memberList.getId());
        memberLoginRecordingDao.addMemberLogin(memberLoginRecording);
        //判断会员当前协议有没有签字确认
        MemberLoginImage memberLoginImage = new MemberLoginImage();
        memberLoginImage.setMemberId(memberList.getId());
        memberLoginImage.setAgreementId(memberAgreement.getId());
        List<MemberLoginImage> select1 = memberLoginImageDao.select(memberLoginImage);
        memberResponse.setIsSignature(1);
        if (select1==null || select1.size()==0){
            memberResponse.setIsSignature(0);
        }
        return memberResponse;
    }

    @Override
    public List<BaseStores> getMemberStore(MemberRequest memberRequest) throws SmsException {
        //根据手机号查询会员存在的门店
        StoreMemberList storeMemberList = new StoreMemberList();
        if(memberRequest.getMobilePhone()==null || memberRequest.getMobilePhone().trim().length()==0){
            throw new SmsException(ResponseCode.MSG,"请输入手机号");
        }
        storeMemberList.setMobilePhone(AESUtils.encrypt(memberRequest.getMobilePhone().trim()));
        List<StoreMemberList> storeMemberLists = dao.select(storeMemberList);
        //然后进行查门店，查询门店的所属总店
        List<Long> storeIds = storeMemberLists.stream().map(StoreMemberList::getStoreId).collect(Collectors.toList());
        List<BaseStores> storesList = ssmBaseStoreService.selectStoreS(storeIds);
        List<BaseStores> baseStores = new ArrayList<>();
        storeIds = new ArrayList<>();
        for (BaseStores store : storesList) {
            if(store.getParentId()==null){
                baseStores.add(store);
            }
            storeIds.add(store.getParentId());
        }
        baseStores.addAll(ssmBaseStoreService.selectStoreS(storeIds));

        return baseStores;
    }


    public String getKey(String phone){
        String key = "";
        if (StringUtils.isNotBlank(phone)){
            key = Constant.memberKey + phone;
        }
        return key;
    }

    public String getPasscodeKey(String phone){
        String key = "";
        if (StringUtils.isNotBlank(phone)){
            key = Constant.memberPasscode + phone;
        }
        return key;
    }
    @Override
    public MemberResponse getStaffCode(MemberRequest memberRequest) throws SmsException, IOException {
        MemberResponse memberResponse = new MemberResponse();
        String code = ObjectUtils.toString((int)((Math.random()*9+1)*1000));//生成验证码
        //先判断手机也没有注册
        Example example = new Example(BlackList.class);
        example.selectProperties("type","storeId");
        Example.Criteria criteria = example.createCriteria();
        String mobilePhone = memberRequest.getMobilePhone();
        if(StringUtils.isEmpty(mobilePhone)){
            throw new SmsException(ResponseCode.MSG,"请输入手机号！");
        }
        criteria.andEqualTo(StaffRequest.Fields.mobilePhone, mobilePhone);
//        criteria.andEqualTo(StaffRequest.Fields.storeId,memberRequest.getStoreId());
        List<BlackList> list = blackListDao.selectByExample(example);
        if(CollectionUtils.isEmpty(list)) {
            throw new SmsException(ResponseCode.MSG,"用户未注册！");
        }
        if (list.get(0).getType()==1){
            throw new SmsException(ResponseCode.BLACK_MSG,"用户已被拉入黑名单，请联系管理员！");
        }
        BaseStore baseStore = ssmBaseStoreService.selectByPrimaryKey(list.get(0).getStoreId());
        int codeInt = Integer.parseInt(code);
        UserResponse userResponse = chuangLanBeanSmsUtil.sendCheckSmsNew(baseStore, mobilePhone, codeInt);
        /*UserResponse userResponse = new UserResponse();
        userResponse.setSendSmsStatus(true);
        log.info("验证码: {}", code);*/
        if (userResponse.getSendSmsStatus()) {
            memberResponse.setPassCode(code);
            //将验证码放入redis中
            redisClient.set(getPasscodeKey(mobilePhone), memberResponse,RedisClient.EXPIRE_TIME_TEN_MINUTES);
        }
        return memberResponse;
    }
}
