package de.roko.genalogy.downloader.database;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ArchivStrukturParser {

    private static final String DB = "archion.db";

    public void parse() throws Exception {
        try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + DB)) {

            String sql = "SELECT id, name, link FROM archive ORDER BY id";
            try (PreparedStatement stmt = conn.prepareStatement(sql);
                 ResultSet rs = stmt.executeQuery()) {

                while (rs.next()) {
                    int archivId = rs.getInt("id");
                    String archivName = rs.getString("name");
                    String archivLink = rs.getString("link");

                    System.out.println("\n🔍 Verarbeite Archiv: " + archivName);
                    processArchiv(conn, archivId, archivLink);
                }
            }
        }
    }

    private static void processArchiv(Connection conn, int archivId, String link) {
        try {
            Document doc = Jsoup.connect(link).get();
            Elements items = doc.select("#archive-nav li.item a");

            List<Kirchenkreis> kreise = new ArrayList<>();
            List<Ort> orte = new ArrayList<>();

            for (Element a : items) {
                String name = a.text().trim();
                String href = a.absUrl("href").trim();

                if (name.toLowerCase().contains("kirchenkreis")
                        || name.toLowerCase().contains("dekanat")
                        || name.toLowerCase().contains("juden")
                        || name.toLowerCase().contains("mennoiten")
                        || name.toLowerCase().contains("militärseelsorge")
                        || name.toLowerCase().contains("reformierte kirche")
                        || name.toLowerCase().contains("auslandsgemeinde")
                        || name.toLowerCase().contains("thüringen")
                        || name.toLowerCase().contains("israeliten")
                        || name.toLowerCase().contains("krankenhausseelsorge")
                        || name.toLowerCase().contains("kreis")
                        || name.toLowerCase().contains("reformierter kirchenkreis")
                        || name.toLowerCase().contains("sonderbestände")
                        || name.toLowerCase().contains("allgemeine hilfsmittel")
                        || name.toLowerCase().contains("allgemeines ortschaftsverzeichnis")
                        || name.toLowerCase().contains("kirchenbezirk")
                        || name.toLowerCase().contains("hinterpommern")
                        || name.toLowerCase().contains("militärkirchenbücher")
                ){
                    kreise.add(new Kirchenkreis(archivId, name, href));
                } else {
                    orte.add(new Ort(null, archivId, name, href));
                }
            }

            saveKreise(kreise, conn);
            saveOrteDirekt(orte, conn);
            System.out.println("→ " + kreise.size() + " Kirchenkreise und " + orte.size() + " direkte Orte gespeichert.");

        } catch (Exception e) {
            System.err.println("⚠️ Fehler bei Archiv-Link " + link + ": " + e.getMessage());
        }
    }

    private static void saveKreise(List<Kirchenkreis> list, Connection conn) throws SQLException {
        String sql = """
            INSERT INTO kreis (archiv_id, name, link)
            VALUES (?, ?, ?)
            ON CONFLICT(archiv_id, name)
            DO UPDATE SET link = excluded.link;
            """;

        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            for (Kirchenkreis k : list) {
                stmt.setInt(1, k.archivId());
                stmt.setString(2, k.name());
                stmt.setString(3, k.link());
                stmt.addBatch();
            }
            stmt.executeBatch();
        }
    }

    private static void saveOrteDirekt(List<Ort> list, Connection conn) throws SQLException {
        String sql = """
            INSERT INTO ort (kreis_id, archiv_id, name, link)
            VALUES (NULL, ?, ?, ?)
            ON CONFLICT(archiv_id, name)
            DO UPDATE SET link = excluded.link;
            """;

        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            for (Ort o : list) {
                stmt.setInt(1, o.archivId());
                stmt.setString(2, o.name());
                stmt.setString(3, o.link());
                stmt.addBatch();
            }
            stmt.executeBatch();
        }
    }

    public record Kirchenkreis(int archivId, String name, String link) {}
    public record Ort(Integer kreisId, Integer archivId, String name, String link) {}
}
