package plugin

import (
	"net/http"
	"strings"

	"github.com/gocql/gocql"
	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config/constants"
	siteservice "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/site"
	siteusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/site"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httperror"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httpresponse"
)

// PluginVerifyHandler handles domain verification from WordPress plugin
type PluginVerifyHandler struct {
	service siteservice.VerifySiteService
	logger  *zap.Logger
}

// ProvidePluginVerifyHandler creates a new PluginVerifyHandler
func ProvidePluginVerifyHandler(service siteservice.VerifySiteService, logger *zap.Logger) *PluginVerifyHandler {
	return &PluginVerifyHandler{
		service: service,
		logger:  logger,
	}
}

// VerifyResponse represents the verification response
type VerifyResponse struct {
	Success bool   `json:"success"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

// Handle handles the HTTP request for verifying a site via plugin API
// Uses API key authentication (site context from middleware)
func (h *PluginVerifyHandler) Handle(w http.ResponseWriter, r *http.Request) {
	// Get tenant ID and site ID from API key middleware context
	tenantIDStr, ok := r.Context().Value(constants.SiteTenantID).(string)
	if !ok {
		h.logger.Error("tenant ID not found in context")
		httperror.ProblemUnauthorized(w, "Authentication required")
		return
	}

	siteIDStr, ok := r.Context().Value(constants.SiteID).(string)
	if !ok {
		h.logger.Error("site ID not found in context")
		httperror.ProblemUnauthorized(w, "Site context required")
		return
	}

	tenantID, err := gocql.ParseUUID(tenantIDStr)
	if err != nil {
		h.logger.Error("invalid tenant ID", zap.Error(err))
		httperror.ProblemBadRequest(w, "Invalid tenant ID")
		return
	}

	siteID, err := gocql.ParseUUID(siteIDStr)
	if err != nil {
		h.logger.Error("invalid site ID", zap.Error(err))
		httperror.ProblemBadRequest(w, "Invalid site ID")
		return
	}

	h.logger.Info("plugin verify request",
		zap.String("tenant_id", tenantID.String()),
		zap.String("site_id", siteID.String()))

	// Call verification service (reuses existing DNS verification logic)
	input := &siteusecase.VerifySiteInput{}
	output, err := h.service.VerifySite(r.Context(), tenantID, siteID, input)
	if err != nil {
		h.logger.Error("verification failed",
			zap.Error(err),
			zap.String("site_id", siteID.String()))

		// Provide user-friendly error messages
		errMsg := err.Error()
		if strings.Contains(errMsg, "DNS TXT record not found") {
			httperror.ProblemBadRequest(w, "DNS TXT record not found. Please ensure you've added the verification record to your domain's DNS settings and wait 5-10 minutes for propagation.")
			return
		}
		if strings.Contains(errMsg, "DNS lookup timed out") || strings.Contains(errMsg, "timeout") {
			httperror.ProblemBadRequest(w, "DNS lookup timed out. Please check that your domain's DNS is properly configured.")
			return
		}
		if strings.Contains(errMsg, "domain not found") {
			httperror.ProblemBadRequest(w, "Domain not found. Please check that your domain is properly registered and DNS is active.")
			return
		}
		if strings.Contains(errMsg, "DNS verification failed") {
			httperror.ProblemBadRequest(w, "DNS verification failed. Please check your DNS settings and try again.")
			return
		}

		httperror.ProblemInternalServerError(w, "Failed to verify site. Please try again later.")
		return
	}

	// Success response
	response := VerifyResponse{
		Success: output.Success,
		Status:  output.Status,
		Message: output.Message,
	}

	h.logger.Info("site verified successfully via plugin",
		zap.String("site_id", siteID.String()))

	httpresponse.OK(w, response)
}
