from __future__ import annotations

from typing import Any

from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel


# ---------------------------------------------------------------------------
# Shared config
# ---------------------------------------------------------------------------

_MODEL_CONFIG = ConfigDict(
    frozen=True,
    populate_by_name=True,
    alias_generator=to_camel,
)


# ---------------------------------------------------------------------------
# Firearms
# ---------------------------------------------------------------------------


class Firearm(BaseModel):
    """A firearm specification record."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    manufacturer_id: str
    category_id: str
    parent_firearm_id: str | None = None
    variant_type: str | None = None
    year_introduced: int | None = None
    year_discontinued: int | None = None
    status: str | None = None
    country_of_origin: str | None = None

    # Physical dimensions
    weight_empty_g: float | None = None
    weight_loaded_g: float | None = None
    overall_length_mm: float | None = None
    barrel_length_mm: float | None = None
    height_mm: float | None = None
    width_mm: float | None = None
    sight_radius_mm: float | None = None
    folded_length_mm: float | None = None

    # Mechanical
    action_type: str | None = None
    firing_mechanism: str | None = None
    trigger_type: str | None = None
    trigger_pull_n: float | None = None
    magazine_capacity: int | None = None
    magazine_type: str | None = None

    # Ballistic
    muzzle_velocity_mps: float | None = None
    muzzle_energy_j: float | None = None
    effective_range_m: float | None = None
    max_range_m: float | None = None
    rate_of_fire_rpm: int | None = None

    # Barrel details
    barrel_rifling: str | None = None
    rifling_twist_mm: float | None = None
    number_of_grooves: int | None = None

    # Materials
    frame_material: str | None = None
    slide_material: str | None = None
    barrel_material: str | None = None
    stock_material: str | None = None
    finish: str | None = None

    # JSON fields (stored as text)
    safety_mechanisms: str | None = None
    features: str | None = None
    feed_systems: str | None = None
    alternate_names: str | None = None
    firing_modes: str | None = None
    conflicts: str | None = None
    production_numbers: str | None = None
    sources: str | None = None

    # Game stats (0-100)
    game_damage: float | None = None
    game_accuracy: float | None = None
    game_range: float | None = None
    game_fire_rate: float | None = None
    game_mobility: float | None = None
    game_recoil_control: float | None = None
    game_reload_speed: float | None = None
    game_concealment: float | None = None

    # Content
    description: str | None = None
    notes: str | None = None
    designer: str | None = None
    lore: str | None = None

    # Ballistic source
    source_muzzle_velocity_mps: float | None = None
    source_muzzle_energy_j: float | None = None
    source_effective_range_m: float | None = None
    source_max_range_m: float | None = None
    ballistics_source: str | None = None
    ballistics_source_url: str | None = None
    default_ammo_id: str | None = None

    # Media
    has_3d_model: int | None = Field(default=None, alias="has3dModel")
    svg_line_art_url: str | None = None
    model_3d_url: str | None = Field(default=None, alias="model3dUrl")

    # Data quality
    data_confidence: float | None = None

    # Timestamps
    created_at: str
    updated_at: str


class FirearmListItem(BaseModel):
    """Summarised firearm returned by list / search endpoints."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    manufacturer_id: str
    category_id: str
    year_introduced: int | None = None
    status: str | None = None
    country_of_origin: str | None = None
    action_type: str | None = None
    weight_empty_g: float | None = None
    barrel_length_mm: float | None = None
    svg_line_art_url: str | None = None
    model_3d_url: str | None = Field(default=None, alias="model3dUrl")
    created_at: str | None = None
    favorite_count: int | None = None


class FirearmCaliberEntry(BaseModel):
    """A caliber entry on a firearm detail, joined from the junction table."""

    model_config = _MODEL_CONFIG

    caliber_id: str
    is_primary: int
    name: str
    nato_designation: str | None = None
    bullet_diameter_mm: float | None = None
    case_length_mm: float | None = None


class FirearmDetail(Firearm):
    """Full firearm detail including related entities."""

    manufacturer: Manufacturer | None = None
    category: Category | None = None
    calibers: list[FirearmCaliberEntry] = []
    images: list[FirearmImage] = []
    users: list[FirearmUser] = []


class FirearmVariant(BaseModel):
    """A firearm variant summary."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    variant_type: str | None = None
    year_introduced: int | None = None
    status: str | None = None


# ---------------------------------------------------------------------------
# Manufacturers
# ---------------------------------------------------------------------------


class Manufacturer(BaseModel):
    """A firearms manufacturer."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    country_code: str | None = None
    founded_year: int | None = None
    website: str | None = None
    logo_url: str | None = None
    description: str | None = None
    created_at: str
    updated_at: str


class ManufacturerStatsManufacturer(BaseModel):
    """Nested manufacturer summary inside ManufacturerStats."""

    model_config = _MODEL_CONFIG

    id: str
    name: str


class ManufacturerStatsAggregates(BaseModel):
    """Aggregate statistics for a manufacturer."""

    model_config = _MODEL_CONFIG

    total_firearms: int
    avg_weight_g: float | None = None
    avg_range_m: float | None = None
    avg_capacity: float | None = None
    active_count: int
    discontinued_count: int
    earliest_year: int | None = None
    latest_year: int | None = None


class ManufacturerStatsCategory(BaseModel):
    """Category breakdown inside ManufacturerStats."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    count: int


class ManufacturerStats(BaseModel):
    """Per-manufacturer aggregate statistics."""

    model_config = _MODEL_CONFIG

    manufacturer: ManufacturerStatsManufacturer
    stats: ManufacturerStatsAggregates | None = None
    categories: list[ManufacturerStatsCategory] = []
    most_common_caliber: ManufacturerStatsCategory | None = None


class ManufacturerTimelineFirearm(BaseModel):
    """A firearm entry in a manufacturer timeline year group."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    year_introduced: int | None = None
    category_id: str
    status: str | None = None


class ManufacturerTimelineYear(BaseModel):
    """A year group in a manufacturer timeline."""

    model_config = _MODEL_CONFIG

    year: int | None = None
    firearms: list[ManufacturerTimelineFirearm] = []


class ManufacturerTimeline(BaseModel):
    """Manufacturer timeline grouping firearms by year introduced."""

    model_config = _MODEL_CONFIG

    manufacturer: ManufacturerStatsManufacturer
    timeline: list[ManufacturerTimelineYear] = []


# ---------------------------------------------------------------------------
# Calibers
# ---------------------------------------------------------------------------


class Caliber(BaseModel):
    """A cartridge / caliber specification."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    aliases: str | None = None
    nato_designation: str | None = None
    bullet_diameter_mm: float | None = None
    neck_diameter_mm: float | None = None
    base_diameter_mm: float | None = None
    case_length_mm: float | None = None
    overall_length_mm: float | None = None
    max_pressure_mpa: float | None = None
    max_pressure_psi: float | None = None
    typical_bullet_weight_g: float | None = None
    typical_muzzle_velocity_mps: float | None = None
    typical_muzzle_energy_j: float | None = None
    primer_type: str | None = None
    cartridge_type: str | None = None
    parent_cartridge_id: str | None = None
    year_introduced: int | None = None
    designer: str | None = None
    created_at: str
    updated_at: str


class CaliberBallisticsCaliber(BaseModel):
    """Nested caliber summary inside CaliberBallistics."""

    model_config = _MODEL_CONFIG

    id: str
    name: str


class CaliberBallistics(BaseModel):
    """Simplified ballistics result for a caliber at a given distance."""

    model_config = _MODEL_CONFIG

    caliber: CaliberBallisticsCaliber
    distance_m: float
    muzzle_velocity_mps: float
    muzzle_energy_j: float
    velocity_at_distance_mps: float
    energy_at_distance_j: float
    time_of_flight_s: float
    bullet_drop_cm: float


class CaliberFamily(BaseModel):
    """Caliber family tree (ancestors + current + descendants)."""

    model_config = _MODEL_CONFIG

    ancestors: list[Caliber] = []
    current: Caliber
    descendants: list[Caliber] = []


# ---------------------------------------------------------------------------
# Ammunition
# ---------------------------------------------------------------------------


class Ammunition(BaseModel):
    """A specific ammunition load for a caliber."""

    model_config = _MODEL_CONFIG

    id: str
    caliber_id: str
    name: str
    designation: str | None = None
    manufacturer: str | None = None
    country_of_origin: str | None = None
    bullet_weight_g: float
    bullet_type: str
    ballistic_coefficient_g1: float | None = Field(
        default=None, alias="ballisticCoefficientG1"
    )
    ballistic_coefficient_g7: float | None = Field(
        default=None, alias="ballisticCoefficientG7"
    )
    reference_velocity_mps: float
    reference_barrel_length_mm: float
    velocity_retention_exponent: float | None = None
    sectional_density: float | None = None
    description: str | None = None
    year_introduced: int | None = None
    is_common: int
    is_military: int
    created_at: str
    updated_at: str


class TrajectoryPoint(BaseModel):
    """A single point along a ballistic trajectory."""

    model_config = _MODEL_CONFIG

    distance_m: float
    velocity_mps: float
    energy_j: float
    drop_cm: float
    time_of_flight_s: float
    mach_number: float
    momentum_kg_ms: float
    tko_factor: float
    energy_density_j_cm2: float = Field(alias="energyDensityJCm2")


class TerminalBallistics(BaseModel):
    """Muzzle-level terminal ballistics summary."""

    model_config = _MODEL_CONFIG

    tko_factor: float
    momentum_kg_ms: float
    sectional_density: float
    hatcher_rsp: float = Field(alias="hatcherRSP")
    energy_density_j_cm2: float = Field(alias="energyDensityJCm2")


class BallisticProfileAmmo(BaseModel):
    """Nested ammunition summary inside BallisticProfile."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    caliber_id: str


class BallisticProfile(BaseModel):
    """Full ballistic profile for an ammunition load."""

    model_config = _MODEL_CONFIG

    ammunition: BallisticProfileAmmo
    barrel_length_mm: float
    muzzle_velocity_mps: float
    muzzle_energy_j: float
    effective_range_m: float
    terminal_ballistics: TerminalBallistics
    trajectory: list[TrajectoryPoint] = []


class FirearmCalculationFirearm(BaseModel):
    """Nested firearm summary inside FirearmCalculation."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    barrel_length_mm: float | None = None


class FirearmCalculationAmmo(BaseModel):
    """Nested ammunition summary inside FirearmCalculation."""

    model_config = _MODEL_CONFIG

    id: str
    name: str


class FirearmCalculationCalculated(BaseModel):
    """Calculated ballistic values inside FirearmCalculation."""

    model_config = _MODEL_CONFIG

    muzzle_velocity_mps: float
    muzzle_energy_j: float
    terminal_ballistics: TerminalBallistics


class FirearmCalculationSourceReported(BaseModel):
    """Source-reported ballistic values inside FirearmCalculation."""

    model_config = _MODEL_CONFIG

    muzzle_velocity_mps: float | None = None
    muzzle_energy_j: float | None = None


class FirearmCalculationDelta(BaseModel):
    """Delta between calculated and source-reported values."""

    model_config = _MODEL_CONFIG

    velocity_mps: float | None = None
    energy_j: float | None = None


class FirearmCalculation(BaseModel):
    """Firearm ballistic calculation result."""

    model_config = _MODEL_CONFIG

    firearm: FirearmCalculationFirearm
    ammunition: FirearmCalculationAmmo | None = None
    calculated: FirearmCalculationCalculated | None = None
    source_reported: FirearmCalculationSourceReported | None = None
    delta: FirearmCalculationDelta | None = None
    error: str | None = None


class FirearmLoadProfileAmmo(BaseModel):
    """Nested ammunition detail inside FirearmLoadProfile."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    caliber_id: str
    bullet_weight_g: float
    bullet_type: str


class FirearmLoadProfileCalculated(BaseModel):
    """Calculated values inside FirearmLoadProfile."""

    model_config = _MODEL_CONFIG

    muzzle_velocity_mps: float
    muzzle_energy_j: float
    effective_range_m: float
    terminal_ballistics: TerminalBallistics


class FirearmLoadProfileSourceReported(BaseModel):
    """Source-reported values inside FirearmLoadProfile."""

    model_config = _MODEL_CONFIG

    muzzle_velocity_mps: float | None = None
    muzzle_energy_j: float | None = None
    effective_range_m: float | None = None


class FirearmLoadProfile(BaseModel):
    """Firearm load profile including full trajectory."""

    model_config = _MODEL_CONFIG

    firearm: FirearmCalculationFirearm
    ammunition: FirearmLoadProfileAmmo | None = None
    calculated: FirearmLoadProfileCalculated | None = None
    source_reported: FirearmLoadProfileSourceReported | None = None
    trajectory: list[TrajectoryPoint] | None = None
    error: str | None = None


# ---------------------------------------------------------------------------
# Categories
# ---------------------------------------------------------------------------


class Category(BaseModel):
    """A firearm category."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    description: str | None = None


# ---------------------------------------------------------------------------
# Firearm Images
# ---------------------------------------------------------------------------


class FirearmImage(BaseModel):
    """An image associated with a firearm."""

    model_config = _MODEL_CONFIG

    id: int
    firearm_id: str
    url: str
    type: str | None = None
    source: str | None = None
    license: str | None = None


# ---------------------------------------------------------------------------
# Firearm Users (adopters)
# ---------------------------------------------------------------------------


class FirearmUser(BaseModel):
    """A military, law-enforcement, or other institutional user of a firearm."""

    model_config = _MODEL_CONFIG

    id: int
    firearm_id: str
    user_name: str
    user_type: str | None = None
    country_code: str | None = None
    adopted_year: int | None = None
    designation: str | None = None


# ---------------------------------------------------------------------------
# Game Stats
# ---------------------------------------------------------------------------


class GameStats(BaseModel):
    """Extracted game statistics for a firearm (0-100 scale per stat)."""

    model_config = _MODEL_CONFIG

    damage: float | None = None
    accuracy: float | None = None
    range: float | None = None
    fire_rate: float | None = None
    mobility: float | None = None
    recoil_control: float | None = None
    reload_speed: float | None = None
    concealment: float | None = None


class GameProfile(BaseModel):
    """Firearm game profile including archetype classification."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    game_damage: float | None = None
    game_accuracy: float | None = None
    game_range: float | None = None
    game_fire_rate: float | None = None
    game_mobility: float | None = None
    game_recoil_control: float | None = None
    game_reload_speed: float | None = None
    game_concealment: float | None = None
    archetype: str
    strengths: list[str] = []
    weaknesses: list[str] = []


class GameMetaItem(BaseModel):
    """A firearm in the game meta listing."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    archetype: str
    game_damage: float | None = None
    game_accuracy: float | None = None
    game_range: float | None = None
    game_fire_rate: float | None = None
    game_mobility: float | None = None
    game_recoil_control: float | None = None
    game_reload_speed: float | None = None
    game_concealment: float | None = None


# ---------------------------------------------------------------------------
# Game Endpoints
# ---------------------------------------------------------------------------


class BalanceDeviation(BaseModel):
    """A single stat deviation in a balance report."""

    model_config = _MODEL_CONFIG

    stat: str
    value: float
    mean: float
    std_dev: float
    z_score: float


class BalanceEntry(BaseModel):
    """Balance report entry flagging statistical outliers."""

    model_config = _MODEL_CONFIG

    firearm_id: str
    firearm_name: str
    deviations: list[BalanceDeviation] = []


class TierItem(BaseModel):
    """An item within a tier."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    category_id: str | None = None
    value: float


class TierListTiers(BaseModel):
    """Tier groupings (S/A/B/C/D)."""

    model_config = _MODEL_CONFIG

    S: list[TierItem] = []
    A: list[TierItem] = []
    B: list[TierItem] = []
    C: list[TierItem] = []
    D: list[TierItem] = []


class TierList(BaseModel):
    """Tier list grouping for a single game stat."""

    model_config = _MODEL_CONFIG

    stat: str
    tiers: TierListTiers


class MatchupFirearm(BaseModel):
    """A firearm entry in a matchup result."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    stats: GameStats


class MatchupResult(BaseModel):
    """Game matchup result comparing two firearms' game stats."""

    model_config = _MODEL_CONFIG

    a: MatchupFirearm
    b: MatchupFirearm
    verdicts: dict[str, str] = {}
    a_wins: int
    b_wins: int
    draws: int


class RoleRosterItem(BaseModel):
    """A firearm in a role roster."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    role_score: float
    stats: GameStats


class StatDistributionPercentiles(BaseModel):
    """Key percentiles for stat distribution."""

    model_config = _MODEL_CONFIG

    p10: float
    p25: float
    p50: float
    p75: float
    p90: float


class StatDistributionHistogramBucket(BaseModel):
    """A bucket in a stat distribution histogram."""

    model_config = _MODEL_CONFIG

    bucket: str
    count: int


class StatDistribution(BaseModel):
    """Stat distribution / histogram for a single game stat."""

    model_config = _MODEL_CONFIG

    stat: str
    count: int
    mean: float
    median: float
    std_dev: float
    min: float
    max: float
    percentiles: StatDistributionPercentiles
    histogram: list[StatDistributionHistogramBucket] = []


# ---------------------------------------------------------------------------
# Game Stats Snapshots
# ---------------------------------------------------------------------------


class GameStatsVersion(BaseModel):
    """A versioned snapshot of game stats for all firearms."""

    model_config = _MODEL_CONFIG

    id: int
    version: str
    description: str | None = None
    firearm_count: int
    created_at: str


class GameStatsSnapshotEntry(BaseModel):
    """A single entry in a game-stats snapshot."""

    model_config = _MODEL_CONFIG

    id: int
    snapshot_id: int
    firearm_id: str
    firearm_name: str
    game_damage: float | None = None
    game_accuracy: float | None = None
    game_range: float | None = None
    game_fire_rate: float | None = None
    game_mobility: float | None = None
    game_recoil_control: float | None = None
    game_reload_speed: float | None = None
    game_concealment: float | None = None


# ---------------------------------------------------------------------------
# Firearm Comparisons
# ---------------------------------------------------------------------------


class FirearmComparison(BaseModel):
    """Comparison result for multiple firearms."""

    model_config = _MODEL_CONFIG

    items: list[FirearmDetail] = []
    deltas: dict[str, Any] = {}


class CaliberComparison(BaseModel):
    """Comparison result for multiple calibers."""

    model_config = _MODEL_CONFIG

    items: list[Caliber] = []
    deltas: dict[str, Any] = {}


# ---------------------------------------------------------------------------
# Head-to-Head
# ---------------------------------------------------------------------------


class HeadToHeadVerdict(BaseModel):
    """Per-field verdict in a head-to-head comparison."""

    model_config = _MODEL_CONFIG

    winner: str
    a: float | None = None
    b: float | None = None
    better: str


class HeadToHead(BaseModel):
    """Head-to-head comparison of two firearms on numeric specs."""

    model_config = _MODEL_CONFIG

    a: dict[str, Any] = {}
    b: dict[str, Any] = {}
    verdicts: dict[str, HeadToHeadVerdict] = {}


# ---------------------------------------------------------------------------
# Family Tree
# ---------------------------------------------------------------------------


class FamilyTree(BaseModel):
    """Firearm family tree (ancestors + current + descendants)."""

    model_config = _MODEL_CONFIG

    ancestors: list[dict[str, Any]] = []
    current: Firearm
    descendants: list[dict[str, Any]] = []


# ---------------------------------------------------------------------------
# Similar Firearms
# ---------------------------------------------------------------------------


class SimilarFirearm(BaseModel):
    """A similar firearm with a computed similarity score."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    score: float


# ---------------------------------------------------------------------------
# Adoption Map
# ---------------------------------------------------------------------------


class AdoptionMapUser(BaseModel):
    """A user entry in an adoption map country."""

    model_config = _MODEL_CONFIG

    name: str
    type: str | None = None
    year: int | None = None
    designation: str | None = None


class AdoptionMapCountry(BaseModel):
    """A country group in an adoption map."""

    model_config = _MODEL_CONFIG

    code: str | None = None
    users: list[AdoptionMapUser] = []


class AdoptionMap(BaseModel):
    """Adoption map for a firearm, grouped by country."""

    model_config = _MODEL_CONFIG

    firearm_id: str
    firearm_name: str
    countries: list[AdoptionMapCountry] = []


# ---------------------------------------------------------------------------
# Top Firearms
# ---------------------------------------------------------------------------


class TopFirearmItem(BaseModel):
    """A firearm in a 'top N' ranking."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    manufacturer_id: str
    category_id: str
    value: float
    unit: str


# ---------------------------------------------------------------------------
# Power Rating
# ---------------------------------------------------------------------------


class PowerRatingBreakdown(BaseModel):
    """Per-component breakdown of a power rating."""

    model_config = _MODEL_CONFIG

    energy: float
    range: float
    fire_rate: float
    capacity: float
    mobility: float


class PowerRating(BaseModel):
    """A firearm's computed power rating with breakdown."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    manufacturer_id: str
    category_id: str
    power_rating: float
    breakdown: PowerRatingBreakdown


# ---------------------------------------------------------------------------
# Timeline
# ---------------------------------------------------------------------------


class TimelineItem(BaseModel):
    """A firearm in a chronological timeline listing."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    manufacturer_id: str
    category_id: str
    year_introduced: int | None = None
    year_discontinued: int | None = None
    status: str | None = None
    country_of_origin: str | None = None


# ---------------------------------------------------------------------------
# Dimensions
# ---------------------------------------------------------------------------


class DimensionsMetric(BaseModel):
    """Metric measurements for a firearm."""

    model_config = _MODEL_CONFIG

    weight_empty_g: float | None = None
    weight_loaded_g: float | None = None
    overall_length_mm: float | None = None
    barrel_length_mm: float | None = None
    height_mm: float | None = None
    width_mm: float | None = None
    folded_length_mm: float | None = None


class DimensionsImperial(BaseModel):
    """Imperial measurements for a firearm (converted from metric)."""

    model_config = _MODEL_CONFIG

    weight_empty_lbs: float | None = None
    weight_loaded_lbs: float | None = None
    overall_length_in: float | None = None
    barrel_length_in: float | None = None
    height_in: float | None = None
    width_in: float | None = None
    folded_length_in: float | None = None


class Dimensions(BaseModel):
    """Firearm dimensions in both metric and imperial units."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    metric: DimensionsMetric
    imperial: DimensionsImperial


# ---------------------------------------------------------------------------
# Filter Options
# ---------------------------------------------------------------------------


class FilterOptionCategory(BaseModel):
    """A category option in filter dropdowns."""

    model_config = _MODEL_CONFIG

    slug: str
    name: str


class FilterOptionItem(BaseModel):
    """A generic filter option (manufacturer, caliber, action type)."""

    model_config = _MODEL_CONFIG

    id: str
    name: str


class FilterOptions(BaseModel):
    """Available filter dropdown options."""

    model_config = _MODEL_CONFIG

    categories: list[FilterOptionCategory] = []
    manufacturers: list[FilterOptionItem] = []
    calibers: list[FilterOptionItem] = []
    action_types: list[FilterOptionItem] = []


# ---------------------------------------------------------------------------
# Statistics
# ---------------------------------------------------------------------------


class StatsSummary(BaseModel):
    """Database summary statistics."""

    model_config = _MODEL_CONFIG

    total_firearms: int
    total_manufacturers: int
    total_calibers: int
    countries_of_origin: int
    avg_confidence: float | None = None
    total_variants: int


class ProductionStatusItem(BaseModel):
    """Production status breakdown."""

    model_config = _MODEL_CONFIG

    status: str
    count: int


class FieldCoverage(BaseModel):
    """Field coverage percentage for a single field."""

    model_config = _MODEL_CONFIG

    field: str
    percentage: float


class PopularCaliber(BaseModel):
    """Popular caliber with firearm count."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    nato_designation: str | None = None
    firearm_count: int


class ProlificManufacturer(BaseModel):
    """Prolific manufacturer with firearm count."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    country_code: str | None = None
    firearm_count: int


class CategoryStats(BaseModel):
    """Category statistics with averages."""

    model_config = _MODEL_CONFIG

    id: str
    name: str
    firearm_count: int
    avg_weight_g: float | None = None
    avg_magazine_capacity: float | None = None
    avg_barrel_length_mm: float | None = None


class EraStats(BaseModel):
    """Era (decade) statistics."""

    model_config = _MODEL_CONFIG

    firearm_count: int
    avg_weight_g: float | None = None
    avg_magazine_capacity: float | None = None
    avg_barrel_length_mm: float | None = None
    earliest_year: int | None = None
    latest_year: int | None = None


class MaterialStatsEntry(BaseModel):
    """A material with its usage count."""

    model_config = _MODEL_CONFIG

    material: str
    count: int


class MaterialStats(BaseModel):
    """Material usage breakdown per component."""

    model_config = _MODEL_CONFIG

    frame: list[MaterialStatsEntry] = []
    slide: list[MaterialStatsEntry] = []
    barrel: list[MaterialStatsEntry] = []
    stock: list[MaterialStatsEntry] = []


class AdoptionByCountryItem(BaseModel):
    """Adoption record by country."""

    model_config = _MODEL_CONFIG

    id: int
    user_name: str
    user_type: str | None = None
    adopted_year: int | None = None
    designation: str | None = None
    firearm_id: str
    firearm_name: str


class AdoptionByTypeItem(BaseModel):
    """Adoption record by user type."""

    model_config = _MODEL_CONFIG

    firearm_id: str
    firearm_name: str
    adoption_count: int
    countries: list[str] = []


class ActionTypeStats(BaseModel):
    """Action type frequency."""

    model_config = _MODEL_CONFIG

    action_type: str
    count: int


class FeatureFrequency(BaseModel):
    """Feature frequency item."""

    model_config = _MODEL_CONFIG

    feature: str
    count: int


class CaliberPopularityByEraCaliberEntry(BaseModel):
    """A caliber entry within a decade's popularity ranking."""

    model_config = _MODEL_CONFIG

    caliber_id: str
    caliber_name: str
    firearm_count: int


class CaliberPopularityByEra(BaseModel):
    """Caliber popularity within a decade."""

    model_config = _MODEL_CONFIG

    decade: str
    calibers: list[CaliberPopularityByEraCaliberEntry] = []


# ---------------------------------------------------------------------------
# Countries
# ---------------------------------------------------------------------------


class Country(BaseModel):
    """A country with its firearm count."""

    model_config = _MODEL_CONFIG

    code: str
    firearm_count: int


class CountryArsenalGroup(BaseModel):
    """A usage-type group in a country's arsenal."""

    model_config = _MODEL_CONFIG

    type: str
    firearms: list[Firearm] = []


class CountryArsenal(BaseModel):
    """A country's firearm arsenal -- military and law enforcement holdings."""

    model_config = _MODEL_CONFIG

    country: Country
    total_firearms: int
    groups: list[CountryArsenalGroup] = []


# ---------------------------------------------------------------------------
# Conflicts
# ---------------------------------------------------------------------------


class ConflictFirearm(BaseModel):
    """A firearm entry within a conflict."""

    model_config = _MODEL_CONFIG

    id: str
    name: str


class Conflict(BaseModel):
    """A conflict with associated firearms."""

    model_config = _MODEL_CONFIG

    name: str
    firearm_count: int
    firearms: list[ConflictFirearm] = []


# ---------------------------------------------------------------------------
# Data Quality
# ---------------------------------------------------------------------------


class DataCoverage(BaseModel):
    """Data coverage summary."""

    model_config = _MODEL_CONFIG

    field: str
    percentage: float


class ConfidenceEntry(BaseModel):
    """A firearm record with its computed data confidence score."""

    model_config = _MODEL_CONFIG

    slug: str
    name: str
    confidence_score: float
    filled_fields: int
    total_fields: int


# ---------------------------------------------------------------------------
# Ballistics Result
# ---------------------------------------------------------------------------


class BallisticsResult(BaseModel):
    """Ballistics data for a caliber at a given distance."""

    model_config = _MODEL_CONFIG

    caliber_id: str
    distance_m: float
    velocity_fps: float
    energy_ft_lbs: float
    drop_inches: float
    drift_inches: float | None = None
    time_of_flight_s: float | None = None


# ---------------------------------------------------------------------------
# Silhouette
# ---------------------------------------------------------------------------


class Silhouette(BaseModel):
    """SVG silhouette data for a firearm."""

    model_config = _MODEL_CONFIG

    slug: str
    svg: str | None = None
    data_uri: str | None = None
    stroke_width: float | None = None
    stroke_color: str | None = None
    width: int | None = None
    height: int | None = None


# ---------------------------------------------------------------------------
# Balance Report
# ---------------------------------------------------------------------------


class BalanceReport(BaseModel):
    """Game balance report identifying outlier firearms."""

    model_config = _MODEL_CONFIG

    threshold: float
    total_analyzed: int
    overpowered: list[BalanceEntry] = []
    underpowered: list[BalanceEntry] = []
    deviations: list[BalanceDeviation] | None = None


# ---------------------------------------------------------------------------
# Role Roster
# ---------------------------------------------------------------------------


class RoleRoster(BaseModel):
    """A roster of firearms suited for a specific game role."""

    model_config = _MODEL_CONFIG

    role: str
    total_considered: int
    firearms: list[RoleRosterItem] = []


# ---------------------------------------------------------------------------
# User-Scoped Resources
# ---------------------------------------------------------------------------


class Favorite(BaseModel):
    """A user's favorited firearm."""

    model_config = _MODEL_CONFIG

    firearm_id: str
    created_at: str


class FavoriteToggle(BaseModel):
    """Result of toggling a favorite."""

    model_config = _MODEL_CONFIG

    firearm_id: str
    favorited: bool


class DataReport(BaseModel):
    """A user-submitted data quality report."""

    model_config = _MODEL_CONFIG

    id: str
    firearm_id: str
    section: str
    issue_type: str
    description: str
    references: list[str] | None = None
    suggested_value: str | None = None
    status: str
    created_at: str
    updated_at: str


class SupportTicket(BaseModel):
    """A support ticket summary."""

    model_config = _MODEL_CONFIG

    id: str
    subject: str
    description: str
    category: str | None = None
    priority: str
    status: str
    created_at: str
    updated_at: str


class SupportTicketReply(BaseModel):
    """A single reply in a support ticket thread."""

    model_config = _MODEL_CONFIG

    id: int
    ticket_id: str
    message: str
    is_staff: bool
    created_at: str


class SupportTicketDetail(SupportTicket):
    """A support ticket with its reply thread."""

    replies: list[SupportTicketReply] = []


class WebhookEndpoint(BaseModel):
    """A webhook endpoint configuration."""

    model_config = _MODEL_CONFIG

    id: str
    url: str
    description: str | None = None
    events: list[str] = []
    active: bool
    secret: str
    created_at: str
    updated_at: str


class WebhookTestResult(BaseModel):
    """Result of sending a test event to a webhook endpoint."""

    model_config = _MODEL_CONFIG

    success: bool
    status_code: int
    response_time_ms: float
    error: str | None = None


class UsageStatsCurrentMonth(BaseModel):
    """Current billing month usage."""

    model_config = _MODEL_CONFIG

    used: int
    limit: int
    percentage: float
    resets_at: str


class UsageStatsDailyEntry(BaseModel):
    """A daily request count entry."""

    model_config = _MODEL_CONFIG

    date: str
    count: int


class UsageStatsPerKeyEntry(BaseModel):
    """Per-API-key usage entry."""

    model_config = _MODEL_CONFIG

    key_id: str
    key_name: str
    count: int


class UsageStatsTier(BaseModel):
    """Current subscription tier details."""

    model_config = _MODEL_CONFIG

    name: str
    requests_per_month: int
    rate_limit: int


class UsageStats(BaseModel):
    """API usage statistics for the authenticated user."""

    model_config = _MODEL_CONFIG

    current_month: UsageStatsCurrentMonth
    daily_breakdown: list[UsageStatsDailyEntry] = []
    per_key: list[UsageStatsPerKeyEntry] = []
    key_count: int
    tier: UsageStatsTier


# ---------------------------------------------------------------------------
# Generic Response Wrappers
# ---------------------------------------------------------------------------


class PaginationMeta(BaseModel):
    """Pagination metadata."""

    model_config = _MODEL_CONFIG

    page: int
    per_page: int
    total: int
    total_pages: int


class PaginatedResponseModel(BaseModel):
    """Standard paginated API response wrapper."""

    model_config = _MODEL_CONFIG

    success: bool
    data: list[Any] = []
    pagination: PaginationMeta


class SuccessResponseModel(BaseModel):
    """Standard single-item API response wrapper."""

    model_config = _MODEL_CONFIG

    success: bool
    data: Any = None
