package iam

import (
	"errors"
	"time"
)

const (
	ContextUserIDKey    = "user_id"
	ContextSessionIDKey = "session_id"
	ContextJTIKey       = "jti"
)

type tokenKind string

const (
	tokenKindAccess  tokenKind = "access"
	tokenKindRefresh tokenKind = "refresh"
)

type accessClaims struct {
	UserID    int64     `json:"uid"`
	SessionID string    `json:"sid"`
	JTI       string    `json:"jti"`
	IssuedAt  int64     `json:"iat"`
	ExpiresAt int64     `json:"exp"`
	Type      tokenKind `json:"typ"`
}

type refreshClaims struct {
	UserID    int64     `json:"uid"`
	SessionID string    `json:"sid"`
	RefreshID string    `json:"rid"`
	IssuedAt  int64     `json:"iat"`
	ExpiresAt int64     `json:"exp"`
	Type      tokenKind `json:"typ"`
}

type Session struct {
	ID         string     `json:"id"`
	UserID     int64      `json:"user_id"`
	DeviceInfo string     `json:"device_info"`
	IP         string     `json:"ip"`
	UserAgent  string     `json:"user_agent"`
	CreatedAt  time.Time  `json:"created_at"`
	ExpiresAt  time.Time  `json:"expires_at"`
	RevokedAt  *time.Time `json:"revoked_at,omitempty"`
}

type tokenPair struct {
	AccessToken        string
	AccessTokenExpires time.Time
	RefreshToken       string
	SessionID          string
}

type requestMeta struct {
	IP         string
	UserAgent  string
	DeviceInfo string
}

type AuthResult struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int64  `json:"expires_in"`
	SessionID   string `json:"session_id"`
}

var (
	errInvalidToken       = errors.New("invalid token")
	errTokenExpired       = errors.New("token expired")
	errInvalidCredentials = errors.New("invalid credentials")
	errAlreadyExists      = errors.New("already exists")
	errSessionRevoked     = errors.New("session revoked")
	errUnauthorized       = errors.New("unauthorized")
	errForbidden          = errors.New("forbidden")
)
