package handlers

import (
	"context"
	"net/http"
	"time"

	"git.haelnorr.com/h/golib/hws"
	"git.haelnorr.com/h/golib/hwsauth"
	"git.haelnorr.com/h/oslstats/internal/db"
	"git.haelnorr.com/h/oslstats/internal/discord"
	"github.com/pkg/errors"
	"github.com/uptrace/bun"
)

func Logout(
	server *hws.Server,
	auth *hwsauth.Authenticator[*db.User, bun.Tx],
	conn *bun.DB,
	discordAPI *discord.APIClient,
) http.Handler {
	return http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
			defer cancel()

			tx, err := conn.BeginTx(ctx, nil)
			if err != nil {
				throwInternalServiceError(server, w, r, "Database error", errors.Wrap(err, "conn.BeginTx"))
				return
			}
			defer tx.Rollback()

			user := db.CurrentUser(r.Context())
			if user == nil {
				// JIC - should be impossible to get here if route is protected by LoginReq
				w.Header().Set("HX-Redirect", "/")
				return
			}
			token, err := user.DeleteDiscordTokens(ctx, tx)
			if err != nil {
				throwInternalServiceError(server, w, r, "Database error", errors.Wrap(err, "user.DeleteDiscordTokens"))
				return
			}
			err = discordAPI.RevokeToken(token.Convert())
			if err != nil {
				throwInternalServiceError(server, w, r, "Discord API error", errors.Wrap(err, "discordAPI.RevokeToken"))
				return
			}
			err = auth.Logout(tx, w, r)
			if err != nil {
				throwInternalServiceError(server, w, r, "Logout failed", err)
				return
			}
			tx.Commit()
			w.Header().Set("HX-Redirect", "/")
		},
	)
}
