package models

import (
	"time"

	"github.com/google/uuid"
)

// User represents a user with full authentication support
type User struct {
	ID                  uuid.UUID  `json:"id" db:"id"`
	ExternalID          *string    `json:"external_id,omitempty" db:"external_id"`
	Email               string     `json:"email" db:"email"`
	PasswordHash        *string    `json:"-" db:"password_hash"` // Never exposed in JSON
	Name                *string    `json:"name,omitempty" db:"name"`
	Role                string     `json:"role" db:"role"` // 'user', 'admin', 'super_admin', 'data_protection_officer'
	EmailVerified       bool       `json:"email_verified" db:"email_verified"`
	EmailVerifiedAt     *time.Time `json:"email_verified_at,omitempty" db:"email_verified_at"`
	AccountStatus       string     `json:"account_status" db:"account_status"` // 'active', 'suspended', 'locked'
	LastLoginAt         *time.Time `json:"last_login_at,omitempty" db:"last_login_at"`
	FailedLoginAttempts int        `json:"failed_login_attempts" db:"failed_login_attempts"`
	LockedUntil         *time.Time `json:"locked_until,omitempty" db:"locked_until"`
	CreatedAt           time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt           time.Time  `json:"updated_at" db:"updated_at"`
}

// LegalDocument represents a type of legal document (e.g., Terms, Privacy Policy)
type LegalDocument struct {
	ID          uuid.UUID `json:"id" db:"id"`
	Type        string    `json:"type" db:"type"` // 'terms', 'privacy', 'cookies', 'community'
	Name        string    `json:"name" db:"name"`
	Description *string   `json:"description" db:"description"`
	IsMandatory bool      `json:"is_mandatory" db:"is_mandatory"`
	IsActive    bool      `json:"is_active" db:"is_active"`
	SortOrder   int       `json:"sort_order" db:"sort_order"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
}

// DocumentVersion represents a specific version of a legal document
type DocumentVersion struct {
	ID                 uuid.UUID  `json:"id" db:"id"`
	DocumentID         uuid.UUID  `json:"document_id" db:"document_id"`
	Version            string     `json:"version" db:"version"` // Semver: 1.0.0, 1.1.0
	Language           string     `json:"language" db:"language"` // ISO 639-1: de, en
	Title              string     `json:"title" db:"title"`
	Content            string     `json:"content" db:"content"` // HTML or Markdown
	Summary            *string    `json:"summary" db:"summary"` // Summary of changes
	Status             string     `json:"status" db:"status"`   // 'draft', 'review', 'approved', 'scheduled', 'published', 'archived'
	PublishedAt        *time.Time `json:"published_at" db:"published_at"`
	ScheduledPublishAt *time.Time `json:"scheduled_publish_at" db:"scheduled_publish_at"`
	CreatedBy          *uuid.UUID `json:"created_by" db:"created_by"`
	ApprovedBy         *uuid.UUID `json:"approved_by" db:"approved_by"`
	ApprovedAt         *time.Time `json:"approved_at" db:"approved_at"`
	CreatedAt          time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt          time.Time  `json:"updated_at" db:"updated_at"`
}

// UserConsent represents a user's consent to a document version
type UserConsent struct {
	ID                uuid.UUID  `json:"id" db:"id"`
	UserID            uuid.UUID  `json:"user_id" db:"user_id"`
	DocumentVersionID uuid.UUID  `json:"document_version_id" db:"document_version_id"`
	Consented         bool       `json:"consented" db:"consented"`
	IPAddress         *string    `json:"ip_address" db:"ip_address"`
	UserAgent         *string    `json:"user_agent" db:"user_agent"`
	ConsentedAt       time.Time  `json:"consented_at" db:"consented_at"`
	WithdrawnAt       *time.Time `json:"withdrawn_at" db:"withdrawn_at"`
}

// CookieCategory represents a category of cookies
type CookieCategory struct {
	ID            uuid.UUID `json:"id" db:"id"`
	Name          string    `json:"name" db:"name"` // 'necessary', 'functional', 'analytics', 'marketing'
	DisplayNameDE string    `json:"display_name_de" db:"display_name_de"`
	DisplayNameEN *string   `json:"display_name_en" db:"display_name_en"`
	DescriptionDE *string   `json:"description_de" db:"description_de"`
	DescriptionEN *string   `json:"description_en" db:"description_en"`
	IsMandatory   bool      `json:"is_mandatory" db:"is_mandatory"`
	SortOrder     int       `json:"sort_order" db:"sort_order"`
	IsActive      bool      `json:"is_active" db:"is_active"`
	CreatedAt     time.Time `json:"created_at" db:"created_at"`
	UpdatedAt     time.Time `json:"updated_at" db:"updated_at"`
}

// CookieConsent represents a user's cookie preferences
type CookieConsent struct {
	ID         uuid.UUID `json:"id" db:"id"`
	UserID     uuid.UUID `json:"user_id" db:"user_id"`
	CategoryID uuid.UUID `json:"category_id" db:"category_id"`
	Consented  bool      `json:"consented" db:"consented"`
	ConsentedAt time.Time `json:"consented_at" db:"consented_at"`
	UpdatedAt  time.Time `json:"updated_at" db:"updated_at"`
}

// AuditLog represents an audit trail entry for GDPR compliance
type AuditLog struct {
	ID         uuid.UUID  `json:"id" db:"id"`
	UserID     *uuid.UUID `json:"user_id" db:"user_id"`
	Action     string     `json:"action" db:"action"` // 'consent_given', 'consent_withdrawn', 'data_export', 'data_delete'
	EntityType *string    `json:"entity_type" db:"entity_type"` // 'document', 'cookie_category'
	EntityID   *uuid.UUID `json:"entity_id" db:"entity_id"`
	Details    *string    `json:"details" db:"details"` // JSON string
	IPAddress  *string    `json:"ip_address" db:"ip_address"`
	UserAgent  *string    `json:"user_agent" db:"user_agent"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
}

// DataExportRequest represents a user's request to export their data
type DataExportRequest struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	UserID      uuid.UUID  `json:"user_id" db:"user_id"`
	Status      string     `json:"status" db:"status"` // 'pending', 'processing', 'completed', 'failed'
	DownloadURL *string    `json:"download_url" db:"download_url"`
	ExpiresAt   *time.Time `json:"expires_at" db:"expires_at"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
	CompletedAt *time.Time `json:"completed_at" db:"completed_at"`
}

// DataDeletionRequest represents a user's request to delete their data
type DataDeletionRequest struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	UserID       uuid.UUID  `json:"user_id" db:"user_id"`
	Status       string     `json:"status" db:"status"` // 'pending', 'processing', 'completed', 'failed'
	Reason       *string    `json:"reason" db:"reason"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	ProcessedAt  *time.Time `json:"processed_at" db:"processed_at"`
	ProcessedBy  *uuid.UUID `json:"processed_by" db:"processed_by"`
}

// ========================================
// DTOs (Data Transfer Objects)
// ========================================

// CreateConsentRequest is the request body for creating a consent
type CreateConsentRequest struct {
	DocumentType string `json:"document_type" binding:"required"`
	VersionID    string `json:"version_id" binding:"required"`
	Consented    bool   `json:"consented"`
}

// CookieConsentRequest is the request body for setting cookie preferences
type CookieConsentRequest struct {
	Categories []CookieCategoryConsent `json:"categories" binding:"required"`
}

// CookieCategoryConsent represents consent for a single cookie category
type CookieCategoryConsent struct {
	CategoryID string `json:"category_id" binding:"required"`
	Consented  bool   `json:"consented"`
}

// ConsentCheckResponse is the response for checking consent status
type ConsentCheckResponse struct {
	HasConsent        bool       `json:"has_consent"`
	CurrentVersionID  *string    `json:"current_version_id,omitempty"`
	ConsentedVersion  *string    `json:"consented_version,omitempty"`
	NeedsUpdate       bool       `json:"needs_update"`
	ConsentedAt       *time.Time `json:"consented_at,omitempty"`
}

// DocumentWithVersion combines document info with its latest published version
type DocumentWithVersion struct {
	Document      LegalDocument   `json:"document"`
	LatestVersion *DocumentVersion `json:"latest_version,omitempty"`
}

// ConsentHistory represents a user's consent history for a document
type ConsentHistory struct {
	Document       LegalDocument   `json:"document"`
	Version        DocumentVersion `json:"version"`
	Consent        UserConsent     `json:"consent"`
}

// ConsentStats represents statistics about consents
type ConsentStats struct {
	TotalUsers        int     `json:"total_users"`
	ConsentedUsers    int     `json:"consented_users"`
	ConsentRate       float64 `json:"consent_rate"`
	RecentConsents    int     `json:"recent_consents"` // Last 7 days
	RecentWithdrawals int     `json:"recent_withdrawals"`
}

// CookieStats represents statistics about cookie consents
type CookieStats struct {
	Category       string  `json:"category"`
	TotalUsers     int     `json:"total_users"`
	ConsentedUsers int     `json:"consented_users"`
	ConsentRate    float64 `json:"consent_rate"`
}

// MyDataResponse represents all data we have about a user
type MyDataResponse struct {
	User           User            `json:"user"`
	Consents       []ConsentHistory `json:"consents"`
	CookieConsents []CookieConsent  `json:"cookie_consents"`
	AuditLog       []AuditLog       `json:"audit_log"`
	ExportedAt     time.Time        `json:"exported_at"`
}

// CreateDocumentRequest is the request body for creating a document
type CreateDocumentRequest struct {
	Type        string  `json:"type" binding:"required"`
	Name        string  `json:"name" binding:"required"`
	Description *string `json:"description"`
	IsMandatory bool    `json:"is_mandatory"`
}

// CreateVersionRequest is the request body for creating a document version
type CreateVersionRequest struct {
	DocumentID string  `json:"document_id" binding:"required"`
	Version    string  `json:"version" binding:"required"`
	Language   string  `json:"language" binding:"required"`
	Title      string  `json:"title" binding:"required"`
	Content    string  `json:"content" binding:"required"`
	Summary    *string `json:"summary"`
}

// UpdateVersionRequest is the request body for updating a version
type UpdateVersionRequest struct {
	Title   *string `json:"title"`
	Content *string `json:"content"`
	Summary *string `json:"summary"`
	Status  *string `json:"status"`
}

// CreateCookieCategoryRequest is the request body for creating a cookie category
type CreateCookieCategoryRequest struct {
	Name          string  `json:"name" binding:"required"`
	DisplayNameDE string  `json:"display_name_de" binding:"required"`
	DisplayNameEN *string `json:"display_name_en"`
	DescriptionDE *string `json:"description_de"`
	DescriptionEN *string `json:"description_en"`
	IsMandatory   bool    `json:"is_mandatory"`
	SortOrder     int     `json:"sort_order"`
}

// ========================================
// Phase 1: Authentication Models
// ========================================

// EmailVerificationToken for email verification
type EmailVerificationToken struct {
	ID        uuid.UUID  `json:"id" db:"id"`
	UserID    uuid.UUID  `json:"user_id" db:"user_id"`
	Token     string     `json:"token" db:"token"`
	ExpiresAt time.Time  `json:"expires_at" db:"expires_at"`
	UsedAt    *time.Time `json:"used_at,omitempty" db:"used_at"`
	CreatedAt time.Time  `json:"created_at" db:"created_at"`
}

// PasswordResetToken for password reset
type PasswordResetToken struct {
	ID        uuid.UUID  `json:"id" db:"id"`
	UserID    uuid.UUID  `json:"user_id" db:"user_id"`
	Token     string     `json:"token" db:"token"`
	ExpiresAt time.Time  `json:"expires_at" db:"expires_at"`
	UsedAt    *time.Time `json:"used_at,omitempty" db:"used_at"`
	IPAddress *string    `json:"ip_address,omitempty" db:"ip_address"`
	CreatedAt time.Time  `json:"created_at" db:"created_at"`
}

// UserSession for session management
type UserSession struct {
	ID             uuid.UUID  `json:"id" db:"id"`
	UserID         uuid.UUID  `json:"user_id" db:"user_id"`
	TokenHash      string     `json:"-" db:"token_hash"`
	DeviceInfo     *string    `json:"device_info,omitempty" db:"device_info"`
	IPAddress      *string    `json:"ip_address,omitempty" db:"ip_address"`
	UserAgent      *string    `json:"user_agent,omitempty" db:"user_agent"`
	ExpiresAt      time.Time  `json:"expires_at" db:"expires_at"`
	RevokedAt      *time.Time `json:"revoked_at,omitempty" db:"revoked_at"`
	CreatedAt      time.Time  `json:"created_at" db:"created_at"`
	LastActivityAt time.Time  `json:"last_activity_at" db:"last_activity_at"`
}

// RegisterRequest for user registration
type RegisterRequest struct {
	Email    string  `json:"email" binding:"required,email"`
	Password string  `json:"password" binding:"required,min=8"`
	Name     *string `json:"name"`
}

// LoginRequest for user login
type LoginRequest struct {
	Email    string `json:"email" binding:"required,email"`
	Password string `json:"password" binding:"required"`
}

// LoginResponse after successful login
type LoginResponse struct {
	User         User   `json:"user"`
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int    `json:"expires_in"` // seconds
}

// RefreshTokenRequest for token refresh
type RefreshTokenRequest struct {
	RefreshToken string `json:"refresh_token" binding:"required"`
}

// VerifyEmailRequest for email verification
type VerifyEmailRequest struct {
	Token string `json:"token" binding:"required"`
}

// ForgotPasswordRequest for password reset request
type ForgotPasswordRequest struct {
	Email string `json:"email" binding:"required,email"`
}

// ResetPasswordRequest for password reset
type ResetPasswordRequest struct {
	Token       string `json:"token" binding:"required"`
	NewPassword string `json:"new_password" binding:"required,min=8"`
}

// ChangePasswordRequest for changing password
type ChangePasswordRequest struct {
	CurrentPassword string `json:"current_password" binding:"required"`
	NewPassword     string `json:"new_password" binding:"required,min=8"`
}

// UpdateProfileRequest for profile updates
type UpdateProfileRequest struct {
	Name *string `json:"name"`
}

// ========================================
// Phase 3: Version Approval Models
// ========================================

// VersionApproval tracks the approval workflow
type VersionApproval struct {
	ID         uuid.UUID `json:"id" db:"id"`
	VersionID  uuid.UUID `json:"version_id" db:"version_id"`
	ApproverID uuid.UUID `json:"approver_id" db:"approver_id"`
	Action     string    `json:"action" db:"action"` // 'submitted_for_review', 'approved', 'rejected', 'published'
	Comment    *string   `json:"comment,omitempty" db:"comment"`
	CreatedAt  time.Time `json:"created_at" db:"created_at"`
}

// SubmitForReviewRequest for submitting a version for review
type SubmitForReviewRequest struct {
	Comment *string `json:"comment"`
}

// ApproveVersionRequest for approving a version (DSB)
type ApproveVersionRequest struct {
	Comment            *string `json:"comment"`
	ScheduledPublishAt *string `json:"scheduled_publish_at"` // ISO 8601 datetime for scheduled publishing
}

// RejectVersionRequest for rejecting a version
type RejectVersionRequest struct {
	Comment string `json:"comment" binding:"required"`
}

// VersionCompareResponse for comparing versions
type VersionCompareResponse struct {
	Published *DocumentVersion `json:"published,omitempty"`
	Draft     *DocumentVersion `json:"draft"`
	Diff      *string          `json:"diff,omitempty"`
	Approvals []VersionApproval `json:"approvals"`
}

// ========================================
// Phase 4: Notification Models
// ========================================

// Notification represents a user notification
type Notification struct {
	ID        uuid.UUID  `json:"id" db:"id"`
	UserID    uuid.UUID  `json:"user_id" db:"user_id"`
	Type      string     `json:"type" db:"type"`    // 'new_version', 'consent_reminder', 'account_warning'
	Channel   string     `json:"channel" db:"channel"` // 'email', 'in_app', 'push'
	Title     string     `json:"title" db:"title"`
	Body      string     `json:"body" db:"body"`
	Data      *string    `json:"data,omitempty" db:"data"` // JSON string
	ReadAt    *time.Time `json:"read_at,omitempty" db:"read_at"`
	SentAt    *time.Time `json:"sent_at,omitempty" db:"sent_at"`
	CreatedAt time.Time  `json:"created_at" db:"created_at"`
}

// PushSubscription for Web Push notifications
type PushSubscription struct {
	ID        uuid.UUID `json:"id" db:"id"`
	UserID    uuid.UUID `json:"user_id" db:"user_id"`
	Endpoint  string    `json:"endpoint" db:"endpoint"`
	P256dh    string    `json:"p256dh" db:"p256dh"`
	Auth      string    `json:"auth" db:"auth"`
	UserAgent *string   `json:"user_agent,omitempty" db:"user_agent"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// NotificationPreferences for user notification settings
type NotificationPreferences struct {
	ID                uuid.UUID `json:"id" db:"id"`
	UserID            uuid.UUID `json:"user_id" db:"user_id"`
	EmailEnabled      bool      `json:"email_enabled" db:"email_enabled"`
	PushEnabled       bool      `json:"push_enabled" db:"push_enabled"`
	InAppEnabled      bool      `json:"in_app_enabled" db:"in_app_enabled"`
	ReminderFrequency string    `json:"reminder_frequency" db:"reminder_frequency"` // 'daily', 'weekly', 'never'
	CreatedAt         time.Time `json:"created_at" db:"created_at"`
	UpdatedAt         time.Time `json:"updated_at" db:"updated_at"`
}

// SubscribePushRequest for subscribing to push notifications
type SubscribePushRequest struct {
	Endpoint string `json:"endpoint" binding:"required"`
	P256dh   string `json:"p256dh" binding:"required"`
	Auth     string `json:"auth" binding:"required"`
}

// UpdateNotificationPreferencesRequest for updating preferences
type UpdateNotificationPreferencesRequest struct {
	EmailEnabled      *bool   `json:"email_enabled"`
	PushEnabled       *bool   `json:"push_enabled"`
	InAppEnabled      *bool   `json:"in_app_enabled"`
	ReminderFrequency *string `json:"reminder_frequency"`
}

// ========================================
// Phase 6: OAuth 2.0 Authorization Code Flow
// ========================================

// OAuthClient represents a registered OAuth 2.0 client application
type OAuthClient struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	ClientID     string     `json:"client_id" db:"client_id"`
	ClientSecret string     `json:"-" db:"client_secret"` // Never expose in JSON
	Name         string     `json:"name" db:"name"`
	Description  *string    `json:"description,omitempty" db:"description"`
	RedirectURIs []string   `json:"redirect_uris" db:"redirect_uris"` // JSON array
	Scopes       []string   `json:"scopes" db:"scopes"`               // Allowed scopes
	GrantTypes   []string   `json:"grant_types" db:"grant_types"`     // authorization_code, refresh_token
	IsPublic     bool       `json:"is_public" db:"is_public"`         // Public clients (SPAs) don't have secret
	IsActive     bool       `json:"is_active" db:"is_active"`
	CreatedBy    *uuid.UUID `json:"created_by,omitempty" db:"created_by"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// OAuthAuthorizationCode represents an authorization code for the OAuth flow
type OAuthAuthorizationCode struct {
	ID                  uuid.UUID `json:"id" db:"id"`
	Code                string    `json:"-" db:"code"` // Hashed
	ClientID            string    `json:"client_id" db:"client_id"`
	UserID              uuid.UUID `json:"user_id" db:"user_id"`
	RedirectURI         string    `json:"redirect_uri" db:"redirect_uri"`
	Scopes              []string  `json:"scopes" db:"scopes"`
	CodeChallenge       *string   `json:"-" db:"code_challenge"`        // For PKCE
	CodeChallengeMethod *string   `json:"-" db:"code_challenge_method"` // S256 or plain
	ExpiresAt           time.Time `json:"expires_at" db:"expires_at"`
	UsedAt              *time.Time `json:"used_at,omitempty" db:"used_at"`
	CreatedAt           time.Time `json:"created_at" db:"created_at"`
}

// OAuthAccessToken represents an OAuth access token
type OAuthAccessToken struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	TokenHash   string     `json:"-" db:"token_hash"`
	ClientID    string     `json:"client_id" db:"client_id"`
	UserID      uuid.UUID  `json:"user_id" db:"user_id"`
	Scopes      []string   `json:"scopes" db:"scopes"`
	ExpiresAt   time.Time  `json:"expires_at" db:"expires_at"`
	RevokedAt   *time.Time `json:"revoked_at,omitempty" db:"revoked_at"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
}

// OAuthRefreshToken represents an OAuth refresh token
type OAuthRefreshToken struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	TokenHash     string     `json:"-" db:"token_hash"`
	AccessTokenID uuid.UUID  `json:"access_token_id" db:"access_token_id"`
	ClientID      string     `json:"client_id" db:"client_id"`
	UserID        uuid.UUID  `json:"user_id" db:"user_id"`
	Scopes        []string   `json:"scopes" db:"scopes"`
	ExpiresAt     time.Time  `json:"expires_at" db:"expires_at"`
	RevokedAt     *time.Time `json:"revoked_at,omitempty" db:"revoked_at"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
}

// OAuthAuthorizeRequest for the authorization endpoint
type OAuthAuthorizeRequest struct {
	ResponseType        string `form:"response_type" binding:"required"` // Must be "code"
	ClientID            string `form:"client_id" binding:"required"`
	RedirectURI         string `form:"redirect_uri" binding:"required"`
	Scope               string `form:"scope"`                                   // Space-separated scopes
	State               string `form:"state" binding:"required"`                // CSRF protection
	CodeChallenge       string `form:"code_challenge"`                          // PKCE
	CodeChallengeMethod string `form:"code_challenge_method"`                   // S256 (recommended) or plain
}

// OAuthTokenRequest for the token endpoint
type OAuthTokenRequest struct {
	GrantType    string `form:"grant_type" binding:"required"` // authorization_code or refresh_token
	Code         string `form:"code"`                          // For authorization_code grant
	RedirectURI  string `form:"redirect_uri"`                  // For authorization_code grant
	ClientID     string `form:"client_id" binding:"required"`
	ClientSecret string `form:"client_secret"`                 // For confidential clients
	CodeVerifier string `form:"code_verifier"`                 // For PKCE
	RefreshToken string `form:"refresh_token"`                 // For refresh_token grant
	Scope        string `form:"scope"`                         // For refresh_token grant (optional)
}

// OAuthTokenResponse for successful token requests
type OAuthTokenResponse struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"` // Always "Bearer"
	ExpiresIn    int    `json:"expires_in"` // Seconds until expiration
	RefreshToken string `json:"refresh_token,omitempty"`
	Scope        string `json:"scope,omitempty"`
}

// OAuthErrorResponse for OAuth errors (RFC 6749)
type OAuthErrorResponse struct {
	Error            string `json:"error"`
	ErrorDescription string `json:"error_description,omitempty"`
	ErrorURI         string `json:"error_uri,omitempty"`
}

// ========================================
// Phase 7: Two-Factor Authentication (2FA/TOTP)
// ========================================

// UserTOTP stores 2FA TOTP configuration for a user
type UserTOTP struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	UserID        uuid.UUID  `json:"user_id" db:"user_id"`
	Secret        string     `json:"-" db:"secret"`              // Encrypted TOTP secret
	Verified      bool       `json:"verified" db:"verified"`     // Has 2FA been verified/activated
	RecoveryCodes []string   `json:"-" db:"recovery_codes"`      // Encrypted backup codes
	EnabledAt     *time.Time `json:"enabled_at,omitempty" db:"enabled_at"`
	LastUsedAt    *time.Time `json:"last_used_at,omitempty" db:"last_used_at"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt     time.Time  `json:"updated_at" db:"updated_at"`
}

// TwoFactorChallenge represents a pending 2FA challenge during login
type TwoFactorChallenge struct {
	ID          uuid.UUID `json:"id" db:"id"`
	UserID      uuid.UUID `json:"user_id" db:"user_id"`
	ChallengeID string    `json:"challenge_id" db:"challenge_id"` // Temporary token
	IPAddress   *string   `json:"ip_address,omitempty" db:"ip_address"`
	UserAgent   *string   `json:"user_agent,omitempty" db:"user_agent"`
	ExpiresAt   time.Time `json:"expires_at" db:"expires_at"`
	UsedAt      *time.Time `json:"used_at,omitempty" db:"used_at"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
}

// Setup2FAResponse when initiating 2FA setup
type Setup2FAResponse struct {
	Secret        string   `json:"secret"`         // Base32 encoded secret for manual entry
	QRCodeDataURL string   `json:"qr_code"`        // Data URL for QR code image
	RecoveryCodes []string `json:"recovery_codes"` // One-time backup codes
}

// Verify2FARequest for verifying 2FA setup or login
type Verify2FARequest struct {
	Code        string `json:"code" binding:"required"` // 6-digit TOTP code
	ChallengeID string `json:"challenge_id,omitempty"`  // For login flow
}

// TwoFactorLoginResponse when 2FA is required during login
type TwoFactorLoginResponse struct {
	RequiresTwoFactor bool   `json:"requires_two_factor"`
	ChallengeID       string `json:"challenge_id"` // Use this to complete 2FA
	Message           string `json:"message"`
}

// Complete2FALoginRequest to complete login with 2FA
type Complete2FALoginRequest struct {
	ChallengeID string `json:"challenge_id" binding:"required"`
	Code        string `json:"code" binding:"required"` // 6-digit TOTP or recovery code
}

// Disable2FARequest for disabling 2FA
type Disable2FARequest struct {
	Password string `json:"password" binding:"required"` // Require password confirmation
	Code     string `json:"code" binding:"required"`     // Current TOTP code
}

// RecoveryCodeUseRequest for using a recovery code
type RecoveryCodeUseRequest struct {
	ChallengeID  string `json:"challenge_id" binding:"required"`
	RecoveryCode string `json:"recovery_code" binding:"required"`
}

// TwoFactorStatusResponse for checking 2FA status
type TwoFactorStatusResponse struct {
	Enabled            bool       `json:"enabled"`
	Verified           bool       `json:"verified"`
	EnabledAt          *time.Time `json:"enabled_at,omitempty"`
	RecoveryCodesCount int        `json:"recovery_codes_count"`
}

// Verify2FAChallengeRequest for verifying a 2FA challenge during login
type Verify2FAChallengeRequest struct {
	ChallengeID  string `json:"challenge_id" binding:"required"`
	Code         string `json:"code,omitempty"`          // 6-digit TOTP code
	RecoveryCode string `json:"recovery_code,omitempty"` // Alternative: recovery code
}

// ========================================
// Phase 5: Consent Deadline Models
// ========================================

// ConsentDeadline tracks consent deadlines per user
type ConsentDeadline struct {
	ID                uuid.UUID  `json:"id" db:"id"`
	UserID            uuid.UUID  `json:"user_id" db:"user_id"`
	DocumentVersionID uuid.UUID  `json:"document_version_id" db:"document_version_id"`
	DeadlineAt        time.Time  `json:"deadline_at" db:"deadline_at"`
	ReminderCount     int        `json:"reminder_count" db:"reminder_count"`
	LastReminderAt    *time.Time `json:"last_reminder_at,omitempty" db:"last_reminder_at"`
	ConsentGivenAt    *time.Time `json:"consent_given_at,omitempty" db:"consent_given_at"`
	CreatedAt         time.Time  `json:"created_at" db:"created_at"`
}

// AccountSuspension tracks account suspensions
type AccountSuspension struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	UserID       uuid.UUID  `json:"user_id" db:"user_id"`
	Reason       string     `json:"reason" db:"reason"` // 'consent_deadline_exceeded'
	Details      *string    `json:"details,omitempty" db:"details"` // JSON
	SuspendedAt  time.Time  `json:"suspended_at" db:"suspended_at"`
	LiftedAt     *time.Time `json:"lifted_at,omitempty" db:"lifted_at"`
	LiftedReason *string    `json:"lifted_reason,omitempty" db:"lifted_reason"`
}

// PendingConsentResponse for pending consents with deadline info
type PendingConsentResponse struct {
	Document    LegalDocument   `json:"document"`
	Version     DocumentVersion `json:"version"`
	DeadlineAt  time.Time       `json:"deadline_at"`
	DaysLeft    int             `json:"days_left"`
	IsOverdue   bool            `json:"is_overdue"`
}

// AccountStatusResponse for account status check
type AccountStatusResponse struct {
	Status           string                   `json:"status"` // 'active', 'suspended'
	PendingConsents  []PendingConsentResponse `json:"pending_consents,omitempty"`
	SuspensionReason *string                  `json:"suspension_reason,omitempty"`
	CanAccess        bool                     `json:"can_access"`
}

// ========================================
// Phase 8: E-Mail Templates (Transactional)
// ========================================

// EmailTemplateType defines the types of transactional emails
// These are like document types but for emails
const (
	// Auth & Security
	EmailTypeWelcome              = "welcome"
	EmailTypeEmailVerification    = "email_verification"
	EmailTypePasswordReset        = "password_reset"
	EmailTypePasswordChanged      = "password_changed"
	EmailType2FAEnabled           = "2fa_enabled"
	EmailType2FADisabled          = "2fa_disabled"
	EmailTypeNewDeviceLogin       = "new_device_login"
	EmailTypeSuspiciousActivity   = "suspicious_activity"
	EmailTypeAccountLocked        = "account_locked"
	EmailTypeAccountUnlocked      = "account_unlocked"

	// Account Lifecycle
	EmailTypeDeletionRequested    = "deletion_requested"
	EmailTypeDeletionConfirmed    = "deletion_confirmed"
	EmailTypeDataExportReady      = "data_export_ready"
	EmailTypeEmailChanged         = "email_changed"
	EmailTypeEmailChangeVerify    = "email_change_verify"

	// Consent-related
	EmailTypeNewVersionPublished  = "new_version_published"
	EmailTypeConsentReminder      = "consent_reminder"
	EmailTypeConsentDeadlineWarning = "consent_deadline_warning"
	EmailTypeAccountSuspended     = "account_suspended"
)

// EmailTemplate represents a template for transactional emails (like LegalDocument)
type EmailTemplate struct {
	ID          uuid.UUID `json:"id" db:"id"`
	Type        string    `json:"type" db:"type"`             // One of EmailType constants
	Name        string    `json:"name" db:"name"`             // Human-readable name
	Description *string   `json:"description" db:"description"`
	IsActive    bool      `json:"is_active" db:"is_active"`
	SortOrder   int       `json:"sort_order" db:"sort_order"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
}

// EmailTemplateVersion represents a specific version of an email template (like DocumentVersion)
type EmailTemplateVersion struct {
	ID                 uuid.UUID  `json:"id" db:"id"`
	TemplateID         uuid.UUID  `json:"template_id" db:"template_id"`
	Version            string     `json:"version" db:"version"`       // Semver: 1.0.0
	Language           string     `json:"language" db:"language"`     // ISO 639-1: de, en
	Subject            string     `json:"subject" db:"subject"`       // Email subject line
	BodyHTML           string     `json:"body_html" db:"body_html"`   // HTML version
	BodyText           string     `json:"body_text" db:"body_text"`   // Plain text version
	Summary            *string    `json:"summary" db:"summary"`       // Change summary
	Status             string     `json:"status" db:"status"`         // draft, review, approved, published, archived
	PublishedAt        *time.Time `json:"published_at" db:"published_at"`
	ScheduledPublishAt *time.Time `json:"scheduled_publish_at" db:"scheduled_publish_at"`
	CreatedBy          *uuid.UUID `json:"created_by" db:"created_by"`
	ApprovedBy         *uuid.UUID `json:"approved_by" db:"approved_by"`
	ApprovedAt         *time.Time `json:"approved_at" db:"approved_at"`
	CreatedAt          time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt          time.Time  `json:"updated_at" db:"updated_at"`
}

// EmailTemplateApproval tracks approval workflow for email templates
type EmailTemplateApproval struct {
	ID         uuid.UUID `json:"id" db:"id"`
	VersionID  uuid.UUID `json:"version_id" db:"version_id"`
	ApproverID uuid.UUID `json:"approver_id" db:"approver_id"`
	Action     string    `json:"action" db:"action"` // submitted_for_review, approved, rejected, published
	Comment    *string   `json:"comment,omitempty" db:"comment"`
	CreatedAt  time.Time `json:"created_at" db:"created_at"`
}

// EmailSendLog tracks sent emails for audit purposes
type EmailSendLog struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	UserID      *uuid.UUID `json:"user_id,omitempty" db:"user_id"`
	VersionID   uuid.UUID  `json:"version_id" db:"version_id"`
	Recipient   string     `json:"recipient" db:"recipient"` // Email address
	Subject     string     `json:"subject" db:"subject"`
	Status      string     `json:"status" db:"status"` // queued, sent, delivered, bounced, failed
	ErrorMsg    *string    `json:"error_msg,omitempty" db:"error_msg"`
	Variables   *string    `json:"variables,omitempty" db:"variables"` // JSON of template variables used
	SentAt      *time.Time `json:"sent_at,omitempty" db:"sent_at"`
	DeliveredAt *time.Time `json:"delivered_at,omitempty" db:"delivered_at"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
}

// EmailTemplateSettings stores global email settings (logo, signature, etc.)
type EmailTemplateSettings struct {
	ID             uuid.UUID  `json:"id" db:"id"`
	LogoURL        *string    `json:"logo_url" db:"logo_url"`
	LogoBase64     *string    `json:"logo_base64" db:"logo_base64"` // For embedding in emails
	CompanyName    string     `json:"company_name" db:"company_name"`
	SenderName     string     `json:"sender_name" db:"sender_name"`
	SenderEmail    string     `json:"sender_email" db:"sender_email"`
	ReplyToEmail   *string    `json:"reply_to_email" db:"reply_to_email"`
	FooterHTML     *string    `json:"footer_html" db:"footer_html"`
	FooterText     *string    `json:"footer_text" db:"footer_text"`
	PrimaryColor   string     `json:"primary_color" db:"primary_color"`     // Hex color
	SecondaryColor string     `json:"secondary_color" db:"secondary_color"` // Hex color
	UpdatedAt      time.Time  `json:"updated_at" db:"updated_at"`
	UpdatedBy      *uuid.UUID `json:"updated_by" db:"updated_by"`
}

// ========================================
// E-Mail Template DTOs
// ========================================

// CreateEmailTemplateRequest for creating a new email template type
type CreateEmailTemplateRequest struct {
	Type        string  `json:"type" binding:"required"`
	Name        string  `json:"name" binding:"required"`
	Description *string `json:"description"`
}

// CreateEmailTemplateVersionRequest for creating a new version of an email template
type CreateEmailTemplateVersionRequest struct {
	TemplateID string  `json:"template_id" binding:"required"`
	Version    string  `json:"version" binding:"required"`
	Language   string  `json:"language" binding:"required"`
	Subject    string  `json:"subject" binding:"required"`
	BodyHTML   string  `json:"body_html" binding:"required"`
	BodyText   string  `json:"body_text" binding:"required"`
	Summary    *string `json:"summary"`
}

// UpdateEmailTemplateVersionRequest for updating a version
type UpdateEmailTemplateVersionRequest struct {
	Subject  *string `json:"subject"`
	BodyHTML *string `json:"body_html"`
	BodyText *string `json:"body_text"`
	Summary  *string `json:"summary"`
	Status   *string `json:"status"`
}

// UpdateEmailTemplateSettingsRequest for updating global settings
type UpdateEmailTemplateSettingsRequest struct {
	LogoURL        *string `json:"logo_url"`
	LogoBase64     *string `json:"logo_base64"`
	CompanyName    *string `json:"company_name"`
	SenderName     *string `json:"sender_name"`
	SenderEmail    *string `json:"sender_email"`
	ReplyToEmail   *string `json:"reply_to_email"`
	FooterHTML     *string `json:"footer_html"`
	FooterText     *string `json:"footer_text"`
	PrimaryColor   *string `json:"primary_color"`
	SecondaryColor *string `json:"secondary_color"`
}

// EmailTemplateWithVersion combines template info with its latest published version
type EmailTemplateWithVersion struct {
	Template      EmailTemplate         `json:"template"`
	LatestVersion *EmailTemplateVersion `json:"latest_version,omitempty"`
}

// SendTestEmailRequest for sending a test email
type SendTestEmailRequest struct {
	VersionID string            `json:"version_id" binding:"required"`
	Recipient string            `json:"recipient" binding:"required,email"`
	Variables map[string]string `json:"variables"` // Template variable overrides
}

// EmailPreviewResponse for previewing an email
type EmailPreviewResponse struct {
	Subject  string `json:"subject"`
	BodyHTML string `json:"body_html"`
	BodyText string `json:"body_text"`
}

// EmailTemplateVariables defines available variables for each template type
type EmailTemplateVariables struct {
	TemplateType string   `json:"template_type"`
	Variables    []string `json:"variables"`
	Descriptions map[string]string `json:"descriptions"`
}

// EmailStats represents statistics about email sends
type EmailStats struct {
	TotalSent      int     `json:"total_sent"`
	Delivered      int     `json:"delivered"`
	Bounced        int     `json:"bounced"`
	Failed         int     `json:"failed"`
	DeliveryRate   float64 `json:"delivery_rate"`
	RecentSent     int     `json:"recent_sent"` // Last 7 days
}

// ========================================
// Phase 9: Schulverwaltung / School Management
// Matrix-basierte Kommunikation für Schulen
// ========================================

// SchoolRole defines roles within the school system
const (
	SchoolRoleTeacher       = "teacher"
	SchoolRoleClassTeacher  = "class_teacher"
	SchoolRoleParent        = "parent"
	SchoolRoleParentRep     = "parent_representative"
	SchoolRoleStudent       = "student"
	SchoolRoleAdmin         = "school_admin"
	SchoolRolePrincipal     = "principal"
	SchoolRoleSecretary     = "secretary"
)

// AttendanceStatus defines the status of student attendance
const (
	AttendancePresent           = "present"
	AttendanceAbsent            = "absent"
	AttendanceAbsentExcused     = "excused"
	AttendanceAbsentUnexcused   = "unexcused"
	AttendanceLate              = "late"
	AttendanceLateExcused       = "late_excused"
	AttendancePending           = "pending_confirmation"
)

// School represents a school/educational institution
type School struct {
	ID                 uuid.UUID  `json:"id" db:"id"`
	Name               string     `json:"name" db:"name"`
	ShortName          *string    `json:"short_name,omitempty" db:"short_name"`
	Type               string     `json:"type" db:"type"` // 'grundschule', 'hauptschule', 'realschule', 'gymnasium', 'gesamtschule', 'berufsschule'
	Address            *string    `json:"address,omitempty" db:"address"`
	City               *string    `json:"city,omitempty" db:"city"`
	PostalCode         *string    `json:"postal_code,omitempty" db:"postal_code"`
	State              *string    `json:"state,omitempty" db:"state"` // Bundesland
	Country            string     `json:"country" db:"country"`        // Default: DE
	Phone              *string    `json:"phone,omitempty" db:"phone"`
	Email              *string    `json:"email,omitempty" db:"email"`
	Website            *string    `json:"website,omitempty" db:"website"`
	MatrixServerName   *string    `json:"matrix_server_name,omitempty" db:"matrix_server_name"` // Optional: eigener Matrix-Server
	LogoURL            *string    `json:"logo_url,omitempty" db:"logo_url"`
	IsActive           bool       `json:"is_active" db:"is_active"`
	CreatedAt          time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt          time.Time  `json:"updated_at" db:"updated_at"`
}

// SchoolYear represents an academic year
type SchoolYear struct {
	ID        uuid.UUID  `json:"id" db:"id"`
	SchoolID  uuid.UUID  `json:"school_id" db:"school_id"`
	Name      string     `json:"name" db:"name"` // e.g., "2024/2025"
	StartDate time.Time  `json:"start_date" db:"start_date"`
	EndDate   time.Time  `json:"end_date" db:"end_date"`
	IsCurrent bool       `json:"is_current" db:"is_current"`
	CreatedAt time.Time  `json:"created_at" db:"created_at"`
}

// Class represents a school class
type Class struct {
	ID             uuid.UUID  `json:"id" db:"id"`
	SchoolID       uuid.UUID  `json:"school_id" db:"school_id"`
	SchoolYearID   uuid.UUID  `json:"school_year_id" db:"school_year_id"`
	Name           string     `json:"name" db:"name"`     // e.g., "5a", "10b"
	Grade          int        `json:"grade" db:"grade"`   // Klassenstufe: 1-13
	Section        *string    `json:"section,omitempty" db:"section"` // e.g., "a", "b", "c"
	Room           *string    `json:"room,omitempty" db:"room"` // Klassenzimmer
	MatrixInfoRoom *string    `json:"matrix_info_room,omitempty" db:"matrix_info_room"` // Broadcast-Raum
	MatrixRepRoom  *string    `json:"matrix_rep_room,omitempty" db:"matrix_rep_room"`   // Elternvertreter-Raum
	IsActive       bool       `json:"is_active" db:"is_active"`
	CreatedAt      time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt      time.Time  `json:"updated_at" db:"updated_at"`
}

// Subject represents a school subject
type Subject struct {
	ID          uuid.UUID `json:"id" db:"id"`
	SchoolID    uuid.UUID `json:"school_id" db:"school_id"`
	Name        string    `json:"name" db:"name"`       // e.g., "Mathematik", "Deutsch"
	ShortName   string    `json:"short_name" db:"short_name"` // e.g., "Ma", "De"
	Color       *string   `json:"color,omitempty" db:"color"` // Hex color for display
	IsActive    bool      `json:"is_active" db:"is_active"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
}

// Student represents a student
type Student struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	SchoolID      uuid.UUID  `json:"school_id" db:"school_id"`
	ClassID       uuid.UUID  `json:"class_id" db:"class_id"`
	UserID        *uuid.UUID `json:"user_id,omitempty" db:"user_id"` // Optional: linked account
	StudentNumber *string    `json:"student_number,omitempty" db:"student_number"` // Internal ID
	FirstName     string     `json:"first_name" db:"first_name"`
	LastName      string     `json:"last_name" db:"last_name"`
	DateOfBirth   *time.Time `json:"date_of_birth,omitempty" db:"date_of_birth"`
	Gender        *string    `json:"gender,omitempty" db:"gender"` // 'm', 'f', 'd'
	MatrixUserID  *string    `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
	MatrixDMRoom  *string    `json:"matrix_dm_room,omitempty" db:"matrix_dm_room"` // Kind-Dialograum
	IsActive      bool       `json:"is_active" db:"is_active"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt     time.Time  `json:"updated_at" db:"updated_at"`
}

// Teacher represents a teacher
type Teacher struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	SchoolID     uuid.UUID  `json:"school_id" db:"school_id"`
	UserID       uuid.UUID  `json:"user_id" db:"user_id"` // Linked user account
	TeacherCode  *string    `json:"teacher_code,omitempty" db:"teacher_code"` // e.g., "MÜL" for Müller
	Title        *string    `json:"title,omitempty" db:"title"` // e.g., "Dr.", "StR"
	FirstName    string     `json:"first_name" db:"first_name"`
	LastName     string     `json:"last_name" db:"last_name"`
	MatrixUserID *string    `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
	IsActive     bool       `json:"is_active" db:"is_active"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// ClassTeacher assigns teachers to classes (Klassenlehrer)
type ClassTeacher struct {
	ID        uuid.UUID `json:"id" db:"id"`
	ClassID   uuid.UUID `json:"class_id" db:"class_id"`
	TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
	IsPrimary bool      `json:"is_primary" db:"is_primary"` // Hauptklassenlehrer vs. Stellvertreter
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// TeacherSubject assigns subjects to teachers
type TeacherSubject struct {
	ID        uuid.UUID `json:"id" db:"id"`
	TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
	SubjectID uuid.UUID `json:"subject_id" db:"subject_id"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// Parent represents a parent/guardian
type Parent struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	UserID       uuid.UUID  `json:"user_id" db:"user_id"` // Linked user account
	MatrixUserID *string    `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
	FirstName    string     `json:"first_name" db:"first_name"`
	LastName     string     `json:"last_name" db:"last_name"`
	Phone        *string    `json:"phone,omitempty" db:"phone"`
	EmergencyContact bool   `json:"emergency_contact" db:"emergency_contact"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// StudentParent links students to their parents
type StudentParent struct {
	ID            uuid.UUID `json:"id" db:"id"`
	StudentID     uuid.UUID `json:"student_id" db:"student_id"`
	ParentID      uuid.UUID `json:"parent_id" db:"parent_id"`
	Relationship  string    `json:"relationship" db:"relationship"` // 'mother', 'father', 'guardian', 'other'
	IsPrimary     bool      `json:"is_primary" db:"is_primary"`     // Hauptansprechpartner
	HasCustody    bool      `json:"has_custody" db:"has_custody"`   // Sorgeberechtigt
	CreatedAt     time.Time `json:"created_at" db:"created_at"`
}

// ParentRepresentative assigns parent representatives to classes
type ParentRepresentative struct {
	ID        uuid.UUID `json:"id" db:"id"`
	ClassID   uuid.UUID `json:"class_id" db:"class_id"`
	ParentID  uuid.UUID `json:"parent_id" db:"parent_id"`
	Role      string    `json:"role" db:"role"` // 'first_rep', 'second_rep', 'substitute'
	ElectedAt time.Time `json:"elected_at" db:"elected_at"`
	ExpiresAt *time.Time `json:"expires_at,omitempty" db:"expires_at"`
	IsActive  bool      `json:"is_active" db:"is_active"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// ========================================
// Stundenplan / Timetable
// ========================================

// TimetableSlot represents a time slot in the timetable
type TimetableSlot struct {
	ID        uuid.UUID `json:"id" db:"id"`
	SchoolID  uuid.UUID `json:"school_id" db:"school_id"`
	SlotNumber int      `json:"slot_number" db:"slot_number"` // 1, 2, 3... (Stunde)
	StartTime string    `json:"start_time" db:"start_time"`   // "08:00"
	EndTime   string    `json:"end_time" db:"end_time"`       // "08:45"
	IsBreak   bool      `json:"is_break" db:"is_break"`       // Pause
	Name      *string   `json:"name,omitempty" db:"name"`     // e.g., "1. Stunde", "Große Pause"
}

// TimetableEntry represents a single lesson in the timetable
type TimetableEntry struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	SchoolYearID uuid.UUID  `json:"school_year_id" db:"school_year_id"`
	ClassID      uuid.UUID  `json:"class_id" db:"class_id"`
	SubjectID    uuid.UUID  `json:"subject_id" db:"subject_id"`
	TeacherID    uuid.UUID  `json:"teacher_id" db:"teacher_id"`
	SlotID       uuid.UUID  `json:"slot_id" db:"slot_id"`
	DayOfWeek    int        `json:"day_of_week" db:"day_of_week"` // 1=Monday, 5=Friday
	Room         *string    `json:"room,omitempty" db:"room"`
	ValidFrom    time.Time  `json:"valid_from" db:"valid_from"`
	ValidUntil   *time.Time `json:"valid_until,omitempty" db:"valid_until"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// TimetableSubstitution represents a substitution/replacement lesson
type TimetableSubstitution struct {
	ID              uuid.UUID  `json:"id" db:"id"`
	OriginalEntryID uuid.UUID  `json:"original_entry_id" db:"original_entry_id"`
	Date            time.Time  `json:"date" db:"date"`
	SubstituteTeacherID *uuid.UUID `json:"substitute_teacher_id,omitempty" db:"substitute_teacher_id"`
	SubstituteSubjectID *uuid.UUID `json:"substitute_subject_id,omitempty" db:"substitute_subject_id"`
	Room            *string    `json:"room,omitempty" db:"room"`
	Type            string     `json:"type" db:"type"` // 'substitution', 'cancelled', 'room_change', 'supervision'
	Note            *string    `json:"note,omitempty" db:"note"`
	CreatedAt       time.Time  `json:"created_at" db:"created_at"`
	CreatedBy       uuid.UUID  `json:"created_by" db:"created_by"`
}

// ========================================
// Abwesenheit / Attendance
// ========================================

// AttendanceRecord represents a student's attendance for a specific lesson
type AttendanceRecord struct {
	ID               uuid.UUID  `json:"id" db:"id"`
	StudentID        uuid.UUID  `json:"student_id" db:"student_id"`
	TimetableEntryID *uuid.UUID `json:"timetable_entry_id,omitempty" db:"timetable_entry_id"`
	Date             time.Time  `json:"date" db:"date"`
	SlotID           uuid.UUID  `json:"slot_id" db:"slot_id"`
	Status           string     `json:"status" db:"status"` // AttendanceStatus constants
	RecordedBy       uuid.UUID  `json:"recorded_by" db:"recorded_by"` // Teacher who recorded
	Note             *string    `json:"note,omitempty" db:"note"`
	CreatedAt        time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt        time.Time  `json:"updated_at" db:"updated_at"`
}

// AbsenceReport represents a full absence report (one or more days)
type AbsenceReport struct {
	ID                 uuid.UUID  `json:"id" db:"id"`
	StudentID          uuid.UUID  `json:"student_id" db:"student_id"`
	StartDate          time.Time  `json:"start_date" db:"start_date"`
	EndDate            time.Time  `json:"end_date" db:"end_date"`
	Reason             *string    `json:"reason,omitempty" db:"reason"`
	ReasonCategory     string     `json:"reason_category" db:"reason_category"` // 'illness', 'family', 'appointment', 'other'
	Status             string     `json:"status" db:"status"` // 'reported', 'confirmed', 'excused', 'unexcused'
	ReportedBy         uuid.UUID  `json:"reported_by" db:"reported_by"` // Parent or student
	ReportedAt         time.Time  `json:"reported_at" db:"reported_at"`
	ConfirmedBy        *uuid.UUID `json:"confirmed_by,omitempty" db:"confirmed_by"` // Teacher
	ConfirmedAt        *time.Time `json:"confirmed_at,omitempty" db:"confirmed_at"`
	MedicalCertificate bool       `json:"medical_certificate" db:"medical_certificate"` // Attestpflicht
	CertificateUploaded bool      `json:"certificate_uploaded" db:"certificate_uploaded"`
	MatrixNotificationSent bool   `json:"matrix_notification_sent" db:"matrix_notification_sent"`
	EmailNotificationSent  bool   `json:"email_notification_sent" db:"email_notification_sent"`
	CreatedAt          time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt          time.Time  `json:"updated_at" db:"updated_at"`
}

// AbsenceNotification tracks notifications sent to parents about absences
type AbsenceNotification struct {
	ID                uuid.UUID  `json:"id" db:"id"`
	AttendanceRecordID uuid.UUID `json:"attendance_record_id" db:"attendance_record_id"`
	ParentID          uuid.UUID  `json:"parent_id" db:"parent_id"`
	Channel           string     `json:"channel" db:"channel"` // 'matrix', 'email', 'push'
	MessageContent    string     `json:"message_content" db:"message_content"`
	SentAt            *time.Time `json:"sent_at,omitempty" db:"sent_at"`
	ReadAt            *time.Time `json:"read_at,omitempty" db:"read_at"`
	ResponseReceived  bool       `json:"response_received" db:"response_received"`
	ResponseContent   *string    `json:"response_content,omitempty" db:"response_content"`
	ResponseAt        *time.Time `json:"response_at,omitempty" db:"response_at"`
	CreatedAt         time.Time  `json:"created_at" db:"created_at"`
}

// ========================================
// Notenspiegel / Grades
// ========================================

// GradeType defines the type of grade
const (
	GradeTypeExam         = "exam"           // Klassenarbeit/Klausur
	GradeTypeTest         = "test"           // Test/Kurzarbeit
	GradeTypeOral         = "oral"           // Mündlich
	GradeTypeHomework     = "homework"       // Hausaufgabe
	GradeTypeProject      = "project"        // Projekt
	GradeTypeParticipation = "participation" // Mitarbeit
	GradeTypeSemester     = "semester"       // Halbjahres-/Semesternote
	GradeTypeFinal        = "final"          // Endnote/Zeugnisnote
)

// GradeScale represents the grading scale used
type GradeScale struct {
	ID          uuid.UUID `json:"id" db:"id"`
	SchoolID    uuid.UUID `json:"school_id" db:"school_id"`
	Name        string    `json:"name" db:"name"`     // e.g., "1-6", "Punkte 0-15"
	MinValue    float64   `json:"min_value" db:"min_value"` // e.g., 1 or 0
	MaxValue    float64   `json:"max_value" db:"max_value"` // e.g., 6 or 15
	PassingValue float64  `json:"passing_value" db:"passing_value"` // e.g., 4 or 5
	IsAscending bool      `json:"is_ascending" db:"is_ascending"` // true: higher=better (Punkte), false: lower=better (Noten)
	IsDefault   bool      `json:"is_default" db:"is_default"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
}

// Grade represents a single grade for a student
type Grade struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	StudentID    uuid.UUID  `json:"student_id" db:"student_id"`
	SubjectID    uuid.UUID  `json:"subject_id" db:"subject_id"`
	TeacherID    uuid.UUID  `json:"teacher_id" db:"teacher_id"`
	SchoolYearID uuid.UUID  `json:"school_year_id" db:"school_year_id"`
	GradeScaleID uuid.UUID  `json:"grade_scale_id" db:"grade_scale_id"`
	Type         string     `json:"type" db:"type"` // GradeType constants
	Value        float64    `json:"value" db:"value"`
	Weight       float64    `json:"weight" db:"weight"` // Gewichtung: 1.0, 2.0, 0.5
	Date         time.Time  `json:"date" db:"date"`
	Title        *string    `json:"title,omitempty" db:"title"` // e.g., "1. Klassenarbeit"
	Description  *string    `json:"description,omitempty" db:"description"`
	IsVisible    bool       `json:"is_visible" db:"is_visible"` // Für Eltern/Schüler sichtbar
	Semester     int        `json:"semester" db:"semester"` // 1 or 2
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// GradeComment represents a teacher comment on a student's grade
type GradeComment struct {
	ID        uuid.UUID `json:"id" db:"id"`
	GradeID   uuid.UUID `json:"grade_id" db:"grade_id"`
	TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
	Comment   string    `json:"comment" db:"comment"`
	IsPrivate bool      `json:"is_private" db:"is_private"` // Only visible to teachers
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// ========================================
// Klassenbuch / Class Diary
// ========================================

// ClassDiaryEntry represents an entry in the digital class diary
type ClassDiaryEntry struct {
	ID               uuid.UUID  `json:"id" db:"id"`
	ClassID          uuid.UUID  `json:"class_id" db:"class_id"`
	Date             time.Time  `json:"date" db:"date"`
	SlotID           uuid.UUID  `json:"slot_id" db:"slot_id"`
	SubjectID        uuid.UUID  `json:"subject_id" db:"subject_id"`
	TeacherID        uuid.UUID  `json:"teacher_id" db:"teacher_id"`
	Topic            *string    `json:"topic,omitempty" db:"topic"`         // Unterrichtsthema
	Homework         *string    `json:"homework,omitempty" db:"homework"`   // Hausaufgabe
	HomeworkDueDate  *time.Time `json:"homework_due_date,omitempty" db:"homework_due_date"`
	Materials        *string    `json:"materials,omitempty" db:"materials"` // Benötigte Materialien
	Notes            *string    `json:"notes,omitempty" db:"notes"`         // Besondere Vorkommnisse
	IsCancelled      bool       `json:"is_cancelled" db:"is_cancelled"`
	CancellationReason *string  `json:"cancellation_reason,omitempty" db:"cancellation_reason"`
	CreatedAt        time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt        time.Time  `json:"updated_at" db:"updated_at"`
}

// ========================================
// Elterngespräche / Parent Meetings
// ========================================

// ParentMeetingSlot represents available time slots for parent meetings
type ParentMeetingSlot struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	TeacherID   uuid.UUID  `json:"teacher_id" db:"teacher_id"`
	Date        time.Time  `json:"date" db:"date"`
	StartTime   string     `json:"start_time" db:"start_time"` // "14:00"
	EndTime     string     `json:"end_time" db:"end_time"`     // "14:15"
	Location    *string    `json:"location,omitempty" db:"location"` // Room or "Online"
	IsOnline    bool       `json:"is_online" db:"is_online"`
	MeetingLink *string    `json:"meeting_link,omitempty" db:"meeting_link"`
	IsBooked    bool       `json:"is_booked" db:"is_booked"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
}

// ParentMeeting represents a booked parent-teacher meeting
type ParentMeeting struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	SlotID       uuid.UUID  `json:"slot_id" db:"slot_id"`
	ParentID     uuid.UUID  `json:"parent_id" db:"parent_id"`
	StudentID    uuid.UUID  `json:"student_id" db:"student_id"`
	Topic        *string    `json:"topic,omitempty" db:"topic"`
	Notes        *string    `json:"notes,omitempty" db:"notes"` // Teacher notes (private)
	Status       string     `json:"status" db:"status"` // 'scheduled', 'completed', 'cancelled', 'no_show'
	CancelledAt  *time.Time `json:"cancelled_at,omitempty" db:"cancelled_at"`
	CancelledBy  *uuid.UUID `json:"cancelled_by,omitempty" db:"cancelled_by"`
	CancelReason *string    `json:"cancel_reason,omitempty" db:"cancel_reason"`
	CompletedAt  *time.Time `json:"completed_at,omitempty" db:"completed_at"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// ========================================
// Matrix / Communication Integration
// ========================================

// MatrixRoom tracks Matrix rooms created for school communication
type MatrixRoom struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	SchoolID    uuid.UUID  `json:"school_id" db:"school_id"`
	MatrixRoomID string    `json:"matrix_room_id" db:"matrix_room_id"` // e.g., "!abc123:breakpilot.local"
	Type        string     `json:"type" db:"type"` // 'class_info', 'class_rep', 'student_dm', 'teacher_dm', 'announcement'
	ClassID     *uuid.UUID `json:"class_id,omitempty" db:"class_id"`
	StudentID   *uuid.UUID `json:"student_id,omitempty" db:"student_id"`
	Name        string     `json:"name" db:"name"`
	IsEncrypted bool       `json:"is_encrypted" db:"is_encrypted"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
}

// MatrixRoomMember tracks membership in Matrix rooms
type MatrixRoomMember struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	MatrixRoomID  uuid.UUID  `json:"matrix_room_id" db:"matrix_room_id"` // FK to MatrixRoom
	MatrixUserID  string     `json:"matrix_user_id" db:"matrix_user_id"` // e.g., "@user:breakpilot.local"
	UserID        *uuid.UUID `json:"user_id,omitempty" db:"user_id"` // FK to User (if known)
	PowerLevel    int        `json:"power_level" db:"power_level"` // Matrix power level (0, 50, 100)
	CanWrite      bool       `json:"can_write" db:"can_write"`
	JoinedAt      time.Time  `json:"joined_at" db:"joined_at"`
	LeftAt        *time.Time `json:"left_at,omitempty" db:"left_at"`
}

// ParentOnboardingToken for QR-code based parent onboarding
type ParentOnboardingToken struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	SchoolID     uuid.UUID  `json:"school_id" db:"school_id"`
	ClassID      uuid.UUID  `json:"class_id" db:"class_id"`
	StudentID    uuid.UUID  `json:"student_id" db:"student_id"`
	Token        string     `json:"token" db:"token"` // Unique token for QR code
	Role         string     `json:"role" db:"role"` // 'parent' or 'parent_representative'
	ExpiresAt    time.Time  `json:"expires_at" db:"expires_at"`
	UsedAt       *time.Time `json:"used_at,omitempty" db:"used_at"`
	UsedByUserID *uuid.UUID `json:"used_by_user_id,omitempty" db:"used_by_user_id"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	CreatedBy    uuid.UUID  `json:"created_by" db:"created_by"` // Teacher who created
}

// ========================================
// Schulverwaltung DTOs
// ========================================

// CreateSchoolRequest for creating a new school
type CreateSchoolRequest struct {
	Name      string  `json:"name" binding:"required"`
	ShortName *string `json:"short_name"`
	Type      string  `json:"type" binding:"required"`
	Address   *string `json:"address"`
	City      *string `json:"city"`
	PostalCode *string `json:"postal_code"`
	State     *string `json:"state"`
	Phone     *string `json:"phone"`
	Email     *string `json:"email"`
	Website   *string `json:"website"`
}

// CreateClassRequest for creating a new class
type CreateClassRequest struct {
	SchoolYearID string  `json:"school_year_id" binding:"required"`
	Name         string  `json:"name" binding:"required"`
	Grade        int     `json:"grade" binding:"required"`
	Section      *string `json:"section"`
	Room         *string `json:"room"`
}

// CreateStudentRequest for creating a new student
type CreateStudentRequest struct {
	ClassID       string  `json:"class_id" binding:"required"`
	StudentNumber *string `json:"student_number"`
	FirstName     string  `json:"first_name" binding:"required"`
	LastName      string  `json:"last_name" binding:"required"`
	DateOfBirth   *string `json:"date_of_birth"` // ISO 8601
	Gender        *string `json:"gender"`
}

// RecordAttendanceRequest for recording attendance
type RecordAttendanceRequest struct {
	StudentID string `json:"student_id" binding:"required"`
	Date      string `json:"date" binding:"required"` // ISO 8601
	SlotID    string `json:"slot_id" binding:"required"`
	Status    string `json:"status" binding:"required"` // AttendanceStatus
	Note      *string `json:"note"`
}

// ReportAbsenceRequest for parents reporting absence
type ReportAbsenceRequest struct {
	StudentID      string  `json:"student_id" binding:"required"`
	StartDate      string  `json:"start_date" binding:"required"` // ISO 8601
	EndDate        string  `json:"end_date" binding:"required"`   // ISO 8601
	Reason         *string `json:"reason"`
	ReasonCategory string  `json:"reason_category" binding:"required"`
}

// CreateGradeRequest for creating a grade
type CreateGradeRequest struct {
	StudentID    string  `json:"student_id" binding:"required"`
	SubjectID    string  `json:"subject_id" binding:"required"`
	SchoolYearID string  `json:"school_year_id" binding:"required"`
	Type         string  `json:"type" binding:"required"` // GradeType
	Value        float64 `json:"value" binding:"required"`
	Weight       float64 `json:"weight"`
	Date         string  `json:"date" binding:"required"` // ISO 8601
	Title        *string `json:"title"`
	Description  *string `json:"description"`
	Semester     int     `json:"semester" binding:"required"`
}

// StudentGradeOverview provides a summary of all grades for a student in a subject
type StudentGradeOverview struct {
	Student     Student   `json:"student"`
	Subject     Subject   `json:"subject"`
	Grades      []Grade   `json:"grades"`
	Average     float64   `json:"average"`
	OralAverage float64   `json:"oral_average"`
	ExamAverage float64   `json:"exam_average"`
	Semester    int       `json:"semester"`
}

// ClassAttendanceOverview provides attendance summary for a class
type ClassAttendanceOverview struct {
	Class           Class      `json:"class"`
	Date            time.Time  `json:"date"`
	TotalStudents   int        `json:"total_students"`
	PresentCount    int        `json:"present_count"`
	AbsentCount     int        `json:"absent_count"`
	LateCount       int        `json:"late_count"`
	Records         []AttendanceRecord `json:"records"`
}

// ParentDashboard provides a parent's view of their children's data
type ParentDashboard struct {
	Children        []StudentOverview `json:"children"`
	UnreadMessages  int               `json:"unread_messages"`
	UpcomingMeetings []ParentMeeting  `json:"upcoming_meetings"`
	RecentGrades    []Grade           `json:"recent_grades"`
	PendingActions  []string          `json:"pending_actions"` // e.g., "Entschuldigung ausstehend"
}

// StudentOverview provides summary info about a student
type StudentOverview struct {
	Student          Student  `json:"student"`
	Class            Class    `json:"class"`
	ClassTeacher     *Teacher `json:"class_teacher,omitempty"`
	AttendanceRate   float64  `json:"attendance_rate"` // Percentage
	UnexcusedAbsences int     `json:"unexcused_absences"`
	GradeAverage     float64  `json:"grade_average"`
}

// TimetableView provides a formatted timetable for display
type TimetableView struct {
	Class      Class              `json:"class"`
	Week       string             `json:"week"` // ISO week: "2025-W01"
	Days       []TimetableDayView `json:"days"`
}

// TimetableDayView represents a single day in the timetable
type TimetableDayView struct {
	Date    time.Time           `json:"date"`
	DayName string              `json:"day_name"` // "Montag"
	Lessons []TimetableLessonView `json:"lessons"`
}

// TimetableLessonView represents a single lesson in the timetable view
type TimetableLessonView struct {
	Slot        TimetableSlot `json:"slot"`
	Subject     *Subject      `json:"subject,omitempty"`
	Teacher     *Teacher      `json:"teacher,omitempty"`
	Room        *string       `json:"room,omitempty"`
	IsSubstitution bool       `json:"is_substitution"`
	IsCancelled    bool       `json:"is_cancelled"`
	Note           *string    `json:"note,omitempty"`
}

// ========================================
// Phase 10: DSGVO Betroffenenanfragen (DSR)
// Data Subject Request Management
// Art. 15, 16, 17, 18, 20 DSGVO
// ========================================

// DSRRequestType defines the GDPR article for the request
type DSRRequestType string

const (
	DSRTypeAccess       DSRRequestType = "access"       // Art. 15 - Auskunftsrecht
	DSRTypeRectification DSRRequestType = "rectification" // Art. 16 - Berichtigungsrecht
	DSRTypeErasure      DSRRequestType = "erasure"      // Art. 17 - Löschungsrecht
	DSRTypeRestriction  DSRRequestType = "restriction"  // Art. 18 - Einschränkungsrecht
	DSRTypePortability  DSRRequestType = "portability"  // Art. 20 - Datenübertragbarkeit
)

// DSRStatus defines the workflow state of a DSR
type DSRStatus string

const (
	DSRStatusIntake              DSRStatus = "intake"                // Eingegangen
	DSRStatusIdentityVerification DSRStatus = "identity_verification" // Identitätsprüfung
	DSRStatusProcessing          DSRStatus = "processing"            // In Bearbeitung
	DSRStatusCompleted           DSRStatus = "completed"             // Abgeschlossen
	DSRStatusRejected            DSRStatus = "rejected"              // Abgelehnt
	DSRStatusCancelled           DSRStatus = "cancelled"             // Storniert
)

// DSRPriority defines the priority level of a DSR
type DSRPriority string

const (
	DSRPriorityNormal   DSRPriority = "normal"
	DSRPriorityExpedited DSRPriority = "expedited" // Art. 16, 17, 18 - beschleunigt
	DSRPriorityUrgent   DSRPriority = "urgent"
)

// DSRSource defines where the request came from
type DSRSource string

const (
	DSRSourceAPI        DSRSource = "api"         // Über API/Self-Service
	DSRSourceAdminPanel DSRSource = "admin_panel" // Manuell im Admin
	DSRSourceEmail      DSRSource = "email"       // Per E-Mail
	DSRSourcePostal     DSRSource = "postal"      // Per Post
)

// DataSubjectRequest represents a GDPR data subject request
type DataSubjectRequest struct {
	ID                       uuid.UUID              `json:"id" db:"id"`
	UserID                   *uuid.UUID             `json:"user_id,omitempty" db:"user_id"`
	RequestNumber            string                 `json:"request_number" db:"request_number"`
	RequestType              DSRRequestType         `json:"request_type" db:"request_type"`
	Status                   DSRStatus              `json:"status" db:"status"`
	Priority                 DSRPriority            `json:"priority" db:"priority"`
	Source                   DSRSource              `json:"source" db:"source"`
	RequesterEmail           string                 `json:"requester_email" db:"requester_email"`
	RequesterName            *string                `json:"requester_name,omitempty" db:"requester_name"`
	RequesterPhone           *string                `json:"requester_phone,omitempty" db:"requester_phone"`
	IdentityVerified         bool                   `json:"identity_verified" db:"identity_verified"`
	IdentityVerifiedAt       *time.Time             `json:"identity_verified_at,omitempty" db:"identity_verified_at"`
	IdentityVerifiedBy       *uuid.UUID             `json:"identity_verified_by,omitempty" db:"identity_verified_by"`
	IdentityVerificationMethod *string              `json:"identity_verification_method,omitempty" db:"identity_verification_method"`
	RequestDetails           map[string]interface{} `json:"request_details" db:"request_details"`
	DeadlineAt               time.Time              `json:"deadline_at" db:"deadline_at"`
	LegalDeadlineDays        int                    `json:"legal_deadline_days" db:"legal_deadline_days"`
	ExtendedDeadlineAt       *time.Time             `json:"extended_deadline_at,omitempty" db:"extended_deadline_at"`
	ExtensionReason          *string                `json:"extension_reason,omitempty" db:"extension_reason"`
	AssignedTo               *uuid.UUID             `json:"assigned_to,omitempty" db:"assigned_to"`
	ProcessingNotes          *string                `json:"processing_notes,omitempty" db:"processing_notes"`
	CompletedAt              *time.Time             `json:"completed_at,omitempty" db:"completed_at"`
	CompletedBy              *uuid.UUID             `json:"completed_by,omitempty" db:"completed_by"`
	ResultSummary            *string                `json:"result_summary,omitempty" db:"result_summary"`
	ResultData               map[string]interface{} `json:"result_data,omitempty" db:"result_data"`
	RejectedAt               *time.Time             `json:"rejected_at,omitempty" db:"rejected_at"`
	RejectedBy               *uuid.UUID             `json:"rejected_by,omitempty" db:"rejected_by"`
	RejectionReason          *string                `json:"rejection_reason,omitempty" db:"rejection_reason"`
	RejectionLegalBasis      *string                `json:"rejection_legal_basis,omitempty" db:"rejection_legal_basis"`
	CreatedAt                time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt                time.Time              `json:"updated_at" db:"updated_at"`
	CreatedBy                *uuid.UUID             `json:"created_by,omitempty" db:"created_by"`
}

// DSRStatusHistory tracks status changes for audit trail
type DSRStatusHistory struct {
	ID         uuid.UUID              `json:"id" db:"id"`
	RequestID  uuid.UUID              `json:"request_id" db:"request_id"`
	FromStatus *DSRStatus             `json:"from_status,omitempty" db:"from_status"`
	ToStatus   DSRStatus              `json:"to_status" db:"to_status"`
	ChangedBy  *uuid.UUID             `json:"changed_by,omitempty" db:"changed_by"`
	Comment    *string                `json:"comment,omitempty" db:"comment"`
	Metadata   map[string]interface{} `json:"metadata,omitempty" db:"metadata"`
	CreatedAt  time.Time              `json:"created_at" db:"created_at"`
}

// DSRCommunication tracks all communications related to a DSR
type DSRCommunication struct {
	ID                 uuid.UUID              `json:"id" db:"id"`
	RequestID          uuid.UUID              `json:"request_id" db:"request_id"`
	Direction          string                 `json:"direction" db:"direction"` // 'outbound', 'inbound'
	Channel            string                 `json:"channel" db:"channel"`     // 'email', 'in_app', 'postal'
	CommunicationType  string                 `json:"communication_type" db:"communication_type"` // Template type used
	TemplateVersionID  *uuid.UUID             `json:"template_version_id,omitempty" db:"template_version_id"`
	Subject            *string                `json:"subject,omitempty" db:"subject"`
	BodyHTML           *string                `json:"body_html,omitempty" db:"body_html"`
	BodyText           *string                `json:"body_text,omitempty" db:"body_text"`
	RecipientEmail     *string                `json:"recipient_email,omitempty" db:"recipient_email"`
	SentAt             *time.Time             `json:"sent_at,omitempty" db:"sent_at"`
	ErrorMessage       *string                `json:"error_message,omitempty" db:"error_message"`
	Attachments        []map[string]interface{} `json:"attachments,omitempty" db:"attachments"`
	CreatedAt          time.Time              `json:"created_at" db:"created_at"`
	CreatedBy          *uuid.UUID             `json:"created_by,omitempty" db:"created_by"`
}

// DSRTemplate represents a template type for DSR communications
type DSRTemplate struct {
	ID           uuid.UUID `json:"id" db:"id"`
	TemplateType string    `json:"template_type" db:"template_type"`
	Name         string    `json:"name" db:"name"`
	Description  *string   `json:"description,omitempty" db:"description"`
	RequestTypes []string  `json:"request_types" db:"request_types"` // Which DSR types use this template
	IsActive     bool      `json:"is_active" db:"is_active"`
	SortOrder    int       `json:"sort_order" db:"sort_order"`
	CreatedAt    time.Time `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time `json:"updated_at" db:"updated_at"`
}

// DSRTemplateVersion represents a versioned template for DSR communications
type DSRTemplateVersion struct {
	ID           uuid.UUID  `json:"id" db:"id"`
	TemplateID   uuid.UUID  `json:"template_id" db:"template_id"`
	Version      string     `json:"version" db:"version"`
	Language     string     `json:"language" db:"language"`
	Subject      string     `json:"subject" db:"subject"`
	BodyHTML     string     `json:"body_html" db:"body_html"`
	BodyText     string     `json:"body_text" db:"body_text"`
	Status       string     `json:"status" db:"status"` // draft, review, approved, published, archived
	PublishedAt  *time.Time `json:"published_at,omitempty" db:"published_at"`
	CreatedBy    *uuid.UUID `json:"created_by,omitempty" db:"created_by"`
	ApprovedBy   *uuid.UUID `json:"approved_by,omitempty" db:"approved_by"`
	ApprovedAt   *time.Time `json:"approved_at,omitempty" db:"approved_at"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

// DSRExceptionCheck tracks Art. 17(3) exception evaluations for erasure requests
type DSRExceptionCheck struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	RequestID     uuid.UUID  `json:"request_id" db:"request_id"`
	ExceptionType string     `json:"exception_type" db:"exception_type"` // Type of exception (Art. 17(3) a-e)
	Description   string     `json:"description" db:"description"`
	Applies       *bool      `json:"applies,omitempty" db:"applies"` // nil = not checked, true/false = result
	CheckedBy     *uuid.UUID `json:"checked_by,omitempty" db:"checked_by"`
	CheckedAt     *time.Time `json:"checked_at,omitempty" db:"checked_at"`
	Notes         *string    `json:"notes,omitempty" db:"notes"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
}

// Art. 17(3) Exception Types
const (
	DSRExceptionFreedomExpression = "freedom_expression" // Art. 17(3)(a)
	DSRExceptionLegalObligation   = "legal_obligation"   // Art. 17(3)(b)
	DSRExceptionPublicInterest    = "public_interest"    // Art. 17(3)(c)
	DSRExceptionPublicHealth      = "public_health"      // Art. 17(3)(c)
	DSRExceptionArchiving         = "archiving"          // Art. 17(3)(d)
	DSRExceptionLegalClaims       = "legal_claims"       // Art. 17(3)(e)
)

// ========================================
// DSR DTOs (Data Transfer Objects)
// ========================================

// CreateDSRRequest for creating a new data subject request
type CreateDSRRequest struct {
	RequestType    string                 `json:"request_type" binding:"required"`
	RequesterEmail string                 `json:"requester_email" binding:"required,email"`
	RequesterName  *string                `json:"requester_name"`
	RequesterPhone *string                `json:"requester_phone"`
	Source         string                 `json:"source"`
	RequestDetails map[string]interface{} `json:"request_details"`
	Priority       string                 `json:"priority"`
}

// UpdateDSRRequest for updating a DSR
type UpdateDSRRequest struct {
	Status            *string                `json:"status"`
	AssignedTo        *string                `json:"assigned_to"` // UUID string
	ProcessingNotes   *string                `json:"processing_notes"`
	ExtendDeadline    *bool                  `json:"extend_deadline"`
	ExtensionReason   *string                `json:"extension_reason"`
	RequestDetails    map[string]interface{} `json:"request_details"`
	Priority          *string                `json:"priority"`
}

// VerifyDSRIdentityRequest for verifying identity of requester
type VerifyDSRIdentityRequest struct {
	Method  string  `json:"method" binding:"required"` // email_confirmation, id_document, in_person
	Comment *string `json:"comment"`
}

// CompleteDSRRequest for completing a DSR
type CompleteDSRRequest struct {
	ResultSummary string                 `json:"result_summary" binding:"required"`
	ResultData    map[string]interface{} `json:"result_data"`
}

// RejectDSRRequest for rejecting a DSR
type RejectDSRRequest struct {
	Reason     string `json:"reason" binding:"required"`
	LegalBasis string `json:"legal_basis" binding:"required"` // Art. 12(5), Art. 17(3)(a-e), etc.
}

// ExtendDSRDeadlineRequest for extending a DSR deadline
type ExtendDSRDeadlineRequest struct {
	Reason string `json:"reason" binding:"required"`
	Days   int    `json:"days"` // Optional: custom extension days
}

// AssignDSRRequest for assigning a DSR to a handler
type AssignDSRRequest struct {
	AssigneeID string  `json:"assignee_id" binding:"required"`
	Comment    *string `json:"comment"`
}

// SendDSRCommunicationRequest for sending a communication
type SendDSRCommunicationRequest struct {
	CommunicationType string            `json:"communication_type" binding:"required"`
	TemplateVersionID *string           `json:"template_version_id"`
	CustomSubject     *string           `json:"custom_subject"`
	CustomBody        *string           `json:"custom_body"`
	Variables         map[string]string `json:"variables"`
}

// UpdateDSRExceptionCheckRequest for updating an exception check
type UpdateDSRExceptionCheckRequest struct {
	Applies bool    `json:"applies"`
	Notes   *string `json:"notes"`
}

// DSRListFilters for filtering DSR list
type DSRListFilters struct {
	Status       *string    `form:"status"`
	RequestType  *string    `form:"request_type"`
	AssignedTo   *string    `form:"assigned_to"`
	Priority     *string    `form:"priority"`
	OverdueOnly  bool       `form:"overdue_only"`
	FromDate     *time.Time `form:"from_date"`
	ToDate       *time.Time `form:"to_date"`
	Search       *string    `form:"search"` // Search in request number, email, name
}

// DSRDashboardStats for the admin dashboard
type DSRDashboardStats struct {
	TotalRequests        int                      `json:"total_requests"`
	PendingRequests      int                      `json:"pending_requests"`
	OverdueRequests      int                      `json:"overdue_requests"`
	CompletedThisMonth   int                      `json:"completed_this_month"`
	AverageProcessingDays float64                 `json:"average_processing_days"`
	ByType               map[string]int           `json:"by_type"`
	ByStatus             map[string]int           `json:"by_status"`
	UpcomingDeadlines    []DataSubjectRequest     `json:"upcoming_deadlines"`
}

// DSRWithDetails combines DSR with related data
type DSRWithDetails struct {
	Request        DataSubjectRequest  `json:"request"`
	StatusHistory  []DSRStatusHistory  `json:"status_history"`
	Communications []DSRCommunication  `json:"communications"`
	ExceptionChecks []DSRExceptionCheck `json:"exception_checks,omitempty"`
	AssigneeName   *string             `json:"assignee_name,omitempty"`
	CreatorName    *string             `json:"creator_name,omitempty"`
}

// DSRTemplateWithVersions combines template with versions
type DSRTemplateWithVersions struct {
	Template       DSRTemplate          `json:"template"`
	LatestVersion  *DSRTemplateVersion  `json:"latest_version,omitempty"`
	Versions       []DSRTemplateVersion `json:"versions,omitempty"`
}

// CreateDSRTemplateVersionRequest for creating a template version
type CreateDSRTemplateVersionRequest struct {
	TemplateID string  `json:"template_id" binding:"required"`
	Version    string  `json:"version" binding:"required"`
	Language   string  `json:"language" binding:"required"`
	Subject    string  `json:"subject" binding:"required"`
	BodyHTML   string  `json:"body_html" binding:"required"`
	BodyText   string  `json:"body_text" binding:"required"`
}

// UpdateDSRTemplateVersionRequest for updating a template version
type UpdateDSRTemplateVersionRequest struct {
	Subject  *string `json:"subject"`
	BodyHTML *string `json:"body_html"`
	BodyText *string `json:"body_text"`
	Status   *string `json:"status"`
}

// PreviewDSRTemplateRequest for previewing a template with variables
type PreviewDSRTemplateRequest struct {
	Variables map[string]string `json:"variables"`
}

// DSRTemplatePreviewResponse for template preview
type DSRTemplatePreviewResponse struct {
	Subject  string `json:"subject"`
	BodyHTML string `json:"body_html"`
	BodyText string `json:"body_text"`
}

// GetRequestTypeLabel returns German label for request type
func (rt DSRRequestType) Label() string {
	switch rt {
	case DSRTypeAccess:
		return "Auskunftsanfrage (Art. 15)"
	case DSRTypeRectification:
		return "Berichtigungsanfrage (Art. 16)"
	case DSRTypeErasure:
		return "Löschanfrage (Art. 17)"
	case DSRTypeRestriction:
		return "Einschränkungsanfrage (Art. 18)"
	case DSRTypePortability:
		return "Datenübertragung (Art. 20)"
	default:
		return string(rt)
	}
}

// GetDeadlineDays returns the legal deadline in days for request type
func (rt DSRRequestType) DeadlineDays() int {
	switch rt {
	case DSRTypeAccess, DSRTypePortability:
		return 30 // 1 month
	case DSRTypeRectification, DSRTypeErasure, DSRTypeRestriction:
		return 14 // 2 weeks (expedited per BDSG)
	default:
		return 30
	}
}

// IsExpedited returns whether this request type should be processed expeditiously
func (rt DSRRequestType) IsExpedited() bool {
	switch rt {
	case DSRTypeRectification, DSRTypeErasure, DSRTypeRestriction:
		return true
	default:
		return false
	}
}

// GetStatusLabel returns German label for status
func (s DSRStatus) Label() string {
	switch s {
	case DSRStatusIntake:
		return "Eingang"
	case DSRStatusIdentityVerification:
		return "Identitätsprüfung"
	case DSRStatusProcessing:
		return "In Bearbeitung"
	case DSRStatusCompleted:
		return "Abgeschlossen"
	case DSRStatusRejected:
		return "Abgelehnt"
	case DSRStatusCancelled:
		return "Storniert"
	default:
		return string(s)
	}
}

// IsValidDSRRequestType checks if a string is a valid DSR request type
func IsValidDSRRequestType(reqType string) bool {
	switch DSRRequestType(reqType) {
	case DSRTypeAccess, DSRTypeRectification, DSRTypeErasure, DSRTypeRestriction, DSRTypePortability:
		return true
	default:
		return false
	}
}

// IsValidDSRStatus checks if a string is a valid DSR status
func IsValidDSRStatus(status string) bool {
	switch DSRStatus(status) {
	case DSRStatusIntake, DSRStatusIdentityVerification, DSRStatusProcessing,
		DSRStatusCompleted, DSRStatusRejected, DSRStatusCancelled:
		return true
	default:
		return false
	}
}
