package httpx

import (
	"strings"
	"sync"
	"time"
)

type paymentIntentVerification struct {
	PaymentIntentID  string    `json:"paymentIntentId"`
	WebhookState     string    `json:"webhookState"`
	WebhookEventID   string    `json:"webhookEventId,omitempty"`
	WebhookEventType string    `json:"webhookEventType,omitempty"`
	Message          string    `json:"message"`
	Verified         bool      `json:"verified"`
	UpdatedAt        time.Time `json:"updatedAt"`
	CreatedAt        time.Time `json:"createdAt"`
}

type paymentIntentStateStore struct {
	mu      sync.RWMutex
	records map[string]paymentIntentVerification
}

func newPaymentIntentStateStore() *paymentIntentStateStore {
	return &paymentIntentStateStore{records: make(map[string]paymentIntentVerification)}
}

func (s *paymentIntentStateStore) upsertCreated(paymentIntentID string) {
	if strings.TrimSpace(paymentIntentID) == "" {
		return
	}

	now := time.Now().UTC()

	s.mu.Lock()
	defer s.mu.Unlock()

	record, exists := s.records[paymentIntentID]
	if !exists {
		record = paymentIntentVerification{
			PaymentIntentID: paymentIntentID,
			CreatedAt:       now,
		}
	}

	record.WebhookState = "awaiting_webhook"
	record.Message = "Waiting for Stripe webhook verification."
	record.Verified = false
	record.UpdatedAt = now

	s.records[paymentIntentID] = record
}

func (s *paymentIntentStateStore) applyWebhook(result *stripeWebhookResult) {
	if result == nil || strings.TrimSpace(result.PaymentIntentID) == "" {
		return
	}

	now := time.Now().UTC()

	s.mu.Lock()
	defer s.mu.Unlock()

	record, exists := s.records[result.PaymentIntentID]
	if !exists {
		record = paymentIntentVerification{
			PaymentIntentID: result.PaymentIntentID,
			CreatedAt:       now,
		}
	}

	record.WebhookEventID = result.EventID
	record.WebhookEventType = result.EventType
	record.Message = result.Message
	record.Verified = result.Verified
	record.UpdatedAt = now

	switch result.OrderState {
	case "paid_verified_local_only", "paid_unrecorded":
		record.WebhookState = "succeeded"
	case "payment_failed_verified_local_only", "payment_failed_unrecorded":
		record.WebhookState = "failed"
	case "processing_verified_local_only", "processing_unrecorded":
		record.WebhookState = "processing"
	case "canceled_verified_local_only", "canceled_unrecorded":
		record.WebhookState = "canceled"
	case "ignored":
		record.WebhookState = "ignored"
	default:
		record.WebhookState = "awaiting_webhook"
	}

	s.records[result.PaymentIntentID] = record
}

func (s *paymentIntentStateStore) get(paymentIntentID string) (paymentIntentVerification, bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()

	record, exists := s.records[paymentIntentID]
	return record, exists
}

var paymentIntentStates = newPaymentIntentStateStore()
