package files

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type Service struct {
	root string
}

type StoredFile struct {
	OriginalName string
	RelativePath string
	AbsolutePath string
}

func NewService(root string) *Service {
	return &Service{root: root}
}

func (s *Service) Save(projectID uint, originalName string, content io.Reader) (StoredFile, error) {
	cleanName := filepath.Base(strings.ReplaceAll(strings.TrimSpace(originalName), "\\", "/"))
	if cleanName == "." || cleanName == "" {
		cleanName = "upload.bin"
	}
	relative := filepath.ToSlash(filepath.Join("projects", fmt.Sprint(projectID), fmt.Sprintf("%d-%s", time.Now().UnixNano(), cleanName)))
	absolute := filepath.Join(s.root, filepath.FromSlash(relative))
	if err := os.MkdirAll(filepath.Dir(absolute), 0o755); err != nil {
		return StoredFile{}, err
	}
	file, err := os.Create(absolute)
	if err != nil {
		return StoredFile{}, err
	}
	defer file.Close()
	if _, err := io.Copy(file, content); err != nil {
		return StoredFile{}, err
	}
	return StoredFile{OriginalName: cleanName, RelativePath: relative, AbsolutePath: absolute}, nil
}
