package gateway

import (
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"strings"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httpvalidation"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/validation"
)

var (
	ErrInvalidLoginRequest = errors.New("invalid login request")
	ErrMissingEmail        = errors.New("email is required")
	ErrInvalidEmail        = errors.New("invalid email format")
	ErrMissingPassword     = errors.New("password is required")
)

// LoginRequestDTO represents the login request payload
type LoginRequestDTO struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

// Validate validates the login request
// CWE-20: Improper Input Validation - Validates email format before authentication
func (dto *LoginRequestDTO) Validate() error {
	// Validate email format
	validator := validation.NewValidator()
	if err := validator.ValidateEmail(dto.Email, "email"); err != nil {
		return ErrInvalidEmail
	}

	// Normalize email (lowercase, trim whitespace)
	dto.Email = strings.ToLower(strings.TrimSpace(dto.Email))

	// Validate password (non-empty)
	if strings.TrimSpace(dto.Password) == "" {
		return ErrMissingPassword
	}

	return nil
}

// ParseLoginRequest parses and validates a login request from HTTP request body
func ParseLoginRequest(r *http.Request) (*LoginRequestDTO, error) {
	// CWE-436: Validate Content-Type before parsing
	if err := httpvalidation.RequireJSONContentType(r); err != nil {
		return nil, err
	}

	// Read body
	body, err := io.ReadAll(r.Body)
	if err != nil {
		return nil, ErrInvalidLoginRequest
	}
	defer r.Body.Close()

	// Parse JSON
	var dto LoginRequestDTO
	if err := json.Unmarshal(body, &dto); err != nil {
		return nil, ErrInvalidLoginRequest
	}

	// Validate
	if err := dto.Validate(); err != nil {
		return nil, err
	}

	return &dto, nil
}
