package com.sonic.bear.domain.entity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.google.common.base.Strings;
import com.sonic.bear.enums.AccountType;
import com.sonic.common.auth.domains.SessionStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;

/**
 * @author coder
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@TableName(value = "user_session", autoResultMap = true)
public class UserSession {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /** 登陆记号 */
    private String token;
    /** 账号 Id */
    private Long userId;
    /** 登陆的账号类型 */
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private AccountType accountType;
    /** 客户端编码 */
    private String clientCode;
    /***
     * 登录类型（账号密码、三方、手机号验证码）
     */
    private String loginType;
    /** session 状态，默认为有效 */
    private SessionStatusEnum status;

    /**
     * 客户端设备基础信息
     */
    private String userAgent;
    /** 扩展数据，json字符串 */
    private String extra;
    /**
     * 登录的设备ID
     */
    private String deviceId;
    /**
     * 登录的IP地址
     */
    private String ip;
    /** session 创建时间 */
    private LocalDateTime createTime;
    /** session 最后一次访问时间 */
    private LocalDateTime lastAccessTime;
    /** session 过期/结束时间 */
    private LocalDateTime expireTime;

    @JSONField(serialize = false)
    public boolean isEnabled() {
        return status == SessionStatusEnum.ENABLED;
    }

    @JSONField(serialize = false)
    public boolean isDisabled() {
        return status != SessionStatusEnum.ENABLED;
    }

    @JSONField(serialize = false)
    public boolean isExpired() {
        return expireTime != null && LocalDateTime.now().isAfter(expireTime);
    }

    /**
     * 是否超过最大存活期内
     * @param sessionAlive 最大存活时间，单位分钟，由 client 定义
     * @return 是否在最大存活时间内
     */
    @JSONField(serialize = false)
    public boolean isOverMaxAlive(Integer sessionAlive) {
        LocalDateTime maxAliveTime = createTime.plusMinutes(sessionAlive);
        return LocalDateTime.now().isAfter(maxAliveTime);
    }

    /** 将extra转为对象 */
    public Extra normalizedExtra() {
        return JSON.parseObject(extra, Extra.class);
    }

    public static Extra parseExtraObject(String text) {
        if (Strings.isNullOrEmpty(text)) {
            return new Extra();
        }
        return JSON.parseObject(text, Extra.class);
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Extra {
        private String email;
    }

}
