package model

import (
	"time"

	"security-center-backend/internal/service/directory"
)

type UserStatus string

const (
	UserStatusActive    UserStatus = "active"
	UserStatusInactive  UserStatus = "inactive"
	UserStatusSuspended UserStatus = "suspended"
)

type EmployeeLinkStatus string

const (
	EmployeeLinkStatusPending EmployeeLinkStatus = "pending"
	EmployeeLinkStatusLinked  EmployeeLinkStatus = "linked"
	EmployeeLinkStatusFailed  EmployeeLinkStatus = "failed"
)

type User struct {
	Base
	ExternalID       string     `gorm:"size:255;uniqueIndex" json:"external_id"`
	Auth0UserID      string     `gorm:"size:255;uniqueIndex" json:"auth0_user_id,omitempty"`
	IdentityProvider string     `gorm:"size:50;default:'google'" json:"identity_provider,omitempty"`
	MigratedToAuth0  bool       `gorm:"default:false" json:"migrated_to_auth0,omitempty"`
	MigrationDate    *time.Time `json:"migration_date,omitempty"`
	Email            string     `gorm:"size:320;uniqueIndex" json:"email"`
	Name             string     `gorm:"size:255" json:"name"`
	AvatarURL        string     `gorm:"size:512" json:"avatar_url"`

	EmployeeID *uint64             `gorm:"index" json:"employee_id,omitempty"`
	Employee   *directory.Employee `gorm:"foreignKey:EmployeeID" json:"employee,omitempty"`

	Status             UserStatus         `gorm:"type:enum('active','inactive','suspended');default:'active'" json:"status"`
	FirstLoginAt       *time.Time         `json:"first_login_at,omitempty"`
	LastLoginAt        *time.Time         `json:"last_login_at,omitempty"`
	EmployeeLinkStatus EmployeeLinkStatus `gorm:"size:20;default:'pending'" json:"employee_link_status,omitempty"`
	DefaultRoleID      *uint64            `gorm:"index" json:"default_role_id,omitempty"`
	DefaultRole        *Role              `json:"default_role,omitempty"`
	Roles              []Role             `gorm:"many2many:user_roles;" json:"roles,omitempty"`
}

// HasRole checks if user has a specific role.
func (u *User) HasRole(roleName string) bool {
	for _, role := range u.Roles {
		if role.Name == roleName {
			return true
		}
	}
	return false
}

// HasPermission checks whether any assigned role grants the permission.
func (u *User) HasPermission(permissionName string) bool {
	for _, role := range u.Roles {
		for _, permission := range role.Permissions {
			if permission.Name == permissionName {
				return true
			}
		}
	}
	return false
}

type Role struct {
	Base
	Name        string       `gorm:"size:100;uniqueIndex" json:"name"`
	Description string       `gorm:"size:255" json:"description"`
	IsDefault   bool         `gorm:"default:false" json:"is_default"`
	Permissions []Permission `gorm:"many2many:role_permissions;" json:"permissions,omitempty"`
}

type Permission struct {
	Base
	Name        string `gorm:"size:150;uniqueIndex" json:"name"`
	Description string `gorm:"size:255" json:"description"`
	Metadata    JSONB  `gorm:"type:json" json:"metadata,omitempty"`
}
