package rbac

import (
	"time"

	"github.com/google/uuid"
)

// IsolationLevel defines namespace isolation strictness
type IsolationLevel string

const (
	IsolationStrict IsolationLevel = "strict"
	IsolationShared IsolationLevel = "shared"
	IsolationPublic IsolationLevel = "public"
)

// DataClassification defines data sensitivity levels
type DataClassification string

const (
	ClassificationPublic       DataClassification = "public"
	ClassificationInternal     DataClassification = "internal"
	ClassificationConfidential DataClassification = "confidential"
	ClassificationRestricted   DataClassification = "restricted"
)

// TenantStatus defines tenant status
type TenantStatus string

const (
	TenantStatusActive    TenantStatus = "active"
	TenantStatusSuspended TenantStatus = "suspended"
	TenantStatusInactive  TenantStatus = "inactive"
)

// PIIRedactionLevel defines PII redaction strictness
type PIIRedactionLevel string

const (
	PIIRedactionStrict   PIIRedactionLevel = "strict"
	PIIRedactionModerate PIIRedactionLevel = "moderate"
	PIIRedactionMinimal  PIIRedactionLevel = "minimal"
	PIIRedactionNone     PIIRedactionLevel = "none"
)

// Tenant represents a customer/organization (Mandant)
type Tenant struct {
	ID              uuid.UUID      `json:"id" db:"id"`
	Name            string         `json:"name" db:"name"`
	Slug            string         `json:"slug" db:"slug"`
	Settings        map[string]any `json:"settings" db:"settings"`
	MaxUsers        int            `json:"max_users" db:"max_users"`
	LLMQuotaMonthly int            `json:"llm_quota_monthly" db:"llm_quota_monthly"`
	Status          TenantStatus   `json:"status" db:"status"`
	CreatedAt       time.Time      `json:"created_at" db:"created_at"`
	UpdatedAt       time.Time      `json:"updated_at" db:"updated_at"`
}

// Namespace represents a department/division within a tenant (z.B. Finance, HR, IT)
type Namespace struct {
	ID                uuid.UUID          `json:"id" db:"id"`
	TenantID          uuid.UUID          `json:"tenant_id" db:"tenant_id"`
	Name              string             `json:"name" db:"name"`
	Slug              string             `json:"slug" db:"slug"`
	ParentNamespaceID *uuid.UUID         `json:"parent_namespace_id,omitempty" db:"parent_namespace_id"`
	IsolationLevel    IsolationLevel     `json:"isolation_level" db:"isolation_level"`
	DataClassification DataClassification `json:"data_classification" db:"data_classification"`
	Metadata          map[string]any     `json:"metadata,omitempty" db:"metadata"`
	CreatedAt         time.Time          `json:"created_at" db:"created_at"`
	UpdatedAt         time.Time          `json:"updated_at" db:"updated_at"`
}

// Role defines a set of permissions
type Role struct {
	ID             uuid.UUID  `json:"id" db:"id"`
	TenantID       *uuid.UUID `json:"tenant_id,omitempty" db:"tenant_id"` // nil for system roles
	Name           string     `json:"name" db:"name"`
	Description    string     `json:"description,omitempty" db:"description"`
	Permissions    []string   `json:"permissions" db:"permissions"`
	IsSystemRole   bool       `json:"is_system_role" db:"is_system_role"`
	HierarchyLevel int        `json:"hierarchy_level" db:"hierarchy_level"`
	CreatedAt      time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt      time.Time  `json:"updated_at" db:"updated_at"`
}

// UserRole represents a user's role assignment with optional namespace scope
type UserRole struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	UserID      uuid.UUID  `json:"user_id" db:"user_id"`
	RoleID      uuid.UUID  `json:"role_id" db:"role_id"`
	TenantID    uuid.UUID  `json:"tenant_id" db:"tenant_id"`
	NamespaceID *uuid.UUID `json:"namespace_id,omitempty" db:"namespace_id"` // nil = tenant-wide
	GrantedBy   uuid.UUID  `json:"granted_by" db:"granted_by"`
	ExpiresAt   *time.Time `json:"expires_at,omitempty" db:"expires_at"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`

	// Joined fields (populated by queries)
	RoleName        string   `json:"role_name,omitempty" db:"role_name"`
	RolePermissions []string `json:"role_permissions,omitempty" db:"role_permissions"`
	NamespaceName   string   `json:"namespace_name,omitempty" db:"namespace_name"`
}

// LLMPolicy defines access controls for LLM operations
type LLMPolicy struct {
	ID                    uuid.UUID         `json:"id" db:"id"`
	TenantID              uuid.UUID         `json:"tenant_id" db:"tenant_id"`
	NamespaceID           *uuid.UUID        `json:"namespace_id,omitempty" db:"namespace_id"`
	Name                  string            `json:"name" db:"name"`
	Description           string            `json:"description,omitempty" db:"description"`
	AllowedDataCategories []string          `json:"allowed_data_categories" db:"allowed_data_categories"`
	BlockedDataCategories []string          `json:"blocked_data_categories" db:"blocked_data_categories"`
	RequirePIIRedaction   bool              `json:"require_pii_redaction" db:"require_pii_redaction"`
	PIIRedactionLevel     PIIRedactionLevel `json:"pii_redaction_level" db:"pii_redaction_level"`
	AllowedModels         []string          `json:"allowed_models" db:"allowed_models"`
	MaxTokensPerRequest   int               `json:"max_tokens_per_request" db:"max_tokens_per_request"`
	MaxRequestsPerDay     int               `json:"max_requests_per_day" db:"max_requests_per_day"`
	MaxRequestsPerHour    int               `json:"max_requests_per_hour" db:"max_requests_per_hour"`
	IsActive              bool              `json:"is_active" db:"is_active"`
	Priority              int               `json:"priority" db:"priority"`
	CreatedAt             time.Time         `json:"created_at" db:"created_at"`
	UpdatedAt             time.Time         `json:"updated_at" db:"updated_at"`
}

// APIKey represents an API key for SDK access
type APIKey struct {
	ID                   uuid.UUID   `json:"id" db:"id"`
	TenantID             uuid.UUID   `json:"tenant_id" db:"tenant_id"`
	Name                 string      `json:"name" db:"name"`
	KeyHash              string      `json:"-" db:"key_hash"` // Never expose
	KeyPrefix            string      `json:"key_prefix" db:"key_prefix"`
	Permissions          []string    `json:"permissions" db:"permissions"`
	NamespaceRestrictions []uuid.UUID `json:"namespace_restrictions,omitempty" db:"namespace_restrictions"`
	RateLimitPerHour     int         `json:"rate_limit_per_hour" db:"rate_limit_per_hour"`
	ExpiresAt            *time.Time  `json:"expires_at,omitempty" db:"expires_at"`
	LastUsedAt           *time.Time  `json:"last_used_at,omitempty" db:"last_used_at"`
	IsActive             bool        `json:"is_active" db:"is_active"`
	CreatedBy            uuid.UUID   `json:"created_by" db:"created_by"`
	CreatedAt            time.Time   `json:"created_at" db:"created_at"`
}

// EffectivePermissions represents a user's computed permissions
type EffectivePermissions struct {
	UserID      uuid.UUID            `json:"user_id"`
	TenantID    uuid.UUID            `json:"tenant_id"`
	NamespaceID *uuid.UUID           `json:"namespace_id,omitempty"`
	Permissions []string             `json:"permissions"`
	Roles       []string             `json:"roles"`
	LLMPolicy   *LLMPolicy           `json:"llm_policy,omitempty"`
	Namespaces  []NamespaceAccess    `json:"namespaces,omitempty"`
}

// NamespaceAccess represents a user's access to a namespace
type NamespaceAccess struct {
	NamespaceID        uuid.UUID          `json:"namespace_id"`
	NamespaceName      string             `json:"namespace_name"`
	NamespaceSlug      string             `json:"namespace_slug"`
	DataClassification DataClassification `json:"data_classification"`
	Roles              []string           `json:"roles"`
	Permissions        []string           `json:"permissions"`
}

// System role names (predefined)
const (
	RoleComplianceExecutive      = "compliance_executive"
	RoleComplianceOfficer        = "compliance_officer"
	RoleDataProtectionOfficer    = "data_protection_officer"
	RoleNamespaceAdmin           = "namespace_admin"
	RoleAuditor                  = "auditor"
	RoleComplianceUser           = "compliance_user"
)

// Common permission patterns
const (
	PermissionComplianceAll      = "compliance:*"
	PermissionComplianceRead     = "compliance:read"
	PermissionComplianceWrite    = "compliance:write"
	PermissionComplianceOwnRead  = "compliance:own:read"
	PermissionAuditAll           = "audit:*"
	PermissionAuditRead          = "audit:read"
	PermissionAuditLogRead       = "audit:log:read"
	PermissionLLMAll             = "llm:*"
	PermissionLLMQuery           = "llm:query:execute"
	PermissionLLMOwnQuery        = "llm:own:query"
	PermissionNamespaceRead      = "namespace:read"
	PermissionNamespaceOwnAdmin  = "namespace:own:admin"
)

// Data categories for LLM access control
const (
	DataCategorySalary    = "salary"
	DataCategoryHealth    = "health"
	DataCategoryPersonal  = "personal"
	DataCategoryFinancial = "financial"
	DataCategoryLegal     = "legal"
	DataCategoryHR        = "hr"
)
