use chrono::{DateTime, NaiveDate, NaiveTime, TimeDelta, Utc};
use crate::{
currency, money::VatOrigin, tariff::v2x::DimensionType, Ampere, Kw, Kwh, Money, Price, Weekday,
};
pub(super) struct Explanation {
pub currency: currency::Code,
pub body: Body,
}
pub(super) enum Body {
Sections(Vec<Section>),
Fallback(Fallback),
}
pub(super) enum Section {
Dimension(Dimension),
Flat(Flat),
Bounds(Bounds),
Validity(Validity),
}
pub(super) struct Dimension {
pub kind: DimensionType,
pub tiers: Vec<Tier>,
pub uniform_step: Option<u64>,
pub dropped_unreachable: bool,
}
pub(super) struct Tier {
pub condition: Condition,
pub rate: Rate,
pub step: Option<u64>,
}
pub(super) enum Rate {
Free,
Priced { amount: Money, vat: VatOrigin },
}
pub(super) struct Flat {
pub tiers: Vec<FlatTier>,
}
pub(super) struct FlatTier {
pub condition: Condition,
pub fee: FlatFee,
}
pub(super) enum FlatFee {
NoFee,
Charged { amount: Money, vat: VatOrigin },
}
pub(super) enum Condition {
Always,
Remaining,
Otherwise,
When(Vec<ConditionPart>),
}
pub(super) enum ConditionPart {
TimeWindow(TimeWindow),
Weekdays(Vec<Weekday>),
DateRange {
start: Option<NaiveDate>,
end: Option<NaiveDate>,
},
MinPower(Kw),
MaxPower(Kw),
MinCurrent(Ampere),
MaxCurrent(Ampere),
DurationScope(Scope<TimeDelta>),
EnergyScope(Scope<Kwh>),
}
pub(super) enum TimeWindow {
Empty { start: NaiveTime, end: NaiveTime },
Wrapping { start: NaiveTime, end: NaiveTime },
Between { start: NaiveTime, end: NaiveTime },
From { start: NaiveTime },
Before { end: NaiveTime },
}
pub(super) enum Scope<T> {
UpTo(T),
After(T),
Between(T, T),
}
pub(super) struct Bounds {
pub min: Option<Price>,
pub max: Option<Price>,
}
pub(super) enum Validity {
Between {
start: DateTime<Utc>,
end: DateTime<Utc>,
},
From { start: DateTime<Utc> },
Until { end: DateTime<Utc> },
}
pub(super) enum Fallback {
ReservationOnly,
NoPriceComponents,
FreeFlatOnly,
}