#!/usr/bin/env python3
from pathlib import Path
import sys

root = Path(__file__).resolve().parents[2]
errors = []

required_files = [
    root / 'index.html',
    root / 'index-en.html',
    root / 'shared/archive-core/archive-app.js',
    root / 'shared/archive-core/archive-styles.css',
    root / 'shared/map/cdv-map.js',
    root / 'shared/map/map.css',
]
for p in required_files:
    if not p.exists():
        errors.append(f'FEHLT: {p.relative_to(root)}')


# Workflow-Anweisungen muessen Teil des Projekts sein und online hochladbar bleiben.
workflow_required = [
    root / 'workflow/index.html',
    root / 'workflow/MASTER-INSTRUCTIONS.md',
    root / 'workflow/PROJECT-INSTRUCTIONS.md',
    root / 'workflow/ai-instructions.json',
    root / 'workflow/IMPORT-PROMPT-TEMPLATE.md',
]
for p in workflow_required:
    if not p.exists():
        errors.append(f'FEHLT WORKFLOW-DATEI: {p.relative_to(root)}')

# Root-Seiten sollen den Workflow diskret verlinken, damit er online auffindbar ist.
for name in ['index.html', 'index-en.html']:
    p = root / name
    if p.exists():
        s = p.read_text(errors='ignore')
        if 'workflow/index.html' not in s and '/workflow/' not in s:
            errors.append(f'FEHLT WORKFLOW-LINK: {name}')

# Workflow-Regeln: MASTER-INSTRUCTIONS.md ist die einzige verbindliche Quelle.
master = root / 'workflow/MASTER-INSTRUCTIONS.md'
if master.exists():
    mt = master.read_text(encoding='utf-8', errors='ignore')
    for marker in [
        'einzige verbindliche Arbeitsanweisung',
        'TEMP-store',
        'Vorderseite',
        'Rückseite',
        'captionEn',
        'Open original',
        'action.php?download=',
        'kein Speichern-Dialog',
        'Zählcheck',
        'vsN-historicbits-clean.zip'
    ]:
        if marker not in mt:
            errors.append(f'MASTER-ANWEISUNG UNVOLLSTAENDIG: MASTER-INSTRUCTIONS.md ohne {marker!r}')

# Andere Workflow-Dateien duerfen nur auf die Master-Anweisung verweisen und keine konkurrierenden Langregeln bilden.
for rel in ['workflow/PROJECT-INSTRUCTIONS.md', 'workflow/IMPORT-PROMPT-TEMPLATE.md']:
    q = root / rel
    if q.exists():
        qt = q.read_text(encoding='utf-8', errors='ignore')
        if 'MASTER-INSTRUCTIONS.md' not in qt:
            errors.append(f'WORKFLOW-DATEI VERWEIST NICHT AUF MASTER: {rel}')

ai_json = root / 'workflow/ai-instructions.json'
if ai_json.exists():
    t = ai_json.read_text(encoding='utf-8', errors='ignore')
    for marker in ['MASTER-INSTRUCTIONS.md', 'captionEn', 'reverse_logic', 'theme_folder_forbidden_files', 'vsN-historicbits-clean.zip', 'open_original_rule']:
        if marker not in t:
            errors.append(f'WORKFLOW-REGEL UNVOLLSTAENDIG: ai-instructions.json ohne {marker}')


# Keine versehentlichen XML-Index-Dateien als Ersatz für HTML.
for p in root.rglob('index.xml'):
    errors.append(f'NICHT ERLAUBT: {p.relative_to(root)} — Themenordner brauchen index.html')

# Root-Startseite darf nicht auf reine Ordner-URLs zeigen, weil file:// lokal dann Directory Listing anzeigen kann.
for name in ['index.html', 'index-en.html']:
    p = root / name
    if p.exists():
        s = p.read_text(errors='ignore')
        if 'href="archive/"' in s or "href='archive/'" in s:
            errors.append(f'RISKANTER ORDNER-LINK: {name} benutzt archive/ statt archive/index.html')
        if 'archive/?year=' in s:
            errors.append(f'RISKANTER TIMELINE-LINK: {name} benutzt archive/?year= statt archive/index.html?year=')

for name in ['app.js', 'app-en.js']:
    p = root / name
    if p.exists():
        s = p.read_text(errors='ignore')
        if 'archive/?year=' in s:
            errors.append(f'RISKANTER TIMELINE-LINK: {name} benutzt archive/?year= statt archive/index.html?year=')
        if 'LIVE_DATA_PAGE = "archive/"' in s:
            errors.append(f'RISKANTER LIVE_DATA_PAGE: {name} benutzt archive/ statt archive/index.html')

skip_dirs = {'assets', 'shared', 'workflow', '__MACOSX'}
for d in root.iterdir():
    if not d.is_dir() or d.name.startswith('.') or d.name in skip_dirs:
        continue
    # Themen-/App-Ordner brauchen index.html, wenn sie Daten oder Karten enthalten.
    looks_like_topic = any((d / x).exists() for x in ['cdv-data-en.js', 'theme-config.js', 'cdv-map-en.html']) or d.name.startswith('_template')
    if looks_like_topic and not (d / 'index.html').exists():
        errors.append(f'FEHLT: {d.name}/index.html')
        continue
    if (d / 'index.html').exists() and looks_like_topic:
        if (d / 'cdv-app.js').exists(): errors.append(f'NICHT ERLAUBT: {d.name}/cdv-app.js')
        if (d / 'styles.css').exists(): errors.append(f'NICHT ERLAUBT: {d.name}/styles.css')
        s = (d / 'index.html').read_text(errors='ignore')
        if 'shared/archive-core/archive-app.js' not in s:
            errors.append(f'FEHLT SHARED-APP-LINK: {d.name}/index.html')
        if 'shared/archive-core/archive-styles.css' not in s:
            errors.append(f'FEHLT SHARED-CSS-LINK: {d.name}/index.html')


# Open original must open a high-res browser view when possible, but never trigger direct downloads.
app_file = root / 'shared/archive-core/archive-app.js'
if app_file.exists():
    app_text = app_file.read_text(encoding='utf-8', errors='ignore')
    if 'function originalOpenUrl(item)' not in app_text:
        errors.append('OPEN-ORIGINAL-REGEL FEHLT: archive-app.js ohne originalOpenUrl(item)')
    if 'function browserOpenImageUrl(url' not in app_text:
        errors.append('OPEN-ORIGINAL-REGEL FEHLT: archive-app.js ohne browserOpenImageUrl(url)')
    if 'download parameter' not in app_text and 'download flag' not in app_text:
        errors.append('OPEN-ORIGINAL-REGEL UNVOLLSTAENDIG: download-Parameter wird nicht sichtbar behandelt')
    if 'href="${esc(highResImageUrl(item.image, item.pageUrl))}"' in app_text:
        errors.append('OPEN-ORIGINAL FEHLER: sichtbarer Link benutzt highResImageUrl(item.image, item.pageUrl)')
    if 'href="${esc(highResImageUrl(item.reverse.image, item.reverse.pageUrl))}"' in app_text:
        errors.append('OPEN-ORIGINAL FEHLER: Rueckseiten-Link benutzt highResImageUrl(reverse.image, reverse.pageUrl)')

master_instructions = root / 'workflow/MASTER-INSTRUCTIONS.md'
if master_instructions.exists():
    instr = master_instructions.read_text(encoding='utf-8', errors='ignore')
    for marker in ['Open original', 'High-Res', 'action.php?download=', 'kein Speichern-Dialog']:
        if marker not in instr:
            errors.append(f'MASTER-REGEL UNVOLLSTAENDIG: MASTER-INSTRUCTIONS.md ohne Open-original-Marker {marker!r}')


# Datenprüfung für Bückeburger Import: englische Detailansicht darf keine gemischten deutschen captionEn-Texte enthalten.
import json, re

def _load_timeline_items(path):
    text = path.read_text(encoding='utf-8', errors='ignore')
    m = re.search(r'window\.timelineItems\s*=\s*(\[.*\]);?\s*$', text, re.S)
    if not m:
        return []
    return json.loads(m.group(1))

german_caption_markers = [
    ' tätig ', ' aufgenommen ', ' um 1880', ' war ', ' Seine ', ' handkolorierten ',
    'typischer Flügelhaube', 'Fürstenhauses', 'Alltags- und Festkultur', 'um die Jahrhundertwende'
]
for rel in ['bueckeburger-trachten/cdv-data-en.js', 'archive/cdv-data-en.js']:
    p = root / rel
    if p.exists():
        for item in _load_timeline_items(p):
            if item.get('collection') == 'Bückeburger Trachten' or '/category/48' in str(item.get('pageUrl', '')):
                caption_en = str(item.get('captionEn', ''))
                bad = [marker for marker in german_caption_markers if marker in caption_en]
                if bad:
                    errors.append(f'DE/EN-MIX IN captionEn: {rel} ID {item.get("id")} enthält {bad[0]!r}')



# vs16 hard check: new Piwigo imports must carry explicit high-res Open Original URLs.
import json as _json
def _load_items(_path):
    _txt = open(_path, encoding="utf-8").read()
    return _json.loads(_txt[_txt.find("["):_txt.rfind("]")+1])
for _rel in ["schnellfotos-kaufhaus/cdv-data-en.js", "sequenzen/cdv-data-en.js", "bueckeburger-trachten/cdv-data-en.js"]:
    _path = root / _rel
    if _path.exists():
        for _item in _load_items(_path):
            if str(_item.get("pageUrl", "")).startswith("https://reinhard-krause.de/sammlung/picture.php?"):
                _url = str(_item.get("openOriginalUrl") or _item.get("originalImage") or "")
                if "action.php?download=" not in _url or f"id={_item.get('id')}" not in _url:
                    errors.append(f"{_rel}: ID {_item.get('id')} has no explicit Piwigo high-res openOriginalUrl")
            _rev = _item.get("reverse")
            if isinstance(_rev, dict) and str(_rev.get("pageUrl", "")).startswith("https://reinhard-krause.de/sammlung/picture.php?"):
                _url = str(_rev.get("openOriginalUrl") or _rev.get("originalImage") or "")
                if "action.php?download=" not in _url or f"id={_rev.get('id')}" not in _url:
                    errors.append(f"{_rel}: reverse ID {_rev.get('id')} has no explicit Piwigo high-res openOriginalUrl")

if errors:
    print('STRUKTURCHECK FEHLGESCHLAGEN')
    print('\n'.join(errors))
    sys.exit(1)
print('STRUKTURCHECK OK')


# Additional static guard for vs20: Core must prioritize openOriginalUrl through browserOpenImageUrl.
from pathlib import Path as _Path
_core = root / 'shared/archive-core/archive-app.js'
if _core.exists():
    _txt = _core.read_text(encoding='utf-8')
    if 'browserOpenImageUrl(item.openOriginalUrl)' not in _txt:
        raise SystemExit('STRUCTURECHECK FAILED: Open original must prioritize browserOpenImageUrl(item.openOriginalUrl).')
_master = root / 'workflow/MASTER-INSTRUCTIONS.md'
if _master.exists():
    _m = _master.read_text(encoding='utf-8')
    if 'openOriginalUrl = verbindliches Ziel' not in _m or 'pageUrl allein ist' not in _m:
        raise SystemExit('STRUCTURECHECK FAILED: MASTER-INSTRUCTIONS missing strict High-Res openOriginalUrl rule.')


# vs27 additional standalone project safety check
from pathlib import Path as _Path
for _folder in []:
    _idx = _Path(_folder) / "index.html"
    if _idx.exists():
        _txt = _idx.read_text(encoding="utf-8")
        assert 'class="nav-link"' in _txt and 'cdv-map-en.html' in _txt, f"{_folder} must include map nav-link; archive-app expects .top-actions .nav-link"
        assert (_Path(_folder) / "cdv-data-en.js").exists(), f"{_folder} missing cdv-data-en.js"

# ENGLISH_FIELD_INTEGRITY_CHECK_REQUIRED: titleEn/captionEn must not contain German source fragments.
# Blocking examples: eines, einer, einem, mit, und, Datierung, Innenansicht, Maenner, Frauen, Kinder, Gebaeude, umlauts.
