package db

import "time"

type ScopeMode string

const (
	ScopeModeAllProjects      ScopeMode = "all_projects"
	ScopeModeProjectAllowList ScopeMode = "project_allow_list"
	ScopeModeProjectDenyList  ScopeMode = "project_deny_list"
	ScopeModeTagAllowList     ScopeMode = "tag_allow_list"
	ScopeModeTagDenyList      ScopeMode = "tag_deny_list"
)

func (m ScopeMode) Valid() bool {
	switch m {
	case ScopeModeAllProjects,
		ScopeModeProjectAllowList,
		ScopeModeProjectDenyList,
		ScopeModeTagAllowList,
		ScopeModeTagDenyList:
		return true
	default:
		return false
	}
}

func (m ScopeMode) UsesProjectRules() bool {
	return m == ScopeModeProjectAllowList || m == ScopeModeProjectDenyList
}

func (m ScopeMode) UsesTagRules() bool {
	return m == ScopeModeTagAllowList || m == ScopeModeTagDenyList
}

type UserRole string

const (
	UserRoleAdmin  UserRole = "admin"
	UserRoleEditor UserRole = "editor"
	UserRoleViewer UserRole = "viewer"
)

type User struct {
	ID           int64
	Email        string
	PasswordHash string
	Role         UserRole
	IsActive     bool
	CreatedAt    time.Time
	UpdatedAt    time.Time
	LastLoginAt  *time.Time
}

type Project struct {
	ID          int64
	Name        string
	Slug        string
	Description string
	IsActive    bool
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

type ProjectListItem struct {
	Project      Project
	TagCount     int
	ReleaseCount int
}

type Tag struct {
	ID          int64
	Name        string
	Slug        string
	Description string
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

type TagListItem struct {
	Tag          Tag
	ProjectCount int
}

type Release struct {
	ID               int64
	ProjectID        int64
	Version          string
	Build            string
	Filename         string
	StoragePath      string
	ChecksumSHA256   string
	SizeBytes        int64
	ContentType      string
	ReleaseNotes     string
	CreatedAt        time.Time
	UpdatedAt        time.Time
	UploadedByUserID *int64
	IsActive         bool
}

type ReleaseListItem struct {
	Release         Release
	UploadedByEmail string
}

type APIKey struct {
	ID                int64
	Name              string
	KeyPrefix         string
	KeyHash           string
	Description       string
	ScopeMode         ScopeMode
	CanDownload       bool
	CanUpload         bool
	CanDelete         bool
	CanManageProjects bool
	IsActive          bool
	ExpiresAt         *time.Time
	CreatedAt         time.Time
	UpdatedAt         time.Time
	LastUsedAt        *time.Time
	CreatedByUserID   *int64
}

func (k APIKey) Expired(now time.Time) bool {
	return k.ExpiresAt != nil && !k.ExpiresAt.After(now.UTC())
}

type APIKeyListItem struct {
	APIKey            APIKey
	ProjectRuleCount  int
	TagRuleCount      int
	AccessiblePreview int
}

type APIKeyProjectAccess struct {
	APIKeyID  int64
	ProjectID int64
	CreatedAt time.Time
}

type APIKeyTagAccess struct {
	APIKeyID  int64
	TagID     int64
	CreatedAt time.Time
}

type Session struct {
	ID            int64
	UserID        int64
	TokenHash     string
	ExpiresAt     time.Time
	LastSeenAt    *time.Time
	InvalidatedAt *time.Time
	IPAddress     string
	UserAgent     string
	CreatedAt     time.Time
}

type SessionWithUser struct {
	Session Session
	User    User
}

type AuditLog struct {
	ID               int64
	ActorUserID      *int64
	APIKeyID         *int64
	Action           string
	TargetType       string
	TargetID         *int64
	TargetIdentifier string
	MetadataJSON     string
	IPAddress        string
	CreatedAt        time.Time
}
