package auth

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/titanappdev/rofs/apps/world/internal/redis"
)

const ticketKeyPrefix = "ws_ticket:"

// TicketPayload is stored in Redis by the PHP API when issuing a WebSocket ticket.
type TicketPayload struct {
	AccountID   int `json:"account_id"`
	CharacterID int `json:"character_id"`
	TileX       int `json:"tile_x"`
	TileY       int `json:"tile_y"`
	IssuedAt    int `json:"issued_at"`
}

// Validator consumes one-time WebSocket tickets from Redis.
type Validator struct {
	redis *redis.Client
}

func NewValidator(r *redis.Client) *Validator {
	return &Validator{redis: r}
}

func (v *Validator) ValidateAndConsume(ctx context.Context, ticket string) (*TicketPayload, error) {
	key := ticketKeyPrefix + ticket
	raw, err := v.redis.Get(ctx, key)
	if err != nil {
		return nil, fmt.Errorf("redis get ticket: %w", err)
	}
	if raw == "" {
		return nil, fmt.Errorf("invalid or expired ticket")
	}

	var payload TicketPayload
	if err := json.Unmarshal([]byte(raw), &payload); err != nil {
		return nil, fmt.Errorf("unmarshal ticket: %w", err)
	}

	if err := v.redis.Del(ctx, key); err != nil {
		return nil, fmt.Errorf("consume ticket: %w", err)
	}

	return &payload, nil
}
