package services

import (
	"errors"
	"fmt"
	"time"

	"github.com/golang-jwt/jwt/v5"
	"go.uber.org/zap"
)

type ChatService struct {
	jwtSecret string
	logger    *zap.Logger
}

func NewChatService(jwtSecret string, logger *zap.Logger) *ChatService {
	if logger == nil {
		logger = zap.NewNop()
	}
	return &ChatService{
		jwtSecret: jwtSecret,
		logger:    logger,
	}
}

type ChatTokenResponse struct {
	Token     string `json:"token"`
	ExpiresIn int64  `json:"expires_in"`
	WSUrl     string `json:"ws_url"`
}

func (s *ChatService) GenerateToken(userID int64, username string) (*ChatTokenResponse, error) {
	if s.jwtSecret == "" {
		return nil, errors.New("JWT secret is not configured")
	}

	now := time.Now()
	expiration := 15 * time.Minute
	exp := now.Add(expiration)

	claims := jwt.MapClaims{
		"sub":  fmt.Sprintf("%d", userID),
		"name": username,
		"aud":  "veza-chat",
		"iss":  "veza-backend",
		"iat":  now.Unix(),
		"exp":  exp.Unix(),
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(s.jwtSecret))
	if err != nil {
		return nil, fmt.Errorf("failed to sign token: %w", err)
	}

	return &ChatTokenResponse{
		Token:     tokenString,
		ExpiresIn: int64(expiration.Seconds()),
		WSUrl:     "/ws", // Relative path, frontend appends base URL
	}, nil
}
