package ucca

import "time"

// LegalSearchResult represents a single search result from the compliance corpus.
// Legal-Zitatfelder (article_label/article/paragraph/...) sind live ab dem
// Prod-Re-Ingest 2026-06 (siehe docs-src/development/rag_reingest_spec.md §2).
type LegalSearchResult struct {
	Text            string  `json:"text"`
	RegulationCode  string  `json:"regulation_code"`
	RegulationName  string  `json:"regulation_name"`
	RegulationShort string  `json:"regulation_short"`
	Category        string  `json:"category"`
	Article         string  `json:"article,omitempty"`
	ArticleLabel    string  `json:"article_label,omitempty"`
	Paragraph       string  `json:"paragraph,omitempty"`
	Sub             string  `json:"sub,omitempty"`
	IsRecital       bool    `json:"is_recital,omitempty"`
	CitationStyle   string  `json:"citation_style,omitempty"`
	Pages           []int   `json:"pages,omitempty"`
	SourceURL       string  `json:"source_url"`
	Score           float64 `json:"score"`

	// Interne Felder fuer das Authority-Re-Ranking (Phase 1) — NICHT serialisiert
	// (json:"-"), daher kein Contract-Change. Aus dem Qdrant-Payload befuellt und nur
	// fuer die Sortierung in rerankByAuthority verwendet.
	AuthorityWeight int    `json:"-"`
	SourceClass     string `json:"-"`
	Jurisdiction    string `json:"-"`

	// Zitations-Graph (Phase 2) — intern, speist nur die Assessment-Berechnung
	// (verbundene Normen, Begruendung). Pro-Result-Schema bleibt eingefroren.
	CitationUnit  string   `json:"-"`
	ReferencesOut []string `json:"-"`
	ReferencesIn  []string `json:"-"`

	// Supersede-Status (status="superseded", use_for_primary=false) — Alt-Quelle,
	// die fuer Default-Fragen demoted wird (nicht versteckt; fuer Historie auffindbar).
	Superseded bool `json:"-"`

	// Evidence-Type-Marker — intern (json:"-", kein Pro-Result-Contract-Change), aus dem
	// Qdrant-Payload befuellt. classifyEvidence() leitet daraus den EvidenceType ab; der
	// Router surfacet nicht-Text-Evidence (Fußnote/Tabelle/Figur) getrennt vom Text-Merge,
	// damit feingranulare Evidence nicht von Breit-Basis-Text ueberrankt wird.
	IsFootnote       bool   `json:"-"`
	FootnoteLabel    string `json:"-"`
	FootnoteVerbatim string `json:"-"`
	RefCitationUnit  string `json:"-"`
	IsTable          bool   `json:"-"` // C6/C9: is_table (liniiert + borderless)
	IsFigure         bool   `json:"-"` // C8: is_figure (noch nicht befuellt bis C8)
}

// LegalAssessment is the auditable explanation layer over a ranked result set:
// which norm is primary, which norms connect to it via the citation graph,
// whether the answer crosses regulatory regimes, and whether a human should
// review. Computed from the already-ranked results — it EXPLAINS retrieval, it
// does not change it (graph edges for reasoning/completeness, not pool-expansion).
type LegalAssessment struct {
	PrimaryNorm       string   `json:"primary_norm"`
	PrimaryRegulation string   `json:"primary_regulation"`
	ConnectedNorms    []string `json:"connected_norms"`
	CrossRegime       bool     `json:"cross_regime"`
	HumanReviewFlag   bool     `json:"human_review_flag"`
	WinnerMargin      float64  `json:"winner_margin"`
	ScoreReasoning    string   `json:"score_reasoning"`
}

// LegalContext represents aggregated legal context for an assessment.
type LegalContext struct {
	Query            string              `json:"query"`
	Results          []LegalSearchResult `json:"results"`
	RelevantArticles []string            `json:"relevant_articles"`
	Regulations      []string            `json:"regulations"`
	GeneratedAt      time.Time           `json:"generated_at"`
}

// CERegulationInfo describes an available regulation in the corpus.
type CERegulationInfo struct {
	ID       string `json:"id"`
	NameDE   string `json:"name_de"`
	NameEN   string `json:"name_en"`
	Short    string `json:"short"`
	Category string `json:"category"`
}

// ScrollChunkResult represents a single chunk from the scroll/list endpoint.
type ScrollChunkResult struct {
	ID              string `json:"id"`
	Text            string `json:"text"`
	RegulationCode  string `json:"regulation_code"`
	RegulationName  string `json:"regulation_name"`
	RegulationShort string `json:"regulation_short"`
	Category        string `json:"category"`
	Article         string `json:"article,omitempty"`
	Paragraph       string `json:"paragraph,omitempty"`
	SourceURL       string `json:"source_url,omitempty"`
}

// CEDocumentInfo represents a document in the CE corpus with metadata.
type CEDocumentInfo struct {
	RegulationID string `json:"regulation_id"`
	NameDE       string `json:"name_de"`
	NameEN       string `json:"name_en"`
	Category     string `json:"category"`
	SourceURL    string `json:"source_url"`
	SourceOrg    string `json:"source_org"`
	ChunkCount   int    `json:"chunk_count"`
}

// --- Internal Qdrant / Ollama HTTP types ---

type ollamaEmbeddingRequest struct {
	Model  string `json:"model"`
	Prompt string `json:"prompt"`
}

type ollamaEmbeddingResponse struct {
	Embedding []float64 `json:"embedding"`
}

type qdrantSearchRequest struct {
	Vector      []float64     `json:"vector"`
	Limit       int           `json:"limit"`
	WithPayload bool          `json:"with_payload"`
	Filter      *qdrantFilter `json:"filter,omitempty"`
}

type qdrantFilter struct {
	Should []qdrantCondition `json:"should,omitempty"`
	Must   []qdrantCondition `json:"must,omitempty"`
}

type qdrantCondition struct {
	Key   string      `json:"key"`
	Match qdrantMatch `json:"match"`
}

type qdrantMatch struct {
	Value string `json:"value"`
}

type qdrantSearchResponse struct {
	Result []qdrantSearchHit `json:"result"`
}

type qdrantSearchHit struct {
	ID      interface{}            `json:"id"`
	Score   float64                `json:"score"`
	Payload map[string]interface{} `json:"payload"`
}

type qdrantQueryRequest struct {
	Prefetch    []qdrantPrefetch `json:"prefetch"`
	Query       *qdrantFusion    `json:"query"`
	Limit       int              `json:"limit"`
	WithPayload bool             `json:"with_payload"`
	Filter      *qdrantFilter    `json:"filter,omitempty"`
}

type qdrantPrefetch struct {
	Query  []float64     `json:"query"`
	Limit  int           `json:"limit"`
	Filter *qdrantFilter `json:"filter,omitempty"`
}

type qdrantFusion struct {
	Fusion string `json:"fusion"`
}

type qdrantQueryResponse struct {
	Result []qdrantSearchHit `json:"result"`
}

type qdrantTextIndexRequest struct {
	FieldName   string                `json:"field_name"`
	FieldSchema qdrantTextFieldSchema `json:"field_schema"`
}

type qdrantTextFieldSchema struct {
	Type      string `json:"type"`
	Tokenizer string `json:"tokenizer"`
	MinLen    int    `json:"min_token_len,omitempty"`
	MaxLen    int    `json:"max_token_len,omitempty"`
}

type qdrantScrollRequest struct {
	Limit       int         `json:"limit"`
	Offset      interface{} `json:"offset,omitempty"`
	WithPayload bool        `json:"with_payload"`
	WithVectors bool        `json:"with_vectors"`
}

type qdrantScrollResponse struct {
	Result struct {
		Points         []qdrantScrollPoint `json:"points"`
		NextPageOffset interface{}         `json:"next_page_offset"`
	} `json:"result"`
}

type qdrantScrollPoint struct {
	ID      interface{}            `json:"id"`
	Payload map[string]interface{} `json:"payload"`
}
