package session

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"

	"github.com/paramah/ai_devs4/s01e03/internal/domain"
)

// FileStorage implements domain.SessionStorage using JSON files
type FileStorage struct {
	baseDir string
}

// NewFileStorage creates a new file-based session storage
func NewFileStorage(baseDir string) *FileStorage {
	return &FileStorage{
		baseDir: baseDir,
	}
}

// Get retrieves a session from file storage
func (s *FileStorage) Get(ctx context.Context, sessionID string) (*domain.Session, error) {
	filePath := s.getFilePath(sessionID)

	// Check if file exists
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		// Return empty session if file doesn't exist
		return &domain.Session{
			ID:       sessionID,
			Messages: []domain.Message{},
		}, nil
	}

	data, err := os.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("reading session file: %w", err)
	}

	var session domain.Session
	if err := json.Unmarshal(data, &session); err != nil {
		return nil, fmt.Errorf("unmarshaling session: %w", err)
	}

	return &session, nil
}

// Save saves a session to file storage
func (s *FileStorage) Save(ctx context.Context, session *domain.Session) error {
	filePath := s.getFilePath(session.ID)

	// Ensure directory exists
	if err := os.MkdirAll(s.baseDir, 0755); err != nil {
		return fmt.Errorf("creating cache directory: %w", err)
	}

	data, err := json.MarshalIndent(session, "", "  ")
	if err != nil {
		return fmt.Errorf("marshaling session: %w", err)
	}

	if err := os.WriteFile(filePath, data, 0644); err != nil {
		return fmt.Errorf("writing session file: %w", err)
	}

	return nil
}

func (s *FileStorage) getFilePath(sessionID string) string {
	return filepath.Join(s.baseDir, fmt.Sprintf("%s.json", sessionID))
}
