// Copyright (C) 2026 Jason M. Schwefel. All Rights Reserved.
package com.coldboreballisticsllc.scopedope.domain.model

import com.coldboreballisticsllc.scopedope.ballistics.BcModel
import com.coldboreballisticsllc.scopedope.ballistics.BcZone
import com.coldboreballisticsllc.scopedope.ballistics.TwistDirection

// BcModel, BcZone, and TwistDirection are defined in :ballistics commonMain and re-exported
// here via typealias so existing domain.model.* wildcard imports continue to resolve.
typealias BcModel        = com.coldboreballisticsllc.scopedope.ballistics.BcModel
typealias BcZone         = com.coldboreballisticsllc.scopedope.ballistics.BcZone
typealias TwistDirection = com.coldboreballisticsllc.scopedope.ballistics.TwistDirection

data class AmmoLoad(
    val id:                   Int,
    val caliber:              String,
    val name:                 String,
    val muzzleVelFps:         Int,
    val bc:                   Double,
    val bcModel:              BcModel,
    val bcG1:                 Double  = 0.0,
    val bcG7:                 Double  = 0.0,
    // Velocity-dependent BC bands (P2). Empty = use single bc field.
    val bcZones:              List<BcZone> = emptyList(),
    val formFactor:           Double  = 0.0,
    val bulletDiameterMm:     Double  = 0.0,
    val bulletLengthMm:       Double  = 0.0,
    val bulletWeightGr:       Double  = 0.0,
    val mvSensitivityFpsPerF: Double  = 0.0,
    val mvReferenceTempF:     Double  = 59.0,
    val isUserDefined:        Boolean = false,
)

// ── DOPE entries ──────────────────────────────────────────────────────────────

data class ConditionsAtMeasurement(
    val altitudeFt:   Int?    = null,
    val temperatureF: Double? = null,
    val pressureHpa:  Double? = null,
    val humidityPct:  Double? = null,
    val windSpeedMph: Double? = null,
    val windAngleDeg: Double? = null,
)

data class DopeEntry(
    val distanceYards:            Int,
    val adjustmentMil:            Double,
    val recordedAt:               String?                    = null,
    val conditionsAtMeasurement:  ConditionsAtMeasurement?  = null,
)

// ── Conditions ────────────────────────────────────────────────────────────────

data class RangeConditions(
    val altitudeFt:     Int    = 0,
    val temperatureF:   Double = 59.0,
    val pressureHpa:    Double = 1013.25,
    val humidityPct:    Double = 50.0,
)

data class WindConditions(
    val speedMph:       Double = 0.0,
    val angleDeg:       Double = 90.0,    // degrees relative to shooter, not cardinal
)

// ── Calculation output ────────────────────────────────────────────────────────

data class ResultRow(
    val distanceYards:     Int,
    val elevationMil:      Double,
    val elevationMoa:      Double,
    val windageMil:        Double,
    val windageMoa:        Double,
    val spinDriftMil:      Double  = 0.0,
    val spinDriftMoa:      Double  = 0.0,
    val coriolisElevMil:   Double  = 0.0,
    val coriolisElevMoa:   Double  = 0.0,
    val coriolisWindMil:   Double  = 0.0,
    val coriolisWindMoa:   Double  = 0.0,
    val aerodynamicJumpMil: Double = 0.0,
    val aerodynamicJumpMoa: Double = 0.0,
    val clicks:            Int,
    val isSubsonic:        Boolean = false,
    val includeOnLabel:    Boolean = true,
)

// ── Label rendering ───────────────────────────────────────────────────────────

data class WindLabel(
    val speedMph: Double,
    val angleDeg: Double,
)

/** One row of data that will appear on a printed/exported label. */
data class LabelEntry(
    val distanceYards: Int,
    val elevationMil:  Double,
    val windageMil:    Double = 0.0,
    val elevationMoa:  Double = 0.0,
    val windageMoa:    Double = 0.0,
)
