# -*- coding: utf-8 -*-
"""
Erzeugt eine HTML-Übersichtsseite über HTML-Tutorial-Dateien.

Funktionen / Eigenschaften:
- Gruppierung ausschließlich nach dem ersten Unterordner (Wurzelebene = Dateien direkt unter BASE_DIR).
- Kacheln mit Titel (ohne .html/.htm), Ordnerzeile und erneutem Dateinamen (ohne Endung).
- Einheitliche, kompakte Kacheln (minimierte Höhe; Clamping verhindert Sprünge).
- Titel-Farbe wie "Nach oben".
- Inline-SVG (Browserfenster mit Code-Klammern), keine externen Assets.
- Einfache Suche/Filter und Stückzahlen je Abschnitt.

Anpassungspunkte:
- GRID_CLASSES: Spaltenraster (breiter = weniger Spalten).
- TILE_MIN_H, TILE_PADDING, TITLE_TEXT_SIZE: Kachelhöhe/-abstände.
"""

import os
from urllib.parse import quote
from datetime import datetime
from collections import defaultdict
from html import escape

# -----------------------------------------------------------------------------
# Konfiguration
# -----------------------------------------------------------------------------
BASE_DIR = r"Y:\KUNDENDATEN\CIMPCS\Intern\Arbeitsunterlagen\Schulungsvideos"
BASE_URL = "https://video.prodat-sql.de"

OUTPUT_DIR = r"Y:\ProdatSQL\ProdatSRV_Develop\Help.Git\PRODAT\HTML"
OUTPUT_FILE = os.path.join(OUTPUT_DIR, "tutorials.html")

HTML_EXTENSIONS = (".html", ".htm")
EXCLUDE_DIRS = {".git", "__pycache__"}
EXCLUDE_DIRS_CI = {d.lower() for d in EXCLUDE_DIRS}
EXCLUDE_FILENAMES_CI = {
    "video.html",
    os.path.basename(OUTPUT_FILE).lower(),
}

# Darstellung (leicht anpassbar)
GRID_CLASSES = "grid gap-4 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-2"
TILE_MIN_H = "min-h-[120px]"        # z. B. "min-h-[100px]" oder komplett entfernen
TILE_PADDING = "p-3"                # p-4 -> höher, p-2.5 -> noch kompakter
TITLE_TEXT_SIZE = "text-lg"         # text-base -> größer, text-[13px] -> kleiner text-sm

# -----------------------------------------------------------------------------
# Hilfsfunktionen
# -----------------------------------------------------------------------------
def is_html_tutorial_file(filename: str) -> bool:
    name = filename.lower()
    if name in EXCLUDE_FILENAMES_CI:
        return False
    return name.endswith(HTML_EXTENSIONS)

def first_segment(rel_path: str) -> str:
    """Ersten Ordner aus einem relativen Pfad liefern."""
    if not rel_path or rel_path == ".":
        return ""
    return rel_path.split(os.sep, 1)[0]

def remove_ext(name: str) -> str:
    """Dateiendung (.html/.htm) entfernen."""
    base, ext = os.path.splitext((name or "").strip())
    # .htm/.html: os.path.splitext trennt korrekt
    return base

def svg_icon_code() -> str:
    """Inline-SVG: Browserfenster mit Code-Klammern, farblich via currentColor."""
    return (
        '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" '
        'viewBox="0 0 24 24" class="w-5 h-5 text-indigo-600 group-hover:text-indigo-700">'
        '<defs>'
        '<mask id="tutorial-code-mask">'
        '<rect width="24" height="24" fill="white"/>'
        '<circle cx="6" cy="6" r="1.2" fill="black"/>'
        '<circle cx="9" cy="6" r="1.2" fill="black"/>'
        '<circle cx="12" cy="6" r="1.2" fill="black"/>'
        '<path d="M10 10 L7.2 12 L10 14" stroke="black" stroke-width="2.2" '
        'stroke-linecap="round" stroke-linejoin="round"/>'
        '<path d="M14 10 L16.8 12 L14 14" stroke="black" stroke-width="2.2" '
        'stroke-linecap="round" stroke-linejoin="round"/>'
        '</mask>'
        '</defs>'
        '<rect x="3" y="3" width="18" height="18" rx="2.5" fill="currentColor" mask="url(#tutorial-code-mask)"/>'
        '<rect x="3" y="3" width="18" height="4" rx="2.5" fill="currentColor" mask="url(#tutorial-code-mask)"/>'
        '</svg>'
    )

# -----------------------------------------------------------------------------
# Hauptlogik
# -----------------------------------------------------------------------------
def generate_html():
    print("[INFO] Generiere HTML-Datei aus Ordnerstruktur...")

    groups = defaultdict(list)  # (title, id) -> [items]
    date_str = datetime.now().strftime("%d.%m.%Y")
    total_files = 0

    # Dateien einsammeln und NUR nach erstem Unterordner gruppieren
    for root, dirs, files in os.walk(BASE_DIR):
        dirs[:] = [d for d in dirs if d.lower() not in EXCLUDE_DIRS_CI]
        rel_path = os.path.relpath(root, BASE_DIR)

        if rel_path == ".":
            group_title = "Wurzelebene"
            group_id = "wurzel"
            folder_display = "/"
        else:
            first = first_segment(rel_path)
            group_title = first
            group_id = first.lower().replace(" ", "-")
            folder_display = "/" + rel_path.replace("\\", "/")

        for file in sorted(files):
            if not is_html_tutorial_file(file):
                continue

            rel_file_path = file if rel_path == "." else os.path.join(rel_path, file).replace("\\", "/")
            url = f"{BASE_URL}/{quote(rel_file_path)}"

            groups[(group_title, group_id)].append({
                "file": file,
                "url": url,
                "folder_display": folder_display,
                "rel_path": rel_path,
            })
            total_files += 1

    # Sortierung: Wurzelebene zuerst, dann alphabetisch
    def group_sort_key(key):
        title, _gid = key
        return ("" if title == "Wurzelebene" else title.lower())

    # Navigation erstellen
    nav_links = []
    for (section_title, section_id) in sorted(groups.keys(), key=group_sort_key):
        count = len(groups[(section_title, section_id)])
        nav_links.append(
            f"""
<li>
  <a href="#{escape(section_id)}" class="flex items-center justify-between rounded-lg border border-gray-200 px-3 py-2 hover:bg-gray-50">
    <span class="truncate">{escape(section_title)}</span>
    <span class="text-xs tabular-nums bg-gray-100 rounded px-2 py-0.5">{count}</span>
  </a>
</li>
""".rstrip()
        )

    # Abschnitte + Kacheln
    sections = []
    icon_html = svg_icon_code()

    for (section_title, section_id) in sorted(groups.keys(), key=group_sort_key):
        items = groups[(section_title, section_id)]
        file_items = []

        for it in items:
            file = it["file"]
            url = it["url"]
            folder_display = it["folder_display"]

            display_name = remove_ext(file)
            # HTML-escaping für sichere Ausgabe
            disp = escape(display_name)
            folder_disp = escape(folder_display)
            data_name = display_name.lower()

            file_items.append(
                f"""
<li data-name="{escape(data_name)}" class="h-full transition">
  <a href="{escape(url)}" class="group block h-full rounded-xl border border-gray-200 {TILE_PADDING} hover:shadow focus:outline-none focus:ring-2 focus:ring-indigo-500 flex flex-col {TILE_MIN_H}">
    <div class="flex items-center gap-1.5">
      {icon_html}
      <span class="font-medium {TITLE_TEXT_SIZE} text-indigo-600 group-hover:text-indigo-700 group-hover:underline clamp-1">{disp}</span>
    </div>
    <div class="text-xs text-gray-700 mt-0.5 clamp-1">{disp}</div>
	<div class="text-xs text-gray-500 mt-0.5 truncate">{folder_disp}</div>    
  </a>
</li>
""".rstrip()
            )

        section_html = f"""
<section id="{escape(section_id)}" data-section class="scroll-mt-24">
  <details open class="group">
    <summary class="flex items-center justify-between cursor-pointer list-none select-none rounded-xl bg-white border border-gray-200 px-4 py-3 shadow-sm hover:shadow">
      <div class="flex items-center gap-2">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-70 group-open:rotate-90 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M9 5l7 7-7 7"/></svg>
        <h2 class="font-semibold">{escape(section_title)}</h2>
      </div>
      <span class="js-count text-xs tabular-nums bg-gray-100 rounded px-2 py-0.5">{len(items)} Dateien</span>
    </summary>
    <div class="mt-3">
      <ul class="{GRID_CLASSES}">
        {''.join(file_items)}
      </ul>
      <div class="mt-3 text-right">
        <a href="#top" class="text-sm text-indigo-600 hover:underline">Nach oben ↑</a>
      </div>
    </div>
  </details>
</section>
""".rstrip()

        sections.append(section_html)

    # Gesamtes HTML-Dokument
    html_output = f"""<!DOCTYPE html>
<html lang="de" class="h-full">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Tutorials – Inhaltsverzeichnis</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- Fallback für Line-Clamping ohne Tailwind-Plugin -->
  <style>
    .clamp-1, .clamp-2 {{ display:-webkit-box; -webkit-box-orient:vertical; overflow:hidden; }}
    .clamp-1 {{ -webkit-line-clamp:1; }}
    .clamp-2 {{ -webkit-line-clamp:2; }}
  </style>
</head>
<body class="h-full bg-gray-50 text-gray-900">
  <a id="top"></a>

  <header class="sticky top-0 z-10 backdrop-blur border-b border-gray-200 bg-white/70">
    <div class="mx-auto max-w-7xl px-4 py-3 flex items-center justify-between gap-4">
      <div>
        <h1 class="text-lg sm:text-xl font-semibold">Tutorials – Inhaltsverzeichnis</h1>
        <p class="text-xs text-gray-600">Stand: {escape(datetime.now().strftime("%d.%m.%Y"))}</p>
      </div>
    </div>
  </header>

  <main class="mx-auto max-w-7xl px-4 py-6 grid gap-6 lg:grid-cols-[280px,1fr]">
    <aside class="order-2 lg:order-1">
      <div class="rounded-xl border border-gray-200 p-3 bg-white">
        <div class="flex items-center justify-between">
          <h2 class="font-semibold">Ordner</h2>
          <span class="text-xs tabular-nums bg-gray-100 rounded px-2 py-0.5" id="total-count">{total_files}</span>
        </div>
        <div class="mt-3">
          <label for="search" class="sr-only">Suche</label>
          <input id="search" type="search" placeholder="Suchen…" class="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500" />
        </div>
        <nav class="mt-3">
          <ul class="flex flex-col gap-2 max-h-[55vh] overflow-auto pr-1">
            {''.join(nav_links)}
          </ul>
        </nav>
      </div>
    </aside>

    <section class="order-1 lg:order-2 space-y-4">
      {''.join(sections)}
    </section>
  </main>

  <footer class="mx-auto max-w-7xl px-4 pb-10">
    <div class="rounded-xl border border-gray-200 p-4 text-sm text-gray-600 bg-white">
      Hinweis: Diese Übersicht wird bei Änderungen im Tutorial-Ordner aktualisiert.
    </div>
  </footer>

  <script>
    const searchInput = document.getElementById('search');
    const totalCountEl = document.getElementById('total-count');

    function applyFilter() {{
      const q = (searchInput.value || '').toLowerCase().trim();
      let totalVisible = 0;

      document.querySelectorAll('section[data-section]').forEach(sec => {{
        let visibleInSection = 0;
        sec.querySelectorAll('li[data-name]').forEach(li => {{
          const name = (li.getAttribute('data-name') || '').toLowerCase();
          const show = !q || name.includes(q);
          li.classList.toggle('hidden', !show);
          if (show) visibleInSection += 1;
        }});
        const countEl = sec.querySelector('.js-count');
        if (countEl) countEl.textContent = (visibleInSection + ' Dateien');
        sec.classList.toggle('hidden', q && visibleInSection === 0);
        totalVisible += visibleInSection;
      }});

      totalCountEl.textContent = totalVisible;
    }}

    searchInput.addEventListener('input', applyFilter);
  </script>
</body>
</html>
"""

    if not os.path.isdir(OUTPUT_DIR):
        raise FileNotFoundError(f"Ausgabeverzeichnis existiert nicht: {OUTPUT_DIR}")

    with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
        f.write(html_output)

    print(f"[OK] Datei erzeugt: {OUTPUT_FILE}")

# -----------------------------------------------------------------------------
if __name__ == "__main__":
    try:
        generate_html()
    except Exception as e:
        print("[FEHLER] Fehler beim Generieren der HTML-Datei.")
        try:
            # ggf. mehr Details ausgeben
            import traceback
            traceback.print_exc()
        except Exception:
            pass
