package plugin

import (
	"fmt"
	"net/http"

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

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config/constants"
	domainsite "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/site"
	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"
)

// StatusHandler handles WordPress plugin status/verification requests
type StatusHandler struct {
	getSiteService siteservice.GetSiteService
	logger         *zap.Logger
}

// ProvideStatusHandler creates a new StatusHandler
func ProvideStatusHandler(
	getSiteService siteservice.GetSiteService,
	logger *zap.Logger,
) *StatusHandler {
	return &StatusHandler{
		getSiteService: getSiteService,
		logger:         logger,
	}
}

// StatusResponse represents the response for plugin status endpoint
type StatusResponse struct {
	// Core Identity
	SiteID   string `json:"site_id"`
	TenantID string `json:"tenant_id"`
	Domain   string `json:"domain"`
	SiteURL  string `json:"site_url"`

	// Status & Verification
	Status               string `json:"status"`
	IsVerified           bool   `json:"is_verified"`
	VerificationStatus   string `json:"verification_status"`                  // "pending" or "verified"
	VerificationToken    string `json:"verification_token,omitempty"`         // Only if pending
	VerificationInstructions string `json:"verification_instructions,omitempty"` // Only if pending

	// Storage (usage tracking only - no quotas)
	StorageUsedBytes int64 `json:"storage_used_bytes"`

	// Usage tracking (monthly, resets for billing)
	SearchRequestsCount int64 `json:"search_requests_count"`
	MonthlyPagesIndexed int64 `json:"monthly_pages_indexed"`
	TotalPagesIndexed   int64 `json:"total_pages_indexed"` // All-time stat

	// Search
	SearchIndexName string `json:"search_index_name"`

	// Additional Info
	APIKeyPrefix   string `json:"api_key_prefix"`
	APIKeyLastFour string `json:"api_key_last_four"`
	PluginVersion  string `json:"plugin_version,omitempty"`
	Language       string `json:"language,omitempty"`
	Timezone       string `json:"timezone,omitempty"`

	Message string `json:"message"`
}

// Handle handles the HTTP request for plugin status verification
// This endpoint is protected by API key middleware, so if we reach here, the API key is valid
func (h *StatusHandler) Handle(w http.ResponseWriter, r *http.Request) {
	// Get site information from context (populated by API key middleware)
	isAuthenticated, ok := r.Context().Value(constants.SiteIsAuthenticated).(bool)
	if !ok || !isAuthenticated {
		h.logger.Error("site not authenticated in context")
		httperror.ProblemUnauthorized(w, "Invalid API key")
		return
	}

	// Extract site ID and tenant ID from context
	siteIDStr, _ := r.Context().Value(constants.SiteID).(string)
	tenantIDStr, _ := r.Context().Value(constants.SiteTenantID).(string)

	h.logger.Info("plugin status check",
		zap.String("site_id", siteIDStr))

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

	// Fetch full site details from database
	siteOutput, err := h.getSiteService.GetSite(r.Context(), tenantID, &siteusecase.GetSiteInput{
		ID: siteIDStr,
	})
	if err != nil {
		h.logger.Error("failed to get site details", zap.Error(err))
		httperror.ProblemInternalServerError(w, "failed to retrieve site details")
		return
	}

	site := siteOutput.Site

	// Build response with full site details
	response := StatusResponse{
		SiteID:   site.ID.String(),
		TenantID: site.TenantID.String(),
		Domain:   site.Domain,
		SiteURL:  site.SiteURL,

		Status:             site.Status,
		IsVerified:         site.IsVerified,
		VerificationStatus: getVerificationStatus(site),

		StorageUsedBytes:    site.StorageUsedBytes,
		SearchRequestsCount: site.SearchRequestsCount,
		MonthlyPagesIndexed: site.MonthlyPagesIndexed,
		TotalPagesIndexed:   site.TotalPagesIndexed,

		SearchIndexName: site.SearchIndexName,

		APIKeyPrefix:   site.APIKeyPrefix,
		APIKeyLastFour: site.APIKeyLastFour,
		PluginVersion:  site.PluginVersion,
		Language:       site.Language,
		Timezone:       site.Timezone,

		Message: "API key is valid",
	}

	// If site is not verified and requires verification, include instructions
	if site.RequiresVerification() && !site.IsVerified {
		response.VerificationToken = site.VerificationToken
		response.VerificationInstructions = generateVerificationInstructions(site)
	}

	httpresponse.OK(w, response)
}

// getVerificationStatus returns the verification status string
func getVerificationStatus(site *domainsite.Site) string {
	if site.IsVerified {
		return "verified"
	}
	return "pending"
}

// generateVerificationInstructions generates DNS verification instructions
func generateVerificationInstructions(site *domainsite.Site) string {
	return fmt.Sprintf(
		"To verify ownership of %s, add this DNS TXT record:\n\n"+
			"Host/Name: %s\n"+
			"Type: TXT\n"+
			"Value: maplepress-verify=%s\n\n"+
			"Instructions:\n"+
			"1. Log in to your domain registrar (GoDaddy, Namecheap, Cloudflare, etc.)\n"+
			"2. Find DNS settings for your domain\n"+
			"3. Add a new TXT record with the values above\n"+
			"4. Wait 5-10 minutes for DNS propagation\n"+
			"5. Click 'Verify Domain' in your WordPress plugin settings",
		site.Domain,
		site.Domain,
		site.VerificationToken,
	)
}
