from pathlib import Path
import json
from typing import Tuple, Dict, List
from flask import Flask, render_template, request

app = Flask(__name__)


def load_words() -> Tuple[List[str], Dict[str, List[str]]]:
    data_dir = Path(__file__).parent / "data"
    txt_path = data_dir / "words_de_5.txt"
    json_path = data_dir / "words_de_5_sources.json"

    words: List[str] = []
    sources_map: Dict[str, List[str]] = {}

    if txt_path.exists():
        with txt_path.open("r", encoding="utf-8") as f:
            for line in f:
                word = line.strip().lower()
                if len(word) == 5 and word.isalpha():
                    words.append(word)

    if json_path.exists():
        try:
            sources_map = json.loads(json_path.read_text(encoding="utf-8"))
        except Exception:
            sources_map = {}

    return words, sources_map


def filter_words(words: List[str], position_letters: List[str], includes_text: str, excludes_text: str) -> List[str]:
    results: List[str] = []
    includes_letters = [ch for ch in includes_text.lower() if ch.isalpha()]
    excludes_letters = [ch for ch in excludes_text.lower() if ch.isalpha()]
    for word in words:
        # feste Positionen
        if any(ch and word[idx] != ch for idx, ch in enumerate(position_letters)):
            continue
        # muss-enthalten
        if not all(ch in word for ch in includes_letters):
            continue
        # darf-nicht-enthalten
        if any(ch in word for ch in excludes_letters):
            continue
        results.append(word)
    return results


@app.route("/", methods=["GET", "POST"])
def index():
    all_words, sources_map = load_words()
    results: List[str] | None = None
    pos: List[str] = ["", "", "", "", ""]
    includes: str = ""
    excludes: str = ""
    if request.method == "POST":
        pos = [
            (request.form.get("pos1") or "").strip().lower(),
            (request.form.get("pos2") or "").strip().lower(),
            (request.form.get("pos3") or "").strip().lower(),
            (request.form.get("pos4") or "").strip().lower(),
            (request.form.get("pos5") or "").strip().lower(),
        ]
        includes = (request.form.get("includes") or "").strip()
        excludes = (request.form.get("excludes") or "").strip()
        results = filter_words(all_words, pos, includes, excludes)
    return render_template(
        "index.html",
        results=results,
        pos=pos,
        includes=includes,
        excludes=excludes,
        words_count=len(all_words),
        sources_map=sources_map,
    )


if __name__ == "__main__":
    app.run(debug=True)
