using System.Globalization;
namespace Flaro.Core.Library;
/// Ein Anlass, zu dem eine eigene Reihe auf der Startseite steht.
///
/// Was über der Reihe steht — „Zu Halloween".
/// Tag im Jahr, ab dem sie erscheint, als „MM-TT".
/// Tag im Jahr, bis zu dem sie bleibt, als „MM-TT".
/// Stichwörter der Metadatenquelle, kleingeschrieben.
/// Genres, falls Stichwörter allein zu wenig hergeben.
///
///
///
/// Einstellbar und nicht eingebaut. Halloween und Weihnachten kennt
/// jeder; der 1. August ist Schweizer Nationalfeiertag, der 4. Juli
/// amerikanischer, und der Geburtstag des Betreibers steht in keiner
/// Bibliothek. Eine feste Liste im Quelltext hiesse: für jeden Anlass eine
/// neue Fassung.
///
///
/// Stichwörter zuerst, Genres als Zugabe. „Stirb langsam" ist kein
/// Familienfilm und trägt trotzdem „christmas" — eine Weihnachtsreihe nach
/// Genres enthielte jeden Zeichentrickfilm und diesen Film nicht.
///
///
public sealed record Saisonanlass(
string Name,
string Von,
string Bis,
IReadOnlyList Stichworte,
IReadOnlyList Genres)
{
/// Was ohne eigene Einstellung dasteht.
///
///
/// Vier, und bewusst nicht mehr. Eine lange Vorgabeliste wäre
/// eine Meinung darüber, was jemand feiert. Diese vier sind weit genug
/// verbreitet, um als Beispiel zu taugen, und zeigen zugleich die drei
/// Formen: ein Zeitraum im Jahr, einer über den Jahreswechsel, und
/// einer, der sich auf Genres stützt.
///
public static IReadOnlyList Vorgabe { get; } =
[
new("Zu Halloween", "10-01", "11-01",
["halloween", "haunted house", "witch", "slasher", "zombie"],
["Horror"]),
new("Zur Weihnachtszeit", "12-01", "12-27",
["christmas", "santa claus", "christmas eve"],
[]),
new("Zum Jahreswechsel", "12-28", "01-02",
["new year's eve", "new year"],
[]),
new("Für den Sommer", "06-15", "08-31",
["summer", "beach", "summer vacation", "road trip"],
[]),
];
/// Ob dieser Anlass an diesem Tag gilt.
///
///
/// Über den Jahreswechsel hinweg. „28.12. bis 02.01." ist kein
/// Fehler, sondern der Normalfall für Silvester — ein Vergleich, der nur
/// „von ≤ heute ≤ bis" kennt, fände diesen Zeitraum nie.
///
public bool Gilt(DateTimeOffset tag)
{
if (Tagnummer(Von) is not { } von || Tagnummer(Bis) is not { } bis) return false;
var heute = tag.Month * 100 + tag.Day;
return von <= bis
? heute >= von && heute <= bis
: heute >= von || heute <= bis;
}
/// „12-24" wird zu 1224 — oder zu null, wenn es keiner ist.
private static int? Tagnummer(string roh)
{
var teile = (roh ?? "").Split('-');
if (teile.Length != 2) return null;
if (!int.TryParse(teile[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var monat)) return null;
if (!int.TryParse(teile[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var tag)) return null;
if (monat is < 1 or > 12 || tag is < 1 or > 31) return null;
return monat * 100 + tag;
}
/// Ob der Anlass überhaupt etwas finden kann.
public bool Brauchbar =>
!string.IsNullOrWhiteSpace(Name)
&& Tagnummer(Von) is not null && Tagnummer(Bis) is not null
&& (Stichworte.Count > 0 || Genres.Count > 0);
}