package eu.mulk.aendggner.gesetz.land;

import static org.assertj.core.api.Assertions.assertThat;

import eu.mulk.aendggner.gesetz.Gliederung;
import org.junit.jupiter.api.Test;

class LandesRechtTextParserTest {

  // Bayern: Gliederung in „Art.“, amtliche Satznummern als Superskript.
  private static final String BAYERN =
      """
      BayJG: Bayerisches Jagdgesetz (BayJG) Vom 13. Oktober 1978 (BayRS V S. 595) BayRS 792-1-W (Art.
      1–64)
      Bayerisches Jagdgesetz
      (BayJG)
      Vom 13. Oktober 1978
      (BayRS V S. 595)
      BayRS 792-1-W
      Vollzitat nach RedR: Bayerisches Jagdgesetz (BayJG) in der in der Bayerischen Rechtssammlung (BayRS
      792-1-L) veröffentlichten bereinigten Fassung
      I. Abschnitt Grundsätze
      Art. 1  Gesetzeszweck

      (1) ¹Die freilebende Tierwelt ist wesentlicher Bestandteil der heimischen Natur. ²Sie ist zu bewahren.
      (2) Dieses Gesetz soll dazu dienen:
      1.  einen artenreichen Wildbestand zu erhalten,

      2.  die Lebensgrundlagen des Wildes zu sichern.

      II. Abschnitt Jagdreviere, Hegegemeinschaften
      1. Allgemeine Vorschriften
      Art. 3  Feststellung der Jagdreviere

      Bestand, Umfang und Grenzen eines Jagdreviers werden durch die
      Jagdbehörde festgestellt.
      2. Jagdreviere
      Art. 8  Eigenjagdreviere

      (1) ¹Die Mindestgröße beträgt 81,755 ha. ²Die Art. 4 Abs. 3, Art. 5 Abs. 2 und
      Art. 11 Abs. 6 sind entsprechend anzuwenden.
      Art. 59  Enteignende Maßnahmen

      (1) Es ist nach den Vorschriften des Gesetzes über die entschädigungspflichtige Enteignung⁶) Entschädigung zu leisten.
      6) [Amtl. Anm.:] BayRS 2141-1-I
      Art. 60  (aufgehoben)

      Art. 63 (Änderungsbestimmung)

      Art. 64  Inkrafttreten; Aufhebung von Vorschriften

      (1) Dieses Gesetz tritt am 1. Januar 1979 in Kraft.
      """;

  // Übriges Landesrecht: Gliederung in „§“ (wie der Bund), hier mit amtlichen Satznummern.
  private static final String PARAGRAPHEN =
      """
      Gemeindeordnung für das Land Nordrhein-Westfalen
      (GO NRW)
      Vom 14. Juli 1994
      I. Teil Grundlagen der Gemeindeverfassung
      § 1  Wesen der Gemeinde

      (1) ¹Die Gemeinden sind die Grundlage des demokratischen Staatsaufbaus. ²Sie fördern das Wohl der Einwohner.
      (2) Die Gemeinden verwalten ihre Angelegenheiten selbst.
      § 2  Aufgaben

      Die Gemeinden erfüllen die Aufgaben der örtlichen Gemeinschaft.
      § 3  (weggefallen)

      § 4  Satzungen

      (1) Die Gemeinden können ihre Angelegenheiten durch Satzung regeln.
      """;

  @Test
  void parstBayerischenTitelblock() {
    var gesetz = LandesRechtTextParser.parse(BAYERN);
    assertThat(gesetz.jurabk()).isEqualTo("BayJG");
    assertThat(gesetz.langue()).isEqualTo("Bayerisches Jagdgesetz");
    assertThat(gesetz.kurzue()).isNull();
  }

  @Test
  void parstBayerischeNormenMitTitelnUndAbsaetzen() {
    var gesetz = LandesRechtTextParser.parse(BAYERN);
    assertThat(gesetz.normen())
        .extracting(n -> n.enbez())
        .containsExactly("Art. 1", "Art. 3", "Art. 8", "Art. 59", "Art. 60", "Art. 63", "Art. 64");

    var art1 = gesetz.norm("Art. 1").orElseThrow();
    assertThat(art1.titel()).isEqualTo("Gesetzeszweck");
    assertThat(art1.absaetze()).hasSize(2);
    assertThat(art1.absaetze().get(0).nummer()).isEqualTo("1");
    assertThat(art1.absaetze().get(0).text()).startsWith("¹Die freilebende Tierwelt");
    assertThat(art1.absaetze().get(1).text()).contains("1.  einen artenreichen");

    // Unnummerierter Einzelabsatz.
    var art3 = gesetz.norm("Art. 3").orElseThrow();
    assertThat(art3.absaetze()).hasSize(1);
    assertThat(art3.absaetze().get(0).nummer()).isNull();
  }

  @Test
  void querverweiseAmZeilenanfangEroeffnenKeineNorm() {
    // „Art. 11 Abs. 6 …“ am Zeilenanfang in Art. 8 ist ein Querverweis, kein Normkopf.
    var gesetz = LandesRechtTextParser.parse(BAYERN);
    var art8 = gesetz.norm("Art. 8").orElseThrow();
    assertThat(art8.absaetze().get(0).text()).contains("Art. 11 Abs. 6 sind entsprechend");
    assertThat(gesetz.norm("Art. 11")).isEmpty();
  }

  @Test
  void parstGliederungenMitUnterUeberschriften() {
    var gesetz = LandesRechtTextParser.parse(BAYERN);
    assertThat(gesetz.gliederungen())
        .extracting(Gliederung::anzeigeText)
        .containsExactly(
            "I. Abschnitt — Grundsätze",
            "II. Abschnitt — Jagdreviere, Hegegemeinschaften",
            "1. — Allgemeine Vorschriften",
            "2. — Jagdreviere");
    // Kennzahlen sind eindeutig und hängen an der Eltern-Gliederung.
    assertThat(gesetz.gliederungen())
        .extracting(Gliederung::kennzahl)
        .containsExactly("001", "002", "002.1", "002.2");
    assertThat(gesetz.norm("Art. 8").orElseThrow().gliederung().kennzahl()).isEqualTo("002.2");
  }

  @Test
  void erkenntWeggefalleneNormenUndFussnoten() {
    var gesetz = LandesRechtTextParser.parse(BAYERN);
    assertThat(gesetz.norm("Art. 60").orElseThrow().weggefallen()).isTrue();
    assertThat(gesetz.norm("Art. 63").orElseThrow().weggefallen()).isFalse();

    // Fußnotenzeile bleibt superskript-normalisiert im tragenden Absatz.
    var art59 = gesetz.norm("Art. 59").orElseThrow();
    assertThat(art59.absaetze().get(0).text())
        .contains("Enteignung⁶)")
        .contains("⁶) [Amtl. Anm.:] BayRS 2141-1-I");
  }

  @Test
  void parstParagraphengegliedertesLandesrecht() {
    // Die übrigen Länder zitieren in „§“; das Sigel folgt aus dem Normkopf, ein Land-Merkmal ist
    // nicht nötig. Amtliche Satznummern werden ebenso wie bei Bayern erhalten.
    var gesetz = LandesRechtTextParser.parse(PARAGRAPHEN);
    assertThat(gesetz.jurabk()).isEqualTo("GO NRW");
    assertThat(gesetz.langue()).isEqualTo("Gemeindeordnung für das Land Nordrhein-Westfalen");
    assertThat(gesetz.normen())
        .extracting(n -> n.enbez())
        .containsExactly("§ 1", "§ 2", "§ 3", "§ 4");

    var p1 = gesetz.norm("§ 1").orElseThrow();
    assertThat(p1.titel()).isEqualTo("Wesen der Gemeinde");
    assertThat(p1.absaetze()).hasSize(2);
    assertThat(p1.absaetze().get(0).text()).startsWith("¹Die Gemeinden sind die Grundlage");

    // Unnummerierter Einzelabsatz und weggefallene Norm wie im bayerischen Fall.
    assertThat(gesetz.norm("§ 2").orElseThrow().absaetze().get(0).nummer()).isNull();
    assertThat(gesetz.norm("§ 3").orElseThrow().weggefallen()).isTrue();
    assertThat(gesetz.gliederungen()).extracting(Gliederung::anzeigeText).containsExactly("I. Teil — Grundlagen der Gemeindeverfassung");
  }
}
