package filemanager

import (
	"context"
	"time"
)

type FolderRepository interface {
	Create(ctx context.Context, row *Folder) error
	Update(ctx context.Context, row *Folder) error
	MoveSubtree(ctx context.Context, id []byte, targetParentID []byte, targetName string, targetNameNormalized string, updatedBy []byte) (*Folder, error)
	Delete(ctx context.Context, id []byte, deletedBy []byte, purgeAt *time.Time) error
	Restore(ctx context.Context, id []byte, restoredBy []byte) error
	Purge(ctx context.Context, id []byte) error
	GetByID(ctx context.Context, id []byte) (*Folder, error)
	GetByIDAny(ctx context.Context, id []byte) (*Folder, error)
	GetByParentAndName(ctx context.Context, parentID []byte, nameNormalized string) (*Folder, error)
	ListByParent(ctx context.Context, parentID []byte, sort string, limit, offset int) ([]Folder, int64, error)
	SearchByName(ctx context.Context, name string, sort string, limit, offset int) ([]Folder, int64, error)
	ListTrash(ctx context.Context, sort string, limit, offset int) ([]Folder, int64, error)
	ListTrashByParent(ctx context.Context, parentID []byte, sort string, limit, offset int) ([]Folder, int64, error)
}

type FileFinalizeParams struct {
	ID             []byte
	ExpectedFrom   string
	FolderID       []byte
	Name           string
	NameNormalized string
	Extension      string
	UpdatedBy      []byte
}

type FileStatusTransitionParams struct {
	ID                  []byte
	ExpectedFrom        string
	To                  string
	UpdatedBy           []byte
	ProcessingStartedAt *time.Time
	ProcessedAt         *time.Time
	ValidatedAt         *time.Time
	FailedAt            *time.Time
	FailureReason       *string
}

type FileRepository interface {
	Create(ctx context.Context, row *File) error
	Update(ctx context.Context, row *File) error
	TransitionStatus(ctx context.Context, params FileStatusTransitionParams) error
	Finalize(ctx context.Context, params FileFinalizeParams) error
	Delete(ctx context.Context, id []byte, deletedBy []byte, purgeAt *time.Time) error
	Restore(ctx context.Context, id []byte, restoredBy []byte) error
	Purge(ctx context.Context, id []byte) error
	GetByID(ctx context.Context, id []byte) (*File, error)
	GetByIDAny(ctx context.Context, id []byte) (*File, error)
	GetByObjectKey(ctx context.Context, objectKey string) (*File, error)
	GetByFolderAndName(ctx context.Context, folderID []byte, nameNormalized string) (*File, error)
	GetByTemplateAndTakeover(ctx context.Context, templateUUID, takeoverID []byte) (*File, error)
	ListEditedTemplatesByTakeoverID(ctx context.Context, takeoverID []byte) ([]File, error)
	ListByFolder(ctx context.Context, folderID []byte, sort string, limit, offset int) ([]File, int64, error)
	SearchByName(ctx context.Context, name string, sort string, limit, offset int) ([]File, int64, error)
	ListTrashByFolder(ctx context.Context, folderID []byte, sort string, limit, offset int) ([]File, int64, error)
}

type FileLifecycleTransitionParams struct {
	ID              []byte
	Status          string
	UpdatedBy       []byte
	AttachedAt      *time.Time
	OrphanedAt      *time.Time
	LifecycleDelete *time.Time
	ClearOrphanedAt bool
}

type FileLifecycleListFilter struct {
	Status                  string
	OrphanedBeforeEq        *time.Time
	CreatedBeforeEq         *time.Time
	ExcludeInTrash          bool
	ExcludeLifecycleDeleted bool
	Limit                   int
}

type FileLifecycleRepository interface {
	UpdateLifecycle(ctx context.Context, params FileLifecycleTransitionParams) error
	IsFileReferenced(ctx context.Context, fileID []byte) (bool, error)
	ListFilesByLifecycle(ctx context.Context, filter FileLifecycleListFilter) ([]File, error)
}

type FileUploadIntentCompleteParams struct {
	ID          []byte
	UpdatedBy   []byte
	CompletedAt time.Time
}

type FileUploadIntentExpireParams struct {
	ID        []byte
	UpdatedBy []byte
	ExpiredAt time.Time
}

type FileUploadIntentSizeUpdateParams struct {
	ID        []byte
	SizeBytes int64
	UpdatedBy []byte
}

type FileUploadIntentRepository interface {
	CreateUploadIntent(ctx context.Context, row *FileUploadIntent) error
	GetUploadIntentByID(ctx context.Context, id []byte) (*FileUploadIntent, error)
	GetUploadIntentByIDForUpdate(ctx context.Context, id []byte) (*FileUploadIntent, error)
	MarkUploadIntentCompleted(ctx context.Context, params FileUploadIntentCompleteParams) error
	MarkUploadIntentExpired(ctx context.Context, params FileUploadIntentExpireParams) error
}

type AttachmentListFilter struct {
	RefType  string
	RefID    string
	Category *string
	Sort     string
	Limit    int
	Offset   int
}

type AttachmentRepository interface {
	Create(ctx context.Context, row *Attachment) error
	Delete(ctx context.Context, id []byte) error
	GetByID(ctx context.Context, id []byte) (*Attachment, error)
	GetByRefAndFile(ctx context.Context, refType, refID string, fileID []byte) (*Attachment, error)
	ListByReference(ctx context.Context, filter AttachmentListFilter) ([]Attachment, int64, error)
}
