package com.fkzy.warn.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fkzy.warn.common.constants.*;
import com.fkzy.warn.model.Authorization;
import com.fkzy.warn.service.AuthorizationService;
import com.fkzy.warn.service.FileService;
import com.fkzy.warn.service.UserService;
import com.fkzy.warn.common.request.RequestParameter;
import com.fkzy.warn.common.response.ApiResponse;
import com.fkzy.warn.common.util.JWTUtil;
import com.fkzy.warn.common.util.RedisUtil;
import com.fkzy.warn.common.util.SMSUtils;
import com.fkzy.warn.mapper.UserMapper;
import com.fkzy.warn.model.User;
import com.nimbusds.jose.JOSEException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * @author zhangjing
 * @date 2024/12/04 14:51
 * @description
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements
    UserService {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private AuthorizationService authorizationService;

    @Autowired
    private JWTUtil jwtUtil;


    @Autowired
    private FileService fileService;

    @Value("${ali.accessKeyId}")
    private String accessKeyId;

    @Value("${ali.secret}")
    private String secret;

    @Override
    public ApiResponse sendCode(JSONObject jsonObject) {
        ApiResponse response = new ApiResponse();
        //账户名：手机号
        String phoneNumber = jsonObject.getString("phoneNumber");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber);
        //用户是否存在
        User user = getOne(queryWrapper);
        if (user == null) {
            response.recordMsgError(ResponseMsgConstants.USER_NOT_FOUND);
            return response;
        }
        String number = redisUtil.getString("code:" + phoneNumber);
        if (number != null) {
            response.recordMsgError(ResponseMsgConstants.CODE_SENT_SUCCESSFULLY);
            return response;
        }
        //生成6为随机验证码
        number = String.format("%06d", new Random().nextInt(1000000));
        //存Redis
        redisUtil.setString("code:" + phoneNumber, number, 60 * 5);
        SMSUtils.sendMessage("", "", "", "", accessKeyId, secret);
        return response;
    }

    @Override
    public ApiResponse login(JSONObject jsonObject) {
        ApiResponse response = new ApiResponse();
        //登录类型：1账户密码登录，2：手机短信验证码登录
        Integer loginType = jsonObject.getInteger("loginType");
        //账户名：手机号
        String phoneNumber = jsonObject.getString("phoneNumber");
        //密码
        String password = jsonObject.getString("password");
        //验证码
        String code = jsonObject.getString("code");
        User user = null;
        if (loginType.equals(UserConstants.SMS_CAPTCHA_LOGIN)) {
            //验证码登录
            String number = redisUtil.getString("code:" + phoneNumber);
            if (number == null) {
                response.recordMsgError(ResponseMsgConstants.CODE_EXPIRED_PLEASE_RESEND);
                return response;
            }
            //登录成功
            if (number.equals(code)) {
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("phone_number", phoneNumber);
                user = getOne(queryWrapper);
                response.setData(user);
            } else {
                response.recordMsgError(ResponseMsgConstants.CODE_ERROR);
                return response;
            }
        } else {
            //密码登录
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("phone_number", phoneNumber);
            user = getOne(queryWrapper);
            if (user == null) {
                response.recordMsgError(ResponseMsgConstants.USER_NOT_FOUND);
                return response;
            }
            if (!user.getPassword().equals(password)) {
                response.recordMsgError(ResponseMsgConstants.PASSWORD_ERROR);
                return response;
            }
            response.setData(user);

        }
        String token = this.createToken(user);
        String ticket = createTicket(token);

        redisUtil.setString(RedisKeyConstants.LOGIN_ST + ticket, token, 60 * 60 * 12);
        return response;
    }

    private String createTicket(String token) {
        String ticket = RedisKeyConstants.LOGIN_ST_HEADER + UUID.randomUUID().toString().replace("-", "");
        try {
            redisUtil.setString(RedisKeyConstants.LOGIN_ST + ticket, token, 60 * 60 * 12);
        } catch (Exception e) {
            log.error("登录,生成token失败,errMsg==={}" + e.getMessage());
            return null;
        }
        return ticket;
    }

    private String createToken(User user) {
        String publicKey = jwtUtil.getPublicKey();
        String token = null;
        try {
            token = jwtUtil.creatToken(user, publicKey);
        } catch (JOSEException e) {
            log.error("登录,生成token失败,errMsg==={}" + e.getMessage());
        }
        return token;
    }

    @Override
    public ApiResponse createUser(User entity, String ticket) {
        ApiResponse response = new ApiResponse();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", entity.getPhoneNumber());
        //用户是否存在
        User user = getOne(queryWrapper);
        if (user != null) {
            response.recordMsgError(ResponseMsgConstants.USER_PHONE_EXIST);
            return response;
        }
        save(entity);
        return response;
    }

    @Override
    public boolean saveModel(User entity) {
        boolean result = this.save(entity);
        return result;
    }

    @Override
    public boolean updateModel(User entity) {
        boolean result = this.updateById(entity);
        return result;
    }

    @Override
    public boolean deleteModel(User entity) {
        boolean result = this.removeById(entity);

        return result;
    }

    @Override
    public Page<User> queryPage(RequestParameter parameter) {
        User entity = parameter.getParameter().toJavaObject(User.class);
        Page<User> page = new Page<User>(parameter.getCurrent(), parameter.getSize());
        page.setSearchCount(true);
        page.setOptimizeCountSql(true);
        QueryWrapper<User> eWrapper = new QueryWrapper<User>(entity);
        Page<User> result = this.page(page, eWrapper);
        setInfo(result);
        return result;
    }

    @Override
    public User getUserByTicket(String ticket) {
        User user = null;
        if (redisUtil.exists(RedisKeyConstants.LOGIN_ST + ticket)) {
            user = jwtUtil.getUserByToken(redisUtil.getString(RedisKeyConstants.LOGIN_ST + ticket));
        }
        return user;
    }

    @Override
    public ApiResponse createTrial(User entity, String ticket) {
        ApiResponse response = new ApiResponse();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", entity.getPhoneNumber());
        //用户是否存在
        User user = getOne(queryWrapper);
        if (user != null) {
            response.recordMsgError(ResponseMsgConstants.USER_PHONE_EXIST);
            return response;
        }
        entity.setIsOfficialAccount(UserConstants.IS_TRIAL);
        entity.setTrialStatus(UserConstants.ACCOUNT_STATUS_UNENABLED);
        save(entity);
        return response;
    }

    @Override
    public Page<User> queryPageTrial(RequestParameter parameter) {
        User entity = parameter.getParameter().toJavaObject(User.class);
        Page<User> page = new Page<User>(parameter.getCurrent(), parameter.getSize());
        page.setSearchCount(true);
        page.setOptimizeCountSql(true);
        QueryWrapper<User> eWrapper = new QueryWrapper<User>(entity);
        eWrapper.eq("is_official_account", UserConstants.IS_TRIAL)
            .eq("is_del", EntityConstants.NORMAL)
            .orderByDesc("creat_time");
        Page<User> result = this.page(page, eWrapper);
        setInfo(result);
        return result;
    }

    @Override
    public ApiResponse setTrial(User entity, String ticket) {
        ApiResponse response = new ApiResponse();
        if (entity.getTrialStatus() == UserConstants.ACCOUNT_STATUS_TRIAL) {
            Date now = new Date();
            LocalDate localNow = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate end = localNow.plusDays(entity.getTrialDay());
            Date endDate = Date.from(end.atStartOfDay(ZoneId.systemDefault()).toInstant());
            entity.setEnableDate(now);
            entity.setEndDate(endDate);
        }
        updateById(entity);
        return response;
    }

    private void setInfo(Page<User> result) {
        for (User user : result.getRecords()) {
            // 这里可以添加需要返回的字段的填充
            if (user.getAuthorizationId() == null) {
                user.setAuthorizationStatus(AuthorizationConstants.STATUS_PENDING_APPLICATION);
            } else {
                user.setAuthorizationStatus(AuthorizationConstants.STATUS_AUTHORIZED_VALID);
                Authorization authorization = authorizationService.getById(user.getAuthorizationId());
                if (authorization != null) {
//                    user.setStartDate(authorization.getStartDate());
//                    user.setEndDate(authorization.getEndDate());
//                    user.setFile(fileService.getById(authorization.getFileId()));
                    //检查日期
                    //大于当前时间授权到期
                    if (authorization.getEndDate().after(new Date())) {
                        user.setAuthorizationStatus(AuthorizationConstants.STATUS_AUTHORIZED_EXPIRED);
                    }
                }
            }
        }
    }


}

