package cauth

import (
	"context"
	"encoding/gob"
	"log"
	"net/http"

	"github.com/coreos/go-oidc/v3/oidc"
	"github.com/gorilla/sessions"
	"github.com/rbcervilla/redisstore/v9"
	"github.com/redis/go-redis/v9"
	"golang.org/x/oauth2"
)

const SESSION_NAME = "auth-session"

type RedisSession struct {
	store *redisstore.RedisStore
}

type RedisSessionParams struct {
	RedisAddress  string
	RedisPassword string
	// SessionSecret []byte
}

type SessionStorer interface {
	Get(r *http.Request) (*sessions.Session, error)
}

func NewRedisSessionStore(params RedisSessionParams) (SessionStorer, error) {
	gob.Register(&oauth2.Token{})
	gob.Register(oidc.IDToken{})
	gob.Register(Identity{})
	gob.Register(UserClaims{})
	client := redis.NewClient(&redis.Options{
		Addr:     params.RedisAddress,
		Password: params.RedisPassword,
	})

	store, err := redisstore.NewRedisStore(context.Background(), client)
	if err != nil {
		log.Fatal("failed to create redis store: ", err)
	}

	store.KeyPrefix("session_")
	store.Options(sessions.Options{
		Path:     "/",
		MaxAge:   86400 * 7,
		HttpOnly: true,
		Secure:   true,
		SameSite: http.SameSiteLaxMode,
	})

	return &RedisSession{
		store: store,
	}, nil
}

func (s *RedisSession) Get(r *http.Request) (*sessions.Session, error) {
	return s.store.Get(r, SESSION_NAME)
}