package com.tourism.webadmin.app.website.service.impl;

import cn.hutool.core.util.ReflectUtil;
import com.tourism.common.additional.constant.CacheConstants;
import com.tourism.common.additional.utils.StringUtils;
import com.tourism.common.core.constant.GlobalDeletedFlag;
import com.tourism.common.core.object.TokenData;
import com.tourism.common.core.util.*;
import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
import com.tourism.webadmin.back.dao.TourBookInfoMapper;
import com.tourism.webadmin.app.website.dto.TourUserRegisterDto;
import com.tourism.webadmin.back.dto.TourBookInfoDto;
import com.tourism.webadmin.back.model.TourBookInfo;
import com.tourism.webadmin.back.model.TourUser;
import com.tourism.webadmin.back.model.constant.TourUserStatus;
import com.tourism.webadmin.app.website.service.LoginToWebsiteService;
import com.tourism.webadmin.back.service.TourBookInfoService;
import com.tourism.webadmin.back.service.TourUserService;
import io.jsonwebtoken.lang.Collections;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 注册校验方法
 * 
 * @author tourism
 */
@Slf4j
@Service("LoginToWebsiteService")
public class LoginToWebsiteServiceImpl implements LoginToWebsiteService
{
    @Autowired
    private TourBookInfoService tourBookInfoService;
    @Autowired
    private TourUserService tourUserService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IdGeneratorWrapper idGenerator;
    @Autowired
    private TourBookInfoMapper tourBookInfoMapper;
    @Autowired
    private RedissonClient redissonClient;
    /**
     * 整个工程的实体对象中，创建者Id字段的Java对象名。
     */
    public static final String CREATE_USER_ID_FIELD_NAME = "createUserId";
    /**
     * 整个工程的实体对象中，创建时间字段的Java对象名。
     */
    public static final String CREATE_TIME_FIELD_NAME = "createTime";
    /**
     * 整个工程的实体对象中，更新者Id字段的Java对象名。
     */
    public static final String UPDATE_USER_ID_FIELD_NAME = "updateUserId";
    /**
     * 整个工程的实体对象中，更新时间字段的Java对象名。
     */
    public static final String UPDATE_TIME_FIELD_NAME = "updateTime";

    /**
     * 校验验证码
     *
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    @Override
    public boolean validateCaptcha(String uuid, String code)
    {
        String verifyKey = CacheConstants.getCaptchaCodeKey(StringUtils.nvl(uuid, ""));
//        String captcha = redisCache.getCacheObject(verifyKey);
        // 获取 RBucket 对象
        RBucket<String> bucket = redissonClient.getBucket(verifyKey);

        // 从缓存中获取对象
        String captcha = bucket.get();

//        redisCache.deleteObject(verifyKey);
        bucket.delete();
        if (captcha == null || !(captcha.equals(code.toLowerCase())))
        {
            return false;
        }
        return true;
    }
    /**
     * 校验短信验证码
     *
     * @param mobile 手机号
     * @param smsCode 短信验证码
     * @return 结果
     */
    @Override
    public boolean validateSmsCode(String mobile,String smsCode){
//        String cacheObject = redisCache.getCacheObject(mobile);

        // 获取 RBucket 对象
        RBucket<String> bucket = redissonClient.getBucket(mobile);

        // 从缓存中获取对象
        String cacheObject = bucket.get();
//        redisCache.deleteObject(mobile);
        bucket.delete();
        if(cacheObject == null || !(smsCode.equals(cacheObject.toLowerCase())) ){
            return false;
        }
        return true;
    }
    /**
     * 保存用户的预约信息
     *
     * @param tourBookInfoDto 门户预定管理Dto对象
     * @return 结果
     */
    @Override
    public boolean saveBookInfo(HttpServletRequest request, TourBookInfoDto tourBookInfoDto){
        String bookMobile = tourBookInfoDto.getBookMobile();
            TourBookInfo tourBookInfo = new TourBookInfo();
            tourBookInfo.setBookMobile(bookMobile);
            tourBookInfo.setBookTime(new Date());
//            tourBookInfo.setBookName(bookName);
            tourBookInfo.setBookIp(IpUtil.getRemoteIpAddress(ContextUtil.getHttpRequest()));
            //默认0为未处理状态
            tourBookInfo.setIsHandle(0);
            tourBookInfo.setProjectId(tourBookInfoDto.getProjectId());
            tourBookInfo.setType(tourBookInfoDto.getType());
            tourBookInfoMapper.insert(buildDefaultValue(tourBookInfo));
            return true;
    }

    private TourBookInfo buildDefaultValue(TourBookInfo tourBookInfo) {
        if (tourBookInfo.getId() == null) {
            tourBookInfo.setId(idGenerator.nextLongId());
        }
        fillCommonsForInsert(tourBookInfo);
        tourBookInfo.setDeletedFlag(GlobalDeletedFlag.NORMAL);
        return tourBookInfo;
    }

    /**
     * 在插入实体对象数据之前，可以调用该方法，初始化通用字段的数据。
     * 在登录之前的操作，所以createdId和updatedId都设置为0.
     * @param data 实体对象。
     * @param <M>  实体对象类型。
     */
    public static <M> void fillCommonsForInsert(M data) {
        Field createdByField = ReflectUtil.getField(data.getClass(), CREATE_USER_ID_FIELD_NAME);
        if (createdByField != null) {
            ReflectUtil.setFieldValue(data, createdByField, 0L);
        }
        Field createTimeField = ReflectUtil.getField(data.getClass(), CREATE_TIME_FIELD_NAME);
        if (createTimeField != null) {
            ReflectUtil.setFieldValue(data, createTimeField, new Date());
        }
        Field updatedByField = ReflectUtil.getField(data.getClass(), UPDATE_USER_ID_FIELD_NAME);
        if (updatedByField != null) {
            ReflectUtil.setFieldValue(data, updatedByField, 0L);
        }
        Field updateTimeField = ReflectUtil.getField(data.getClass(), UPDATE_TIME_FIELD_NAME);
        if (updateTimeField != null) {
            ReflectUtil.setFieldValue(data, updateTimeField, new Date());
        }
    }
    /**
     * 保存用户的注册信息
     *
     * @param tourUserRegisterDto 预约手机号
     * @return 结果
     */
    @Override
    public boolean saveRegisterUserInfo(TourUserRegisterDto tourUserRegisterDto){
        //存储用户信息
        TourUser tourUser = new TourUser();
        //手机号注册，默认用户名为手机号
        tourUser.setLoginName(tourUserRegisterDto.getMobile());
        tourUser.setUserStatus(TourUserStatus.STATUS_NORMAL);
        tourUser.setPassword(passwordEncoder.encode(tourUser.getPassword()));
        tourUserService.saveNew(tourUser);
        return true;
    }
}
