using MeterVault.App.Analysis;
using MeterVault.App.Localization;
using MeterVault.App.TariffEditing;
using MeterVault.Core.Analysis;
using MeterVault.Core.Analysis.Costing;
using MeterVault.Core.Analysis.Totals;
using MeterVault.Core.Analysis.Virtual;
using MeterVault.Core.Domain;
using static MeterVault.Integration.Tests.Analysis.AnalysisUiTestData;
namespace MeterVault.Integration.Tests.Analysis;
///
/// The seams where the reworked pages meet (integration of the page reworks): a cost whose quantity is unknown says so
/// instead of "Priced" beside "—"; the meter's Calculation tab words a finding like the attention list, leaving the
/// meters to its links; the tariff list and a meter's Tariffs tab agree on when a tariff ends. Pure; no database.
///
public sealed class PageIntegrationTests
{
[Fact]
public void A_priced_bucket_without_quantity_reads_as_its_quantity_status() => In("en", () =>
{
var buckets = Buckets(D(2026, 1, 1), D(2026, 2, 28));
var tariff = new Tariff
{
Id = 1,
ScopeType = TariffScope.EnergyType,
ScopeId = 1,
Component = TariffComponent.UnitPrice,
Value = 0.3,
Unit = "EUR/kWh",
ValidFrom = D(2000, 1, 1),
};
var parts = CostCalculator.Parts(buckets).ToList();
List quantities = [CostQuantity.Known(parts[0], 100), CostQuantity.Unknown(parts[1])];
var line = new CostLine(10, 1, BillLineKind.UnitPrice, "kWh", quantities);
var cost = CostCalculator.Calculate(new CostRequest(buckets, D(2039, 12, 31), TariffBook.Create([tariff], "EUR"), [line]));
var priced = FigureText.Of(cost.Totals[0]);
Assert.True(priced.IsKnown);
Assert.Equal("Priced", priced.Status);
var noQuantity = FigureText.Of(cost.Totals[1]);
Assert.False(noQuantity.IsKnown);
Assert.Equal(BucketStatus.Missing.Display(), noQuantity.Status);
Assert.Null(noQuantity.Detail);
// A known cost over incomplete quantities keeps naming its prices, with the quantities' state as detail.
var total = FigureText.Of(cost.Total);
Assert.True(total.IsKnown);
Assert.Equal("Priced", total.Status);
Assert.Contains(BucketStatus.Partial.Display(), total.Detail);
});
[Fact]
public void The_calculation_tab_words_a_finding_like_the_attention_list_without_the_meters() => In("en", () =>
{
var names = new AttentionNames(new Dictionary { [4] = "Solar 1", [8] = "Wasser" });
var units = new VirtualProblem(VirtualProblemKind.UnitMismatch, [4, 8], ["kWh", "m³"]);
var cycle = new VirtualProblem(VirtualProblemKind.DependencyCycle, [9, 4, 9], []);
var kinds = new VirtualProblem(VirtualProblemKind.ResultKindRequired, [4, 8], ["generation", "mixed"]);
Assert.Equal(VirtualProblemKind.UnitMismatch.Display() + " (kWh, m³)", AttentionItems.VirtualReasonWithoutMeters(units));
Assert.Equal(VirtualProblemKind.DependencyCycle.Display(), AttentionItems.VirtualReasonWithoutMeters(cycle));
Assert.StartsWith(VirtualProblemKind.ResultKindRequired.Display() + " (" + QuantityKind.Generation.Display() + ", ",
AttentionItems.VirtualReasonWithoutMeters(kinds));
Assert.EndsWith(", gemischt)", In("de", () => AttentionItems.VirtualReasonWithoutMeters(kinds)));
// The attention list names the meters itself.
Assert.Contains("Solar 1", AttentionItems.VirtualReason(new VirtualProblem(VirtualProblemKind.SourceInvalid, [4], []), names));
Assert.Equal(
VirtualProblemKind.DependencyCycle.Display() + " (Meter #9 → Solar 1 → Meter #9)",
AttentionItems.VirtualReason(cycle, names));
});
[Fact]
public void A_tariff_ends_where_the_next_one_of_its_kind_starts()
{
TariffSpan[] tariffs =
[
new(1, TariffScope.EnergyType, 1, TariffComponent.UnitPrice, D(2023, 1, 1), null),
new(2, TariffScope.EnergyType, 1, TariffComponent.UnitPrice, D(2024, 1, 1), null),
new(3, TariffScope.EnergyType, 1, TariffComponent.UnitPrice, D(2025, 1, 1), D(2025, 6, 30)),
new(4, TariffScope.EnergyType, 2, TariffComponent.UnitPrice, D(2023, 6, 1), null),
new(5, TariffScope.EnergyType, 1, TariffComponent.BasePrice, D(2023, 1, 1), D(2030, 12, 31)),
new(6, TariffScope.EnergyType, 1, TariffComponent.BasePrice, D(2026, 1, 1), null),
];
var ends = TariffValidity.EffectiveEnds(tariffs);
Assert.Equal(D(2023, 12, 31), ends[1]);
Assert.Equal(D(2024, 12, 31), ends[2]);
Assert.Equal(D(2025, 6, 30), ends[3]);
Assert.Null(ends[4]);
Assert.Equal(D(2025, 12, 31), ends[5]);
Assert.Null(ends[6]);
}
}