// Package client provides a Go SDK for interacting with the MapleFile API.
package client

import "time"

// -----------------------------------------------------------------------------
// Health & Version Types
// -----------------------------------------------------------------------------

// HealthResponse represents the health check response.
type HealthResponse struct {
	Status string `json:"status"`
}

// VersionResponse represents the API version response.
type VersionResponse struct {
	Version string `json:"version"`
}

// -----------------------------------------------------------------------------
// Authentication Types
// -----------------------------------------------------------------------------

// RegisterInput represents the registration request.
type RegisterInput struct {
	BetaAccessCode                                 string `json:"beta_access_code"`
	Email                                          string `json:"email"`
	FirstName                                      string `json:"first_name"`
	LastName                                       string `json:"last_name"`
	Phone                                          string `json:"phone"`
	Country                                        string `json:"country"`
	Timezone                                       string `json:"timezone"`
	PasswordSalt                                   string `json:"salt"`
	KDFAlgorithm                                   string `json:"kdf_algorithm"`
	KDFIterations                                  int    `json:"kdf_iterations"`
	KDFMemory                                      int    `json:"kdf_memory"`
	KDFParallelism                                 int    `json:"kdf_parallelism"`
	KDFSaltLength                                  int    `json:"kdf_salt_length"`
	KDFKeyLength                                   int    `json:"kdf_key_length"`
	EncryptedMasterKey                             string `json:"encryptedMasterKey"`
	PublicKey                                      string `json:"publicKey"`
	EncryptedPrivateKey                            string `json:"encryptedPrivateKey"`
	EncryptedRecoveryKey                           string `json:"encryptedRecoveryKey"`
	MasterKeyEncryptedWithRecoveryKey              string `json:"masterKeyEncryptedWithRecoveryKey"`
	AgreeTermsOfService                            bool   `json:"agree_terms_of_service"`
	AgreePromotions                                bool   `json:"agree_promotions"`
	AgreeToTrackingAcrossThirdPartyAppsAndServices bool   `json:"agree_to_tracking_across_third_party_apps_and_services"`
}

// RegisterResponse represents the registration response.
type RegisterResponse struct {
	Message string `json:"message"`
	UserID  string `json:"user_id"`
}

// VerifyEmailInput represents the email verification request.
type VerifyEmailInput struct {
	Email string `json:"email"`
	Code  string `json:"code"`
}

// VerifyEmailResponse represents the email verification response.
type VerifyEmailResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}

// ResendVerificationInput represents the resend verification request.
type ResendVerificationInput struct {
	Email string `json:"email"`
}

// OTTResponse represents the OTT request response.
type OTTResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}

// VerifyOTTResponse represents the OTT verification response.
type VerifyOTTResponse struct {
	Message             string `json:"message"`
	ChallengeID         string `json:"challengeId"`
	EncryptedChallenge  string `json:"encryptedChallenge"`
	Salt                string `json:"salt"`
	EncryptedMasterKey  string `json:"encryptedMasterKey"`
	EncryptedPrivateKey string `json:"encryptedPrivateKey"`
	PublicKey           string `json:"publicKey"`
	// KDFAlgorithm specifies which key derivation algorithm to use.
	// Values: "PBKDF2-SHA256" (web frontend) or "argon2id" (native app legacy)
	KDFAlgorithm string `json:"kdfAlgorithm"`
}

// CompleteLoginInput represents the complete login request.
type CompleteLoginInput struct {
	Email         string `json:"email"`
	ChallengeID   string `json:"challengeId"`
	DecryptedData string `json:"decryptedData"`
}

// LoginResponse represents the login response (from complete-login or token refresh).
type LoginResponse struct {
	Message                string `json:"message"`
	AccessToken            string `json:"access_token"`
	RefreshToken           string `json:"refresh_token"`
	AccessTokenExpiryDate  string `json:"access_token_expiry_date"`
	RefreshTokenExpiryDate string `json:"refresh_token_expiry_date"`
	Username               string `json:"username"`
}

// RefreshTokenInput represents the token refresh request.
type RefreshTokenInput struct {
	RefreshToken string `json:"value"`
}

// RecoveryInitiateInput represents the recovery initiation request.
type RecoveryInitiateInput struct {
	Email  string `json:"email"`
	Method string `json:"method"` // "recovery_key"
}

// RecoveryInitiateResponse represents the recovery initiation response.
type RecoveryInitiateResponse struct {
	Message            string `json:"message"`
	SessionID          string `json:"session_id"`
	EncryptedChallenge string `json:"encrypted_challenge"`
}

// RecoveryVerifyInput represents the recovery verification request.
type RecoveryVerifyInput struct {
	SessionID          string `json:"session_id"`
	DecryptedChallenge string `json:"decrypted_challenge"`
}

// RecoveryVerifyResponse represents the recovery verification response.
type RecoveryVerifyResponse struct {
	Message             string `json:"message"`
	RecoveryToken       string `json:"recovery_token"`
	CanResetCredentials bool   `json:"can_reset_credentials"`
}

// RecoveryCompleteInput represents the recovery completion request.
type RecoveryCompleteInput struct {
	RecoveryToken                        string `json:"recovery_token"`
	NewSalt                              string `json:"new_salt"`
	NewPublicKey                         string `json:"new_public_key"`
	NewEncryptedMasterKey                string `json:"new_encrypted_master_key"`
	NewEncryptedPrivateKey               string `json:"new_encrypted_private_key"`
	NewEncryptedRecoveryKey              string `json:"new_encrypted_recovery_key"`
	NewMasterKeyEncryptedWithRecoveryKey string `json:"new_master_key_encrypted_with_recovery_key"`
}

// RecoveryCompleteResponse represents the recovery completion response.
type RecoveryCompleteResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}

// -----------------------------------------------------------------------------
// User/Profile Types
// -----------------------------------------------------------------------------

// User represents a user profile.
type User struct {
	ID                                             string    `json:"id"`
	Email                                          string    `json:"email"`
	FirstName                                      string    `json:"first_name"`
	LastName                                       string    `json:"last_name"`
	Name                                           string    `json:"name"`
	LexicalName                                    string    `json:"lexical_name"`
	Role                                           int8      `json:"role"`
	Phone                                          string    `json:"phone,omitempty"`
	Country                                        string    `json:"country,omitempty"`
	Timezone                                       string    `json:"timezone"`
	Region                                         string    `json:"region,omitempty"`
	City                                           string    `json:"city,omitempty"`
	PostalCode                                     string    `json:"postal_code,omitempty"`
	AddressLine1                                   string    `json:"address_line1,omitempty"`
	AddressLine2                                   string    `json:"address_line2,omitempty"`
	AgreePromotions                                bool      `json:"agree_promotions,omitempty"`
	AgreeToTrackingAcrossThirdPartyAppsAndServices bool      `json:"agree_to_tracking_across_third_party_apps_and_services,omitempty"`
	ShareNotificationsEnabled                      *bool     `json:"share_notifications_enabled,omitempty"`
	CreatedAt                                      time.Time `json:"created_at,omitempty"`
	Status                                         int8      `json:"status"`
	ProfileVerificationStatus                      int8      `json:"profile_verification_status,omitempty"`
	WebsiteURL                                     string    `json:"website_url"`
	Description                                    string    `json:"description"`
	ComicBookStoreName                             string    `json:"comic_book_store_name,omitempty"`
}

// UpdateUserInput represents the user update request.
type UpdateUserInput struct {
	Email                                          string `json:"email"`
	FirstName                                      string `json:"first_name"`
	LastName                                       string `json:"last_name"`
	Phone                                          string `json:"phone,omitempty"`
	Country                                        string `json:"country,omitempty"`
	Region                                         string `json:"region,omitempty"`
	Timezone                                       string `json:"timezone"`
	AgreePromotions                                bool   `json:"agree_promotions,omitempty"`
	AgreeToTrackingAcrossThirdPartyAppsAndServices bool   `json:"agree_to_tracking_across_third_party_apps_and_services,omitempty"`
	ShareNotificationsEnabled                      *bool  `json:"share_notifications_enabled,omitempty"`
}

// DeleteUserInput represents the user deletion request.
type DeleteUserInput struct {
	Password string `json:"password"`
}

// PublicUser represents public user information returned from lookup.
type PublicUser struct {
	UserID            string `json:"user_id"`
	Email             string `json:"email"`
	Name              string `json:"name"`
	PublicKeyInBase64 string `json:"public_key_in_base64"`
	VerificationID    string `json:"verification_id"`
}

// -----------------------------------------------------------------------------
// Blocked Email Types
// -----------------------------------------------------------------------------

// CreateBlockedEmailInput represents the blocked email creation request.
type CreateBlockedEmailInput struct {
	Email  string `json:"email"`
	Reason string `json:"reason,omitempty"`
}

// BlockedEmail represents a blocked email entry.
type BlockedEmail struct {
	UserID        string    `json:"user_id"`
	BlockedEmail  string    `json:"blocked_email"`
	BlockedUserID string    `json:"blocked_user_id,omitempty"`
	Reason        string    `json:"reason,omitempty"`
	CreatedAt     time.Time `json:"created_at"`
}

// ListBlockedEmailsResponse represents the list of blocked emails response.
type ListBlockedEmailsResponse struct {
	BlockedEmails []*BlockedEmail `json:"blocked_emails"`
	Count         int             `json:"count"`
}

// DeleteBlockedEmailResponse represents the blocked email deletion response.
type DeleteBlockedEmailResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
}

// -----------------------------------------------------------------------------
// Dashboard Types
// -----------------------------------------------------------------------------

// Dashboard represents dashboard data.
type Dashboard struct {
	Summary           DashboardSummary         `json:"summary"`
	StorageUsageTrend StorageUsageTrend        `json:"storage_usage_trend"`
	RecentFiles       []RecentFileDashboard    `json:"recent_files"`
	CollectionKeys    []DashboardCollectionKey `json:"collection_keys,omitempty"`
}

// DashboardCollectionKey contains the encrypted collection key for client-side decryption
// This allows clients to decrypt file metadata without making additional API calls
type DashboardCollectionKey struct {
	CollectionID                string `json:"collection_id"`
	EncryptedCollectionKey      string `json:"encrypted_collection_key"`
	EncryptedCollectionKeyNonce string `json:"encrypted_collection_key_nonce"`
}

// DashboardResponse represents the dashboard response.
type DashboardResponse struct {
	Dashboard *Dashboard `json:"dashboard"`
	Success   bool       `json:"success"`
	Message   string     `json:"message"`
}

// DashboardSummary represents dashboard summary data.
type DashboardSummary struct {
	TotalFiles             int           `json:"total_files"`
	TotalFolders           int           `json:"total_folders"`
	StorageUsed            StorageAmount `json:"storage_used"`
	StorageLimit           StorageAmount `json:"storage_limit"`
	StorageUsagePercentage int           `json:"storage_usage_percentage"`
}

// StorageAmount represents a storage amount with value and unit.
type StorageAmount struct {
	Value float64 `json:"value"`
	Unit  string  `json:"unit"`
}

// StorageUsageTrend represents storage usage trend data.
type StorageUsageTrend struct {
	Period     string      `json:"period"`
	DataPoints []DataPoint `json:"data_points"`
}

// DataPoint represents a single data point in the usage trend.
type DataPoint struct {
	Date  string        `json:"date"`
	Usage StorageAmount `json:"usage"`
}

// RecentFileDashboard represents a recent file in the dashboard.
// Note: File metadata is E2EE encrypted. Clients should use locally cached
// decrypted data when available, or show placeholder text for cloud-only files.
type RecentFileDashboard struct {
	ID                       string               `json:"id"`
	CollectionID             string               `json:"collection_id"`
	OwnerID                  string               `json:"owner_id"`
	EncryptedMetadata        string               `json:"encrypted_metadata"`
	EncryptedFileKey         EncryptedFileKeyData `json:"encrypted_file_key"`
	EncryptionVersion        string               `json:"encryption_version"`
	EncryptedHash            string               `json:"encrypted_hash"`
	EncryptedFileSizeInBytes int64                `json:"encrypted_file_size_in_bytes"`
	CreatedAt                time.Time            `json:"created_at"`
	ModifiedAt               time.Time            `json:"modified_at"`
	Version                  uint64               `json:"version"`
	State                    string               `json:"state"`
}

// -----------------------------------------------------------------------------
// Collection Types
// -----------------------------------------------------------------------------

// EncryptedKeyData represents an encrypted key with its nonce (used for collections and tags)
type EncryptedKeyData struct {
	Ciphertext string `json:"ciphertext"`
	Nonce      string `json:"nonce"`
}

// Collection represents a file collection (folder).
type Collection struct {
	ID                       string            `json:"id"`
	ParentID                 string            `json:"parent_id,omitempty"`
	UserID                   string            `json:"user_id"`
	Name                     string            `json:"name"`
	Description              string            `json:"description,omitempty"`
	EncryptedCollectionKey   EncryptedKeyData  `json:"encrypted_collection_key"`
	// CustomIcon is the decrypted custom icon for this collection.
	// Empty string means use default folder/album icon.
	// Contains either an emoji character (e.g., "📷") or "icon:<identifier>" for predefined icons.
	CustomIcon               string    `json:"custom_icon,omitempty"`
	// EncryptedCustomIcon is the encrypted version of CustomIcon (for sync operations).
	EncryptedCustomIcon      string    `json:"encrypted_custom_icon,omitempty"`
	TotalFiles               int       `json:"total_files"`
	TotalSizeInBytes         int64     `json:"total_size_in_bytes"`
	State                    string    `json:"state"`
	CreatedAt                time.Time `json:"created_at"`
	ModifiedAt               time.Time `json:"modified_at"`
	SharedWith               []Share   `json:"shared_with,omitempty"`
	PermissionLevel          string    `json:"permission_level,omitempty"`
	IsOwner                  bool          `json:"is_owner"`
	OwnerName                string        `json:"owner_name,omitempty"`
	OwnerEmail               string        `json:"owner_email,omitempty"`
	Tags                     []EmbeddedTag `json:"tags,omitempty"` // Tags assigned to this collection
}

// Share represents a collection sharing entry.
type Share struct {
	UserID          string    `json:"user_id"`
	Email           string    `json:"email"`
	Name            string    `json:"name"`
	PermissionLevel string    `json:"permission_level"`
	SharedAt        time.Time `json:"shared_at"`
}

// CreateCollectionInput represents the collection creation request.
type CreateCollectionInput struct {
	ParentID                 string `json:"parent_id,omitempty"`
	Name                     string `json:"name"`
	Description              string `json:"description,omitempty"`
	EncryptedCollectionKey   string `json:"encrypted_collection_key"`
	Nonce                    string `json:"nonce"`
}

// UpdateCollectionInput represents the collection update request.
type UpdateCollectionInput struct {
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
}

// MoveCollectionInput represents the collection move request.
type MoveCollectionInput struct {
	NewParentID string `json:"new_parent_id"`
}

// ShareCollectionInput represents the collection sharing request.
type ShareCollectionInput struct {
	Email                    string `json:"email"`
	PermissionLevel          string `json:"permission_level"` // "read_only", "read_write", "admin"
	EncryptedCollectionKey   string `json:"encrypted_collection_key"`
	Nonce                    string `json:"nonce"`
}

// CollectionFilter represents filters for listing collections.
type CollectionFilter struct {
	State    string `json:"state,omitempty"`    // "active", "archived", "trashed"
	ParentID string `json:"parent_id,omitempty"`
}

// SyncInput represents the sync request.
type SyncInput struct {
	Cursor string `json:"cursor,omitempty"`
	Limit  int64  `json:"limit,omitempty"`
}

// CollectionSyncResponse represents the collection sync response.
type CollectionSyncResponse struct {
	Collections []*Collection `json:"collections"`
	NextCursor  string        `json:"next_cursor,omitempty"`
	HasMore     bool          `json:"has_more"`
}

// -----------------------------------------------------------------------------
// File Types
// -----------------------------------------------------------------------------

// EncryptedFileKeyData represents the encrypted file key structure returned by the API.
type EncryptedFileKeyData struct {
	Ciphertext string `json:"ciphertext"`
	Nonce      string `json:"nonce"`
}

// File represents a file in a collection.
type File struct {
	ID                     string               `json:"id"`
	CollectionID           string               `json:"collection_id"`
	UserID                 string               `json:"user_id"`
	EncryptedFileKey       EncryptedFileKeyData `json:"encrypted_file_key"`
	FileKeyNonce           string               `json:"file_key_nonce"`
	EncryptedMetadata      string               `json:"encrypted_metadata"`
	MetadataNonce          string               `json:"metadata_nonce"`
	FileNonce              string               `json:"file_nonce"`
	EncryptedSizeInBytes   int64                `json:"encrypted_file_size_in_bytes"`
	DecryptedSizeInBytes   int64                `json:"decrypted_size_in_bytes,omitempty"`
	State                  string               `json:"state"`
	StorageMode            string               `json:"storage_mode"`
	Version                int                  `json:"version"`
	CreatedAt              time.Time            `json:"created_at"`
	ModifiedAt             time.Time            `json:"modified_at"`
	ThumbnailURL           string               `json:"thumbnail_url,omitempty"`
	Tags                   []*EmbeddedTag       `json:"tags,omitempty"`
}

// PendingFile represents a file in pending state (awaiting upload).
type PendingFile struct {
	ID           string `json:"id"`
	CollectionID string `json:"collection_id"`
	State        string `json:"state"`
}

// CreateFileInput represents the file creation request.
type CreateFileInput struct {
	CollectionID         string `json:"collection_id"`
	EncryptedFileKey     string `json:"encrypted_file_key"`
	FileKeyNonce         string `json:"file_key_nonce"`
	EncryptedMetadata    string `json:"encrypted_metadata"`
	MetadataNonce        string `json:"metadata_nonce"`
	FileNonce            string `json:"file_nonce"`
	EncryptedSizeInBytes int64  `json:"encrypted_size_in_bytes"`
}

// UpdateFileInput represents the file update request.
type UpdateFileInput struct {
	EncryptedMetadata string `json:"encrypted_metadata,omitempty"`
	MetadataNonce     string `json:"metadata_nonce,omitempty"`
}

// CompleteUploadInput represents the file upload completion request.
type CompleteUploadInput struct {
	ActualFileSizeInBytes int64 `json:"actual_file_size_in_bytes"`
	UploadConfirmed       bool  `json:"upload_confirmed"`
}

// PresignedURL represents a presigned upload URL response.
type PresignedURL struct {
	URL       string `json:"url"`
	ExpiresAt string `json:"expires_at"`
}

// PresignedDownloadResponse represents a presigned download URL response.
type PresignedDownloadResponse struct {
	FileURL      string `json:"file_url"`
	ThumbnailURL string `json:"thumbnail_url,omitempty"`
	ExpiresAt    string `json:"expires_at"`
}

// DeleteMultipleFilesInput represents the multiple files deletion request.
type DeleteMultipleFilesInput struct {
	FileIDs []string `json:"file_ids"`
}

// FileSyncResponse represents the file sync response.
type FileSyncResponse struct {
	Files      []*File `json:"files"`
	NextCursor string  `json:"next_cursor,omitempty"`
	HasMore    bool    `json:"has_more"`
}

// ListFilesResponse represents the list files response.
type ListFilesResponse struct {
	Files []*File `json:"files"`
	Count int     `json:"count"`
}

// -----------------------------------------------------------------------------
// Tag Types
// -----------------------------------------------------------------------------

// Tag represents a user-defined label with color that can be assigned to collections or files.
// All sensitive data (name, color) is encrypted end-to-end.
type Tag struct {
	ID              string              `json:"id"`
	UserID          string              `json:"user_id"`
	EncryptedName   string              `json:"encrypted_name"`
	EncryptedColor  string              `json:"encrypted_color"`
	EncryptedTagKey *EncryptedTagKey    `json:"encrypted_tag_key"`
	CreatedAt       time.Time           `json:"created_at"`
	ModifiedAt      time.Time           `json:"modified_at"`
	Version         uint64              `json:"version"`
	State           string              `json:"state"`
}

// EncryptedTagKey represents the encrypted tag key data
type EncryptedTagKey struct {
	Ciphertext string `json:"ciphertext"` // Base64 encoded
	Nonce      string `json:"nonce"`      // Base64 encoded
	KeyVersion int    `json:"key_version,omitempty"`
}

// EmbeddedTag represents tag data that is embedded in collections and files
// This eliminates the need for frontend API lookups to get tag colors
type EmbeddedTag struct {
	ID              string           `json:"id"`
	EncryptedName   string           `json:"encrypted_name"`
	EncryptedColor  string           `json:"encrypted_color"`
	EncryptedTagKey *EncryptedTagKey `json:"encrypted_tag_key"`
	ModifiedAt      time.Time        `json:"modified_at"`
}

// CreateTagInput represents the tag creation request
type CreateTagInput struct {
	ID              string           `json:"id"`
	EncryptedName   string           `json:"encrypted_name"`
	EncryptedColor  string           `json:"encrypted_color"`
	EncryptedTagKey *EncryptedTagKey `json:"encrypted_tag_key"`
	CreatedAt       string           `json:"created_at"`
	ModifiedAt      string           `json:"modified_at"`
	Version         uint64           `json:"version"`
	State           string           `json:"state"`
}

// UpdateTagInput represents the tag update request
type UpdateTagInput struct {
	EncryptedName   string           `json:"encrypted_name,omitempty"`
	EncryptedColor  string           `json:"encrypted_color,omitempty"`
	EncryptedTagKey *EncryptedTagKey `json:"encrypted_tag_key"`
	CreatedAt       string           `json:"created_at"`
	ModifiedAt      string           `json:"modified_at"`
	Version         uint64           `json:"version"`
	State           string           `json:"state"`
}

// ListTagsResponse represents the list tags response
type ListTagsResponse struct {
	Tags []*Tag `json:"tags"`
}

// TagAssignment represents the assignment of a tag to a collection or file
type TagAssignment struct {
	ID         string    `json:"id"`
	UserID     string    `json:"user_id"`
	TagID      string    `json:"tag_id"`
	EntityID   string    `json:"entity_id"`
	EntityType string    `json:"entity_type"` // "collection" or "file"
	CreatedAt  time.Time `json:"created_at"`
}

// CreateTagAssignmentInput represents the tag assignment request
type CreateTagAssignmentInput struct {
	TagID      string `json:"tag_id"`
	EntityID   string `json:"entity_id"`
	EntityType string `json:"entity_type"`
}

// ListTagAssignmentsResponse represents the list tag assignments response
type ListTagAssignmentsResponse struct {
	TagAssignments []*TagAssignment `json:"tag_assignments"`
}

// SearchByTagsResponse represents the unified search by tags response
type SearchByTagsResponse struct {
	Collections     []*Collection `json:"collections"`
	Files           []*File       `json:"files"`
	TagCount        int           `json:"tag_count"`
	CollectionCount int           `json:"collection_count"`
	FileCount       int           `json:"file_count"`
}
