package config

import (
	"fmt"
	"time"
)

// SlurpConfig holds SLURP event system integration configuration
type SlurpConfig struct {
	// Connection settings
	Enabled             bool          `yaml:"enabled" json:"enabled"`
	BaseURL             string        `yaml:"base_url" json:"base_url"`
	APIKey              string        `yaml:"api_key" json:"api_key"`
	Timeout             time.Duration `yaml:"timeout" json:"timeout"`
	RetryCount          int           `yaml:"retry_count" json:"retry_count"`
	RetryDelay          time.Duration `yaml:"retry_delay" json:"retry_delay"`
	
	// Event generation settings
	EventGeneration     EventGenerationConfig `yaml:"event_generation" json:"event_generation"`
	
	// Project-specific event mappings
	ProjectMappings     map[string]ProjectEventMapping `yaml:"project_mappings" json:"project_mappings"`
	
	// Default event settings
	DefaultEventSettings DefaultEventConfig `yaml:"default_event_settings" json:"default_event_settings"`
	
	// Batch processing settings
	BatchProcessing     BatchConfig `yaml:"batch_processing" json:"batch_processing"`
	
	// Reliability settings
	Reliability         ReliabilityConfig `yaml:"reliability" json:"reliability"`
}

// EventGenerationConfig controls when and how SLURP events are generated
type EventGenerationConfig struct {
	// Consensus requirements
	MinConsensusStrength    float64       `yaml:"min_consensus_strength" json:"min_consensus_strength"`
	MinParticipants         int           `yaml:"min_participants" json:"min_participants"`
	RequireUnanimity        bool          `yaml:"require_unanimity" json:"require_unanimity"`
	
	// Time-based triggers
	MaxDiscussionDuration   time.Duration `yaml:"max_discussion_duration" json:"max_discussion_duration"`
	MinDiscussionDuration   time.Duration `yaml:"min_discussion_duration" json:"min_discussion_duration"`
	
	// Event type generation rules
	EnabledEventTypes       []string      `yaml:"enabled_event_types" json:"enabled_event_types"`
	DisabledEventTypes      []string      `yaml:"disabled_event_types" json:"disabled_event_types"`
	
	// Severity calculation
	SeverityRules           SeverityConfig `yaml:"severity_rules" json:"severity_rules"`
}

// SeverityConfig defines how to calculate event severity from HMMM discussions
type SeverityConfig struct {
	// Base severity for each event type (1-10 scale)
	BaseSeverity          map[string]int `yaml:"base_severity" json:"base_severity"`
	
	// Modifiers based on discussion characteristics
	ParticipantMultiplier float64        `yaml:"participant_multiplier" json:"participant_multiplier"`
	DurationMultiplier    float64        `yaml:"duration_multiplier" json:"duration_multiplier"`
	UrgencyKeywords       []string       `yaml:"urgency_keywords" json:"urgency_keywords"`
	UrgencyBoost          int            `yaml:"urgency_boost" json:"urgency_boost"`
	
	// Severity caps
	MinSeverity           int            `yaml:"min_severity" json:"min_severity"`
	MaxSeverity           int            `yaml:"max_severity" json:"max_severity"`
}

// ProjectEventMapping defines project-specific event mapping rules
type ProjectEventMapping struct {
	ProjectPath           string                    `yaml:"project_path" json:"project_path"`
	CustomEventTypes      map[string]string         `yaml:"custom_event_types" json:"custom_event_types"`
	SeverityOverrides     map[string]int            `yaml:"severity_overrides" json:"severity_overrides"`
	AdditionalMetadata    map[string]interface{}    `yaml:"additional_metadata" json:"additional_metadata"`
	EventFilters          []EventFilter             `yaml:"event_filters" json:"event_filters"`
}

// EventFilter defines conditions for filtering or modifying events
type EventFilter struct {
	Name              string            `yaml:"name" json:"name"`
	Conditions        map[string]string `yaml:"conditions" json:"conditions"`
	Action            string            `yaml:"action" json:"action"` // "allow", "deny", "modify"
	Modifications     map[string]string `yaml:"modifications" json:"modifications"`
}

// DefaultEventConfig provides default settings for generated events
type DefaultEventConfig struct {
	DefaultSeverity       int               `yaml:"default_severity" json:"default_severity"`
	DefaultCreatedBy      string            `yaml:"default_created_by" json:"default_created_by"`
	DefaultTags           []string          `yaml:"default_tags" json:"default_tags"`
	MetadataTemplate      map[string]string `yaml:"metadata_template" json:"metadata_template"`
}

// BatchConfig controls batch processing of SLURP events
type BatchConfig struct {
	Enabled               bool          `yaml:"enabled" json:"enabled"`
	MaxBatchSize          int           `yaml:"max_batch_size" json:"max_batch_size"`
	MaxBatchWait          time.Duration `yaml:"max_batch_wait" json:"max_batch_wait"`
	FlushOnShutdown       bool          `yaml:"flush_on_shutdown" json:"flush_on_shutdown"`
}

// ReliabilityConfig controls reliability features (idempotency, circuit breaker, DLQ)
type ReliabilityConfig struct {
	// Circuit breaker settings
	MaxFailures       int           `yaml:"max_failures" json:"max_failures"`
	CooldownPeriod    time.Duration `yaml:"cooldown_period" json:"cooldown_period"`
	HalfOpenTimeout   time.Duration `yaml:"half_open_timeout" json:"half_open_timeout"`
	
	// Idempotency settings
	IdempotencyWindow time.Duration `yaml:"idempotency_window" json:"idempotency_window"`
	
	// Dead letter queue settings
	DLQDirectory      string        `yaml:"dlq_directory" json:"dlq_directory"`
	MaxRetries        int           `yaml:"max_retries" json:"max_retries"`
	RetryInterval     time.Duration `yaml:"retry_interval" json:"retry_interval"`
	
	// Backoff settings
	InitialBackoff    time.Duration `yaml:"initial_backoff" json:"initial_backoff"`
	MaxBackoff        time.Duration `yaml:"max_backoff" json:"max_backoff"`
	BackoffMultiplier float64       `yaml:"backoff_multiplier" json:"backoff_multiplier"`
	JitterFactor      float64       `yaml:"jitter_factor" json:"jitter_factor"`
}

// HmmmToSlurpMapping defines the mapping between HMMM discussion outcomes and SLURP event types
type HmmmToSlurpMapping struct {
	// Consensus types to SLURP event types
	ConsensusApproval     string `yaml:"consensus_approval" json:"consensus_approval"`         // -> "approval"
	RiskIdentified        string `yaml:"risk_identified" json:"risk_identified"`             // -> "warning"
	CriticalBlocker       string `yaml:"critical_blocker" json:"critical_blocker"`           // -> "blocker"
	PriorityChange        string `yaml:"priority_change" json:"priority_change"`             // -> "priority_change"
	AccessRequest         string `yaml:"access_request" json:"access_request"`               // -> "access_update"
	ArchitectureDecision  string `yaml:"architecture_decision" json:"architecture_decision"` // -> "structural_change"
	InformationShare      string `yaml:"information_share" json:"information_share"`         // -> "announcement"
	
	// Keywords that trigger specific event types
	ApprovalKeywords      []string `yaml:"approval_keywords" json:"approval_keywords"`
	WarningKeywords       []string `yaml:"warning_keywords" json:"warning_keywords"`
	BlockerKeywords       []string `yaml:"blocker_keywords" json:"blocker_keywords"`
	PriorityKeywords      []string `yaml:"priority_keywords" json:"priority_keywords"`
	AccessKeywords        []string `yaml:"access_keywords" json:"access_keywords"`
	StructuralKeywords    []string `yaml:"structural_keywords" json:"structural_keywords"`
	AnnouncementKeywords  []string `yaml:"announcement_keywords" json:"announcement_keywords"`
}

// GetDefaultSlurpConfig returns default SLURP configuration
func GetDefaultSlurpConfig() SlurpConfig {
	return SlurpConfig{
		Enabled:     false, // Disabled by default until configured
		BaseURL:     "http://localhost:8080",
		Timeout:     30 * time.Second,
		RetryCount:  3,
		RetryDelay:  5 * time.Second,
		
		EventGeneration: EventGenerationConfig{
			MinConsensusStrength:  0.7,
			MinParticipants:       2,
			RequireUnanimity:      false,
			MaxDiscussionDuration: 30 * time.Minute,
			MinDiscussionDuration: 1 * time.Minute,
			EnabledEventTypes: []string{
				"announcement", "warning", "blocker", "approval", 
				"priority_change", "access_update", "structural_change",
			},
			DisabledEventTypes: []string{},
			SeverityRules: SeverityConfig{
				BaseSeverity: map[string]int{
					"announcement":     3,
					"warning":          5,
					"blocker":          8,
					"approval":         4,
					"priority_change":  6,
					"access_update":    5,
					"structural_change": 7,
				},
				ParticipantMultiplier: 0.2,
				DurationMultiplier:    0.1,
				UrgencyKeywords:       []string{"urgent", "critical", "blocker", "emergency", "immediate"},
				UrgencyBoost:          2,
				MinSeverity:           1,
				MaxSeverity:           10,
			},
		},
		
		ProjectMappings: make(map[string]ProjectEventMapping),
		
		DefaultEventSettings: DefaultEventConfig{
			DefaultSeverity:  5,
			DefaultCreatedBy: "hmmm-consensus",
			DefaultTags:      []string{"hmmm-generated", "automated"},
			MetadataTemplate: map[string]string{
				"source":           "hmmm-discussion",
				"generation_type":  "consensus-based",
			},
		},
		
		BatchProcessing: BatchConfig{
			Enabled:         true,
			MaxBatchSize:    10,
			MaxBatchWait:    5 * time.Second,
			FlushOnShutdown: true,
		},
		
		Reliability: ReliabilityConfig{
			// Circuit breaker: allow 5 consecutive failures before opening for 1 minute
			MaxFailures:       5,
			CooldownPeriod:    1 * time.Minute,
			HalfOpenTimeout:   30 * time.Second,
			
			// Idempotency: 1-hour window to catch duplicate events
			IdempotencyWindow: 1 * time.Hour,
			
			// DLQ: retry up to 3 times with exponential backoff
			DLQDirectory:      "./data/slurp_dlq",
			MaxRetries:        3,
			RetryInterval:     30 * time.Second,
			
			// Backoff: start with 1s, max 5min, 2x multiplier, ±25% jitter
			InitialBackoff:    1 * time.Second,
			MaxBackoff:        5 * time.Minute,
			BackoffMultiplier: 2.0,
			JitterFactor:      0.25,
		},
	}
}

// GetHmmmToSlurpMapping returns the default mapping configuration
func GetHmmmToSlurpMapping() HmmmToSlurpMapping {
	return HmmmToSlurpMapping{
		ConsensusApproval:     "approval",
		RiskIdentified:        "warning",
		CriticalBlocker:       "blocker",
		PriorityChange:        "priority_change",
		AccessRequest:         "access_update",
		ArchitectureDecision:  "structural_change",
		InformationShare:      "announcement",
		
		ApprovalKeywords:      []string{"approve", "approved", "looks good", "lgtm", "accepted", "agree"},
		WarningKeywords:       []string{"warning", "caution", "risk", "potential issue", "concern", "careful"},
		BlockerKeywords:       []string{"blocker", "blocked", "critical", "urgent", "cannot proceed", "show stopper"},
		PriorityKeywords:      []string{"priority", "urgent", "high priority", "low priority", "reprioritize"},
		AccessKeywords:        []string{"access", "permission", "auth", "authorization", "credentials", "token"},
		StructuralKeywords:    []string{"architecture", "structure", "design", "refactor", "framework", "pattern"},
		AnnouncementKeywords:  []string{"announce", "fyi", "information", "update", "news", "notice"},
	}
}

// ValidateSlurpConfig validates SLURP configuration
func ValidateSlurpConfig(config SlurpConfig) error {
	if config.Enabled {
		if config.BaseURL == "" {
			return fmt.Errorf("slurp.base_url is required when SLURP is enabled")
		}
		
		if config.EventGeneration.MinConsensusStrength < 0 || config.EventGeneration.MinConsensusStrength > 1 {
			return fmt.Errorf("slurp.event_generation.min_consensus_strength must be between 0 and 1")
		}
		
		if config.EventGeneration.MinParticipants < 1 {
			return fmt.Errorf("slurp.event_generation.min_participants must be at least 1")
		}
		
		if config.DefaultEventSettings.DefaultSeverity < 1 || config.DefaultEventSettings.DefaultSeverity > 10 {
			return fmt.Errorf("slurp.default_event_settings.default_severity must be between 1 and 10")
		}
		
		// Validate reliability settings
		if config.Reliability.MaxFailures < 1 {
			return fmt.Errorf("slurp.reliability.max_failures must be at least 1")
		}
		
		if config.Reliability.CooldownPeriod <= 0 {
			return fmt.Errorf("slurp.reliability.cooldown_period must be positive")
		}
		
		if config.Reliability.IdempotencyWindow <= 0 {
			return fmt.Errorf("slurp.reliability.idempotency_window must be positive")
		}
		
		if config.Reliability.MaxRetries < 0 {
			return fmt.Errorf("slurp.reliability.max_retries cannot be negative")
		}
		
		if config.Reliability.BackoffMultiplier <= 1.0 {
			return fmt.Errorf("slurp.reliability.backoff_multiplier must be greater than 1.0")
		}
	}
	
	return nil
}