package auth

import (
	"context"
	"crypto/rand"
	"database/sql"
	"encoding/hex"
	"fmt"
	"time"

	"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/config"
)

type SessionStore struct {
	db  *sql.DB
	cfg *config.Config
}

func NewSessionStore(db *sql.DB, cfg *config.Config) *SessionStore {
	return &SessionStore{db: db, cfg: cfg}
}

func (s *SessionStore) Create(ctx context.Context, userID string) (string, error) {
	b := make([]byte, 32)
	if _, err := rand.Read(b); err != nil {
		return "", fmt.Errorf("generate token: %w", err)
	}
	token := hex.EncodeToString(b)

	_, err := s.db.ExecContext(ctx, `
		INSERT INTO sessions (user_id, token, expires_at)
		VALUES ($1, $2, $3)
	`, userID, token, time.Now().Add(s.cfg.Session.Duration))
	if err != nil {
		return "", fmt.Errorf("insert session: %w", err)
	}

	return token, nil
}

func (s *SessionStore) GetUserIDByToken(ctx context.Context, token string) (string, error) {
	var userID string
	err := s.db.QueryRowContext(ctx, `
		SELECT user_id FROM sessions
		WHERE token = $1 AND expires_at > NOW()
	`, token).Scan(&userID)
	if err != nil {
		return "", err
	}
	return userID, nil
}

func (s *SessionStore) Delete(ctx context.Context, token string) error {
	_, err := s.db.ExecContext(ctx, `DELETE FROM sessions WHERE token = $1`, token)
	return err
}
