package auth

import (
	"net/http"

	"github.com/gorilla/sessions"
)

// SessionManager manages user sessions
type SessionManager struct {
	store    *sessions.CookieStore
	options  *sessions.Options
}

// Session keys
const (
	SessionKeyUserEmail = "user_email"
	SessionKeyLoggedIn  = "logged_in"
)

// NewSessionManager creates a new session manager with the given secret key
func NewSessionManager(secretKey string) *SessionManager {
	store := sessions.NewCookieStore([]byte(secretKey))
	
	// Secure session options
	options := &sessions.Options{
		Path:     "/",
		MaxAge:   86400 * 7, // 7 days
		HttpOnly: true,
		Secure:   true, // Requires HTTPS
		SameSite: http.SameSiteStrictMode,
	}

	return &SessionManager{
		store:   store,
		options: options,
	}
}

// CreateSession creates a new session for the user
func (sm *SessionManager) CreateSession(w http.ResponseWriter, r *http.Request, email string) error {
	session, err := sm.store.Get(r, "inboxer_session")
	if err != nil {
		return err
	}

	session.Values[SessionKeyUserEmail] = email
	session.Values[SessionKeyLoggedIn] = true
	session.Options = sm.options

	return session.Save(r, w)
}

// GetUserEmail returns the email from the session if the user is logged in
func (sm *SessionManager) GetUserEmail(r *http.Request) (string, bool) {
	session, err := sm.store.Get(r, "inboxer_session")
	if err != nil {
		return "", false
	}

	// Check if logged in
	loggedIn, ok := session.Values[SessionKeyLoggedIn].(bool)
	if !ok || !loggedIn {
		return "", false
	}

	email, ok := session.Values[SessionKeyUserEmail].(string)
	if !ok {
		return "", false
	}

	return email, true
}

// DestroySession removes the user session (logout)
func (sm *SessionManager) DestroySession(w http.ResponseWriter, r *http.Request) error {
	session, err := sm.store.Get(r, "inboxer_session")
	if err != nil {
		return err
	}

	// Clear session values
	session.Values = make(map[interface{}]interface{})
	session.Options = &sessions.Options{
		Path:     "/",
		MaxAge:   -1, // Immediately expire
		HttpOnly: true,
	}

	return session.Save(r, w)
}

// IsLoggedIn checks if the user is logged in
func (sm *SessionManager) IsLoggedIn(r *http.Request) bool {
	session, err := sm.store.Get(r, "inboxer_session")
	if err != nil {
		return false
	}

	loggedIn, ok := session.Values[SessionKeyLoggedIn].(bool)
	return ok && loggedIn
}

// UpdateSessionOptions updates session options (e.g., for development without HTTPS)
func (sm *SessionManager) UpdateSessionOptions(secure bool, maxAge int) {
	sm.options.Secure = secure
	sm.options.MaxAge = maxAge
}