package iace

import (
	"fmt"
	"strings"
)

// Dual-model risk suggestion for the "Risikobewertung" tab. BreakPilot proposes
// justified starting values for BOTH a EN-62061-style model (F/W/P/S) and the
// Fine-Kinney model (P/E/C); the professional adjusts them (e.g. from his own
// licensed DIN/Beuth data). We expose the FORMULAS and computed values only —
// no norm table is stored or reproduced.

// SuggestedValue is a proposed parameter value plus the plain-language reason.
type SuggestedValue struct {
	Value         float64 `json:"value"`
	Justification string  `json:"justification"`
}

// EN62061Suggestion is the EN-62061-style risk (the Excel format the
// professional knows): R = S * (F + W + P).
type EN62061Suggestion struct {
	Severity    SuggestedValue `json:"severity"`
	Frequency   SuggestedValue `json:"frequency"`
	Probability SuggestedValue `json:"probability"`
	Avoidance   SuggestedValue `json:"avoidance"`
	Score       int            `json:"score"`
	Level       string         `json:"level"`
	Formula     string         `json:"formula"`
}

// FineKinneySuggestion is the Fine-Kinney risk (US-recognized): R = P * E * C.
type FineKinneySuggestion struct {
	Probability SuggestedValue `json:"probability"`
	Exposure    SuggestedValue `json:"exposure"`
	Consequence SuggestedValue `json:"consequence"`
	Score       float64        `json:"score"`
	Band        string         `json:"band"`
	Action      string         `json:"action"`
	Formula     string         `json:"formula"`
}

// RiskSuggestion carries both models for one hazard.
type RiskSuggestion struct {
	HazardID    string               `json:"hazard_id"`
	ContactMode string               `json:"contact_mode"`
	EN62061     EN62061Suggestion    `json:"en62061"`
	FineKinney  FineKinneySuggestion `json:"fine_kinney"`
	DataSource  *RiskEvidence        `json:"data_source,omitempty"`
	Note        string               `json:"note"`
}

// BuildRiskSuggestion derives both models' justified starting values from the
// hazard's category/scenario/lifecycle, using only public-data anchors.
func BuildRiskSuggestion(hz *Hazard) RiskSuggestion {
	cats := []string{hz.Category}
	scenario := hz.Scenario
	if scenario == "" {
		scenario = hz.Name
	}
	lifecycle := splitLifecyclePhases(hz.LifecyclePhase)

	mode := DetectContactMode(cats, scenario)
	modeLabel := mode
	if modeLabel == "" {
		modeLabel = "unbestimmt"
	}

	// Cite the actual public statistic + license for the W anchor where documented.
	wJustification := fmt.Sprintf("Wahrscheinlichkeit W aus ESAW-Haeufigkeit der Kontaktart '%s'", modeLabel)
	var dataSource *RiskEvidence
	if ev, ok := RiskEvidenceFor(mode); ok {
		wJustification += fmt.Sprintf(" (%s: %s; %s)", ev.Label, ev.Stat, ev.Attribution)
		dataSource = &ev
	}

	// EN-62061-style (F/W/P/S)
	s := EstimateSeverity(cats, scenario, 0)
	f := EstimateFrequency(lifecycle)
	w := EstimateProbabilityW(cats, scenario)
	p := EstimateAvoidabilityP(cats, scenario)
	idx, level := EstimateRiskLevel(s, f, w, p)

	// Fine-Kinney (P/E/C)
	fk := SuggestFineKinney(cats, scenario, lifecycle, 0)

	return RiskSuggestion{
		HazardID:    hz.ID.String(),
		ContactMode: modeLabel,
		EN62061: EN62061Suggestion{
			Severity:    SuggestedValue{float64(s), fmt.Sprintf("Schwere S%d aus Verletzungsbild der Kontaktart '%s' (NIOSH/OSHA/MIL-STD-882)", s, modeLabel)},
			Frequency:   SuggestedValue{float64(f), "Haeufigkeit F aus Lebensphasen-Exposition des Projekts"},
			Probability: SuggestedValue{float64(w), wJustification},
			Avoidance:   SuggestedValue{float64(p), fmt.Sprintf("Vermeidbarkeit P aus Kinematik der Kontaktart '%s'", modeLabel)},
			Score:       idx,
			Level:       level,
			Formula:     "R = S × (F + W + P)",
		},
		FineKinney: FineKinneySuggestion{
			Probability: SuggestedValue{fk.Probability.Value, fk.Probability.Justification},
			Exposure:    SuggestedValue{fk.Exposure.Value, fk.Exposure.Justification},
			Consequence: SuggestedValue{fk.Consequence.Value, fk.Consequence.Justification},
			Score:       fk.Score,
			Band:        fk.Band,
			Action:      fk.Action,
			Formula:     "R = P × E × C",
		},
		DataSource: dataSource,
		Note:       "Begruendete Vorschlagswerte (BreakPilot, oeffentliche Datenquellen). Vom Sachverstaendigen anpassbar.",
	}
}

func splitLifecyclePhases(s string) []string {
	var out []string
	for _, p := range strings.Split(s, ",") {
		if p = strings.TrimSpace(p); p != "" {
			out = append(out, p)
		}
	}
	return out
}
