package iace

import "encoding/json"

// ============================================================================
// Ground Truth types — stores a professional risk assessment for benchmarking
// ============================================================================

// GroundTruth is the top-level container stored in project metadata.ground_truth.
type GroundTruth struct {
	Entries     []GroundTruthEntry `json:"entries"`
	SourceFile  string             `json:"source_file,omitempty"`
	ImportedAt  string             `json:"imported_at"`
	Description string             `json:"description,omitempty"`
}

// GroundTruthEntry represents a single hazard from a professional risk assessment.
type GroundTruthEntry struct {
	Nr                    string            `json:"nr"`
	HazardGroup           string            `json:"hazard_group"`
	HazardGroupApplicable bool              `json:"hazard_group_applicable"`
	HazardSubgroup        string            `json:"hazard_subgroup"`
	HazardType            string            `json:"hazard_type"`
	HazardCause           string            `json:"hazard_cause"`
	LifecyclePhases       []string          `json:"lifecycle_phases"`
	ComponentZone         string            `json:"component_zone"`
	RiskIn                GTRisk            `json:"risk_in"`
	PLr                   *GTPLr            `json:"plr,omitempty"`
	Measures              []string          `json:"measures"`
	MeasureType           string            `json:"measure_type"`
	RiskOut               GTRisk            `json:"risk_out"`
	NormReferences        []string          `json:"norm_references"`
	Sufficient            bool              `json:"sufficient"`
	Comment               string            `json:"comment,omitempty"`
	ReductionSteps        []GTReductionStep `json:"reduction_steps,omitempty"`
}

// GTRisk represents the EN 62061 additive risk: R = (F + W + P) * S.
type GTRisk struct {
	F int `json:"f"`
	W int `json:"w"`
	P int `json:"p"`
	S int `json:"s"`
	R int `json:"r"`
}

// GTPLr represents Performance Level required (EN ISO 13849-1).
type GTPLr struct {
	S   string `json:"s"`
	F   string `json:"f"`
	P   string `json:"p"`
	EW  string `json:"ew,omitempty"`
	PLr string `json:"plr"`
}

// GTReductionStep represents an iterative risk reduction row.
type GTReductionStep struct {
	RiskIn         GTRisk   `json:"risk_in"`
	PLr            *GTPLr   `json:"plr,omitempty"`
	Measures       []string `json:"measures"`
	MeasureType    string   `json:"measure_type"`
	RiskOut        GTRisk   `json:"risk_out"`
	NormReferences []string `json:"norm_references"`
	Sufficient     bool     `json:"sufficient"`
	Comment        string   `json:"comment,omitempty"`
}

// ============================================================================
// Benchmark result types — comparison output
// ============================================================================

// BenchmarkResult is the API response for the comparison endpoint.
type BenchmarkResult struct {
	CoverageScore     float64            `json:"coverage_score"`
	MeasureCoverage   float64            `json:"measure_coverage"`
	TotalGT           int                `json:"total_gt"`
	TotalEngine       int                `json:"total_engine"`
	MatchedPairs      []HazardMatchPair  `json:"matched_pairs"`
	MissingFromEngine []GroundTruthEntry `json:"missing_from_engine"`
	ExtraInEngine     []HazardSummary    `json:"extra_in_engine"`
	CategoryBreakdown []CategoryScore    `json:"category_breakdown"`
	RiskRankPairs     []RiskRankPair     `json:"risk_rank_pairs"`
	// Risk-number comparison (tool vs professional) per matched hazard + aggregate.
	RiskComparison []RiskComparisonPair `json:"risk_comparison,omitempty"`
	RiskAgreement  RiskAgreement        `json:"risk_agreement"`
	// Dimensional comparison: do the engine's mm/mm-s values match the GT's?
	Distances *DistanceComparison `json:"distances,omitempty"`
}

// HazardMatchPair links a GT entry to an engine hazard.
type HazardMatchPair struct {
	GTEntry      GroundTruthEntry `json:"gt_entry"`
	EngineHazard HazardSummary    `json:"engine_hazard"`
	MatchScore   float64          `json:"match_score"`
	MatchReason  string           `json:"match_reason"`
}

// HazardSummary is a hazard representation for benchmark results with detail fields.
type HazardSummary struct {
	ID             string   `json:"id"`
	Name           string   `json:"name"`
	Category       string   `json:"category"`
	Component      string   `json:"component,omitempty"`
	Zone           string   `json:"zone,omitempty"`
	RiskLevel      string   `json:"risk_level,omitempty"`
	Description    string   `json:"description,omitempty"`
	Scenario       string   `json:"scenario,omitempty"`
	PossibleHarm   string   `json:"possible_harm,omitempty"`
	TriggerEvent   string   `json:"trigger_event,omitempty"`
	AffectedPerson string   `json:"affected_person,omitempty"`
	LifecyclePhase string   `json:"lifecycle_phase,omitempty"`
	Mitigations    []string `json:"mitigations,omitempty"`
}

// CategoryScore shows coverage per ISO 12100 hazard group.
type CategoryScore struct {
	Category   string  `json:"category"`
	GTCount    int     `json:"gt_count"`
	MatchCount int     `json:"match_count"`
	Coverage   float64 `json:"coverage"`
}

// RiskRankPair compares risk ordering between GT and engine.
type RiskRankPair struct {
	GTRank      int     `json:"gt_rank"`
	EngineRank  int     `json:"engine_rank"`
	HazardName  string  `json:"hazard_name"`
	GTRiskScore int     `json:"gt_risk_score"`
	EngineRisk  float64 `json:"engine_risk"`
}

// ParseGroundTruth extracts GroundTruth from project metadata JSON.
func ParseGroundTruth(metadata json.RawMessage) (*GroundTruth, error) {
	var m map[string]json.RawMessage
	if err := json.Unmarshal(metadata, &m); err != nil {
		return nil, err
	}
	raw, ok := m["ground_truth"]
	if !ok {
		return nil, nil
	}
	var gt GroundTruth
	if err := json.Unmarshal(raw, &gt); err != nil {
		return nil, err
	}
	return &gt, nil
}
