package entities

import (
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

// DocumentSession represents an OnlyOffice document editing session
type DocumentSession struct {
	ID          uuid.UUID  `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
	DocumentID  uuid.UUID  `gorm:"type:uuid;not null;index" json:"document_id"`
	DocumentKey string     `gorm:"uniqueIndex;not null" json:"document_key"` // OnlyOffice document key
	UserID      uuid.UUID  `gorm:"type:uuid;not null" json:"user_id"`
	Status      int        `gorm:"not null;default:0" json:"status"` // OnlyOffice status codes
	IsLocked    bool       `gorm:"default:false" json:"is_locked"`
	LockedBy    *uuid.UUID `gorm:"type:uuid" json:"locked_by,omitempty"`
	LockedAt    *time.Time `json:"locked_at,omitempty"`
	LastSavedAt *time.Time `json:"last_saved_at,omitempty"`
	Version     int        `gorm:"not null;default:1" json:"version"`
	CreatedAt   time.Time  `gorm:"autoCreateTime" json:"created_at"`
	UpdatedAt   time.Time  `gorm:"autoUpdateTime" json:"updated_at"`

	// Relations
	User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
}

func (DocumentSession) TableName() string {
	return "document_sessions"
}

func (ds *DocumentSession) BeforeCreate(tx *gorm.DB) error {
	if ds.ID == uuid.Nil {
		ds.ID = uuid.New()
	}
	return nil
}

// DocumentVersion represents a version of a document
type DocumentVersion struct {
	ID         uuid.UUID  `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
	DocumentID uuid.UUID  `gorm:"type:uuid;not null;index" json:"document_id"`
	Version    int        `gorm:"not null" json:"version"`
	FileURL    string     `gorm:"not null" json:"file_url"`
	FileSize   int64      `gorm:"not null" json:"file_size"`
	ChangesURL *string    `json:"changes_url,omitempty"`
	SavedBy    uuid.UUID  `gorm:"type:uuid;not null" json:"saved_by"`
	SavedAt    time.Time  `gorm:"not null" json:"saved_at"`
	IsActive   bool       `gorm:"default:false;index" json:"is_active"`
	Comments   *string    `json:"comments,omitempty"`
	CreatedAt  time.Time  `gorm:"autoCreateTime" json:"created_at"`

	// Relations
	User *User `gorm:"foreignKey:SavedBy" json:"user,omitempty"`
}

func (DocumentVersion) TableName() string {
	return "document_versions"
}

func (dv *DocumentVersion) BeforeCreate(tx *gorm.DB) error {
	if dv.ID == uuid.Nil {
		dv.ID = uuid.New()
	}
	return nil
}

// DocumentError represents errors during document operations
type DocumentError struct {
	ID         uuid.UUID              `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
	DocumentID uuid.UUID              `gorm:"type:uuid;not null;index" json:"document_id"`
	SessionID  *uuid.UUID             `gorm:"type:uuid" json:"session_id,omitempty"`
	ErrorType  string                 `gorm:"not null" json:"error_type"`
	ErrorMsg   string                 `gorm:"not null" json:"error_msg"`
	Details    map[string]interface{} `gorm:"type:jsonb" json:"details,omitempty"`
	CreatedAt  time.Time              `gorm:"autoCreateTime" json:"created_at"`

	// Relations
	Session *DocumentSession `gorm:"foreignKey:SessionID" json:"session,omitempty"`
}

func (DocumentError) TableName() string {
	return "document_errors"
}

func (de *DocumentError) BeforeCreate(tx *gorm.DB) error {
	if de.ID == uuid.Nil {
		de.ID = uuid.New()
	}
	return nil
}

// DocumentMetadata stores document-specific metadata
type DocumentMetadata struct {
	ID           uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
	DocumentID   uuid.UUID `gorm:"type:uuid;uniqueIndex;not null" json:"document_id"`
	DocumentType string    `gorm:"not null" json:"document_type"` // letter_attachment, outgoing_attachment, etc.
	ReferenceID  uuid.UUID `gorm:"type:uuid;not null" json:"reference_id"` // ID of the parent entity (letter, outgoing letter, etc.)
	FileName     string    `gorm:"not null" json:"file_name"`
	FileType     string    `gorm:"not null" json:"file_type"`
	FileSize     int64     `gorm:"not null" json:"file_size"`
	MimeType     string    `json:"mime_type,omitempty"`
	CreatedAt    time.Time `gorm:"autoCreateTime" json:"created_at"`
	UpdatedAt    time.Time `gorm:"autoUpdateTime" json:"updated_at"`
}

func (DocumentMetadata) TableName() string {
	return "document_metadata"
}

func (dm *DocumentMetadata) BeforeCreate(tx *gorm.DB) error {
	if dm.ID == uuid.Nil {
		dm.ID = uuid.New()
	}
	return nil
}