//! DTOs for StemeDB claims endpoints.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use utoipa::{IntoParams, ToSchema};

/// Request to create a claim in StemeDB.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateClaimRequest {
    /// The claim to create
    pub claim: AuthoredClaimDto,
}

/// Response after creating a claim.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateClaimResponse {
    /// Unique identifier of the created claim
    pub id: String,
    /// Whether the claim was successfully stored
    pub stored: bool,
}

/// Authored claim DTO with full metadata.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AuthoredClaimDto {
    /// Unique identifier for this claim
    pub id: String,
    /// Concept path (e.g., "myapp/auth")
    pub concept_path: String,
    /// Predicate name (e.g., "enabled")
    pub predicate: String,
    /// The claim value
    pub value: AuthoredValueDto,
    /// Comparison mode ("equals", "absent", etc.)
    pub comparison: String,
    /// Source/origin of this claim (who/where it came from)
    pub provenance: String,
    /// The invariant that must hold (what MUST be true)
    pub invariant: String,
    /// What breaks if the invariant is violated
    pub consequence: String,
    /// Authority tier (e.g., "expert", "team_policy")
    pub authority_tier: String,
    /// Supporting evidence (file paths, ADR numbers, etc.)
    pub evidence: Vec<String>,
    /// Category (e.g., "security", "architecture")
    pub category: String,
    /// Status ("active", "deprecated", etc.)
    pub status: String,
    /// Optional ID of the claim this supersedes
    pub supersedes: Option<String>,
    /// Who created this claim
    pub created_by: String,
    /// When the claim was created (ISO 8601)
    pub created_at: String,
    /// When the claim was last updated (ISO 8601)
    pub updated_at: Option<String>,
}

/// Value type for authored claims.
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(tag = "type", content = "value")]
pub enum AuthoredValueDto {
    /// Boolean value
    Bool(bool),
    /// Numeric value
    Number(f64),
    /// Text value
    Text(String),
}

/// Search query supporting glob/wildcard patterns.
#[derive(Debug, Deserialize, IntoParams, ToSchema)]
pub struct ClaimSearchQuery {
    /// Glob pattern, e.g. "*/auth/*" or "maxwell/wallet/*"
    pub concept_pattern: Option<String>,
    /// Exact predicate or prefix match, e.g. "imported" or "key_"
    pub predicate: Option<String>,
    /// Filter by category: "security", "architecture", etc.
    pub category: Option<String>,
    /// Filter by authority tier number (0=regulatory, 1=clinical, 2=observational, 3=expert,
    /// 4=community, 5=anecdotal). Only claims at or below this tier are returned.
    pub max_tier: Option<u8>,
    /// Filter by status: "active", "deprecated", "superseded"
    pub status: Option<String>,
    /// Max results (default 50, max 200)
    pub limit: Option<usize>,
}

/// Statistics for a concept_path/predicate combination.
#[derive(Debug, Serialize, ToSchema)]
pub struct ClaimStatsDto {
    /// concept_path of the queried claim
    pub concept_path: String,
    /// predicate of the queried claim
    pub predicate: String,
    /// Total claims matching this concept_path + predicate in the store
    pub matching_claims: usize,
    /// Breakdown by tier number: tier -> count
    pub by_tier: HashMap<u8, usize>,
    /// Breakdown by status string: status -> count
    pub by_status: HashMap<String, usize>,
    /// Most common value ("true"/"false" for booleans, actual value for strings/numbers)
    pub most_common_value: Option<String>,
    /// Whether this concept_path/predicate has Tier 0-1 (regulatory/clinical) backing
    pub has_authoritative_backing: bool,
}
