package services

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

// LocalBackend stores files on the local filesystem.
type LocalBackend struct {
	baseDir string
}

// NewLocalBackend creates a local filesystem storage backend.
// It ensures the base directory and standard subdirectories exist.
func NewLocalBackend(baseDir string) (*LocalBackend, error) {
	if err := os.MkdirAll(baseDir, 0755); err != nil {
		return nil, fmt.Errorf("failed to create upload directory: %w", err)
	}

	for _, subdir := range []string{"images", "documents", "completions"} {
		path := filepath.Join(baseDir, subdir)
		if err := os.MkdirAll(path, 0755); err != nil {
			return nil, fmt.Errorf("failed to create subdirectory %s: %w", subdir, err)
		}
	}

	return &LocalBackend{baseDir: baseDir}, nil
}

func (b *LocalBackend) Write(key string, data []byte) error {
	destPath, err := SafeResolvePath(b.baseDir, key)
	if err != nil {
		return fmt.Errorf("invalid path: %w", err)
	}
	return os.WriteFile(destPath, data, 0644)
}

func (b *LocalBackend) Read(key string) ([]byte, error) {
	fullPath, err := SafeResolvePath(b.baseDir, key)
	if err != nil {
		return nil, fmt.Errorf("invalid path: %w", err)
	}
	return os.ReadFile(fullPath)
}

func (b *LocalBackend) Delete(key string) error {
	fullPath, err := SafeResolvePath(b.baseDir, key)
	if err != nil {
		return nil // invalid path = nothing to delete
	}
	if err := os.Remove(fullPath); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("failed to delete file: %w", err)
	}
	return nil
}

func (b *LocalBackend) ReadStream(key string) (io.ReadCloser, error) {
	fullPath, err := SafeResolvePath(b.baseDir, key)
	if err != nil {
		return nil, fmt.Errorf("invalid path: %w", err)
	}
	return os.Open(fullPath)
}

// BaseDir returns the local storage base directory.
func (b *LocalBackend) BaseDir() string {
	return b.baseDir
}
