package identity

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

	"github.com/gin-gonic/gin"
)

// VerificationHandler manages HTTP requests for identity verification
type VerificationHandler struct {
	service *VerificationService
}

// NewVerificationHandler creates a new verification handler
func NewVerificationHandler() *VerificationHandler {
	service := NewVerificationService()

	// Get Privado API key and URL from environment
	privadoAPIKey := os.Getenv("PRIVADO_API_KEY")
	privadoAPIURL := os.Getenv("PRIVADO_API_URL")
	if privadoAPIKey == "" {
		privadoAPIKey = "development-key"
	}
	if privadoAPIURL == "" {
		privadoAPIURL = "https://api.privado.ai"
	}

	// Register default providers with Privado integration
	service.RegisterProvider(NewUSVerificationProvider(privadoAPIKey, privadoAPIURL))
	service.RegisterProvider(NewCanadaVerificationProvider(privadoAPIKey, privadoAPIURL))

	return &VerificationHandler{
		service: service,
	}
}

// VerificationRequest represents the JSON payload for verification requests
type VerificationRequest struct {
	Country                     string            `json:"country" binding:"required"`
	ZKPProof                    string            `json:"zkpProof" binding:"required"`
	SelfAttestedEligible        string            `json:"selfAttestedEligible"`
	LegalDisclaimerAcknowledged bool              `json:"legalDisclaimerAcknowledged"`
	AdditionalData              map[string]string `json:"additionalData"`
}

// VerificationResponse represents the JSON response for verification requests
type VerificationResponse struct {
	Status              string         `json:"status"`
	CitizenshipVerified bool           `json:"citizenshipVerified"`
	EligibilityVerified bool           `json:"eligibilityVerified"`
	Error               *ErrorResponse `json:"error,omitempty"`
}

// ErrorResponse provides a structured error response
type ErrorResponse struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

// LegalDisclaimerResponse provides the legal disclaimer text
type LegalDisclaimerResponse struct {
	DisclaimerText string `json:"disclaimerText"`
}

// HandleVerify handles the verification endpoint
func (h *VerificationHandler) HandleVerify(c *gin.Context) {
	var request VerificationRequest

	// Parse the request body
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": ErrorResponse{
				Code:    ErrorCodeInvalidInput,
				Message: "Invalid request format",
			},
		})
		return
	}

	// Create a timeout context
	ctx, cancel := context.WithTimeout(c.Request.Context(), 10*time.Second)
	defer cancel()

	// Prepare userData map from the request
	userData := make(map[string]string)

	// Add ZKP proof
	userData["zkpProof"] = request.ZKPProof

	// Add eligibility self-attestation if provided
	if request.SelfAttestedEligible != "" {
		userData["selfAttestedEligible"] = request.SelfAttestedEligible
	} else {
		userData["selfAttestedEligible"] = "false"
	}

	// Add legal disclaimer acknowledgment
	if request.LegalDisclaimerAcknowledged {
		userData["legalDisclaimerAcknowledged"] = "true"
	} else {
		userData["legalDisclaimerAcknowledged"] = "false"
	}

	// Add any additional data
	if request.AdditionalData != nil {
		for key, value := range request.AdditionalData {
			userData[key] = value
		}
	}

	// Verify the user
	result := h.service.VerifyUser(ctx, request.Country, userData)

	// Prepare the response
	response := VerificationResponse{
		Status:              string(result.Status),
		CitizenshipVerified: result.CitizenshipVerified,
		EligibilityVerified: result.EligibilityVerified,
	}

	// Handle errors
	if result.Error != nil {
		if ve, ok := result.Error.(*VerificationError); ok {
			response.Error = &ErrorResponse{
				Code:    ve.Code,
				Message: ve.Message,
			}
		} else {
			response.Error = &ErrorResponse{
				Code:    ErrorCodeServiceUnavailable,
				Message: result.Error.Error(),
			}
		}
	}

	c.JSON(http.StatusOK, response)
}

// HandleGetLegalDisclaimer provides the legal disclaimer text
func (h *VerificationHandler) HandleGetLegalDisclaimer(c *gin.Context) {
	disclaimer := `By selecting "I agree" below, I attest that I am eligible to participate 
in this platform under applicable laws and regulations. I understand that false statements 
may result in account suspension and potentially other consequences. 
The verification process uses zero-knowledge proofs to verify my citizenship 
without exposing my personal data.`

	c.JSON(http.StatusOK, LegalDisclaimerResponse{
		DisclaimerText: disclaimer,
	})
}

// RegisterRoutes registers the verification routes with the provided router
func (h *VerificationHandler) RegisterRoutes(router *gin.Engine) {
	// Add CORS OPTIONS handlers
	router.OPTIONS("/verify", handleCORS)
	router.OPTIONS("/verify/disclaimer", handleCORS)

	// Add the main verification handlers
	router.POST("/verify", h.corsMiddleware(h.HandleVerify))
	router.GET("/verify/disclaimer", h.corsMiddleware(h.HandleGetLegalDisclaimer))
}

// corsMiddleware applies CORS headers to routes
func (h *VerificationHandler) corsMiddleware(handlerFunc gin.HandlerFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
		c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
		handlerFunc(c)
	}
}

// handleCORS is a standalone handler for OPTIONS requests
func handleCORS(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")
	c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
	c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
	c.Status(http.StatusOK)
}