package models

import (
	"apskel-pos-be/internal/constants"
	"time"

	"github.com/google/uuid"
)

type File struct {
	ID             uuid.UUID
	OrganizationID uuid.UUID
	UserID         uuid.UUID
	FileName       string
	OriginalName   string
	FileURL        string
	FileSize       int64
	MimeType       string
	FileType       string
	UploadPath     string
	IsPublic       bool
	Metadata       map[string]interface{}
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

// Request DTOs
type UploadFileRequest struct {
	FileType constants.FileType `validate:"required"`
	IsPublic *bool              `validate:"omitempty"`
	Metadata map[string]interface{}
}

type UpdateFileRequest struct {
	IsPublic *bool `validate:"omitempty"`
	Metadata map[string]interface{}
}

type ListFilesRequest struct {
	OrganizationID *uuid.UUID
	UserID         *uuid.UUID
	FileType       *constants.FileType
	IsPublic       *bool
	DateFrom       *time.Time
	DateTo         *time.Time
	Search         string
	Page           int `validate:"required,min=1"`
	Limit          int `validate:"required,min=1,max=100"`
}

// Response DTOs
type FileResponse struct {
	ID             uuid.UUID
	OrganizationID uuid.UUID
	UserID         uuid.UUID
	FileName       string
	OriginalName   string
	FileURL        string
	FileSize       int64
	MimeType       string
	FileType       string
	UploadPath     string
	IsPublic       bool
	Metadata       map[string]interface{}
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type ListFilesResponse struct {
	Files      []*FileResponse
	TotalCount int
	Page       int
	Limit      int
	TotalPages int
}

type UploadFileResponse struct {
	File FileResponse
}

// Helper methods
func (f *File) IsImage() bool {
	return f.FileType == string(constants.FileTypeImage)
}

func (f *File) IsDocument() bool {
	return f.FileType == string(constants.FileTypeDocument)
}

func (f *File) IsVideo() bool {
	return f.FileType == string(constants.FileTypeVideo)
}

func (f *File) GetFileExtension() string {
	// Extract extension from original name
	for i := len(f.OriginalName) - 1; i >= 0; i-- {
		if f.OriginalName[i] == '.' {
			return f.OriginalName[i:]
		}
	}
	return ""
}
