"""
Naimportuje stažené PDF puzzle z DownloadedPuzzles/ do MySQL tabulky sudoku_killer.

Spuštění:
  python import_do_mysql.py          # přeskočí již existující (podle puzzle_number)
  python import_do_mysql.py --all    # reimportuje vše (přepíše existující)
"""

import re
import sys
import argparse
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent / "Knihovny"))
from mysql_db import connect_mysql

sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")

SAVE_DIR = Path(__file__).parent / "DownloadedPuzzles"

# 2009-01-01 Puzzle SudokuKiller 1 [difficulty 5 of 10] [average solving time 47 min].pdf
FILENAME_RE = re.compile(
    r"^(?P<date>\d{4}-\d{2}-\d{2}) Puzzle (?P<type>SudokuKillerGreaterThan|SudokuKiller) (?P<num>\d+) "
    r"\[difficulty (?P<diff>\d+) of (?P<maxdiff>\d+)\] "
    r"\[average solving time (?P<time>[^\]]+)\]"
    r"(?P<solution> \[solution\])?\.pdf$"
)

def parse_time_to_minutes(time_str):
    """Převede '47 min', '1h 7m', '17h 44m' na celkový počet minut."""
    time_str = time_str.strip()
    m = re.match(r"^(\d+)h\s+(\d+)m$", time_str)
    if m:
        return int(m.group(1)) * 60 + int(m.group(2))
    m = re.match(r"^(\d+)\s+min$", time_str)
    if m:
        return int(m.group(1))
    return None

def load_puzzle_types(cursor):
    cursor.execute("SELECT id, name FROM puzzle_type")
    return {row["name"]: row["id"] for row in cursor.fetchall()}

def load_existing_numbers(cursor):
    cursor.execute("SELECT puzzle_number FROM sudoku_killer")
    return {row["puzzle_number"] for row in cursor.fetchall()}

def parse_files():
    """Vrátí dict: puzzle_number -> {"puzzle": Path, "solution": Path|None, metadata...}"""
    puzzles = {}
    for f in SAVE_DIR.iterdir():
        m = FILENAME_RE.match(f.name)
        if not m:
            print(f"[SKIP] Nerozpoznaný název: {f.name}", file=sys.stderr)
            continue
        num = int(m.group("num"))
        if num not in puzzles:
            puzzles[num] = {
                "puzzle_number": num,
                "puzzle_date": m.group("date"),
                "puzzle_type": m.group("type"),
                "difficulty": int(m.group("diff")),
                "max_difficulty": int(m.group("maxdiff")),
                "avg_minutes": parse_time_to_minutes(m.group("time")),
                "file_puzzle": None,
                "file_solution": None,
            }
        if m.group("solution"):
            puzzles[num]["file_solution"] = f
        else:
            puzzles[num]["file_puzzle"] = f
    return puzzles

def import_puzzle(cursor, puzzle, type_ids):
    if puzzle["file_puzzle"] is None:
        print(f"[SKIP] puzzle_number={puzzle['puzzle_number']}: chybí PDF puzzlu")
        return False

    type_id = type_ids.get(puzzle["puzzle_type"])
    if type_id is None:
        print(f"[SKIP] Neznámý typ: {puzzle['puzzle_type']}")
        return False

    pdf_puzzle = puzzle["file_puzzle"].read_bytes()
    pdf_solution = puzzle["file_solution"].read_bytes() if puzzle["file_solution"] else None

    cursor.execute("""
        INSERT INTO sudoku_killer
            (puzzle_number, puzzle_type_id, puzzle_date, difficulty, max_difficulty,
             avg_solving_time_minutes, file_puzzle, file_solution)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
        ON DUPLICATE KEY UPDATE
            puzzle_type_id = VALUES(puzzle_type_id),
            puzzle_date = VALUES(puzzle_date),
            difficulty = VALUES(difficulty),
            max_difficulty = VALUES(max_difficulty),
            avg_solving_time_minutes = VALUES(avg_solving_time_minutes),
            file_puzzle = VALUES(file_puzzle),
            file_solution = VALUES(file_solution)
    """, (
        puzzle["puzzle_number"],
        type_id,
        puzzle["puzzle_date"],
        puzzle["difficulty"],
        puzzle["max_difficulty"],
        puzzle["avg_minutes"],
        pdf_puzzle,
        pdf_solution,
    ))
    return True

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--all", action="store_true", help="Reimportuje i existující záznamy")
    args = parser.parse_args()

    import pymysql.cursors
    conn = connect_mysql(database="puzzle", cursorclass=pymysql.cursors.DictCursor)
    cursor = conn.cursor()

    type_ids = load_puzzle_types(cursor)
    existing = load_existing_numbers(cursor) if not args.all else set()

    puzzles = parse_files()
    total = len(puzzles)
    print(f"Nalezeno {total} puzzle v adresáři.")

    imported = skipped = errors = 0
    for i, (num, puzzle) in enumerate(sorted(puzzles.items()), 1):
        if num in existing:
            skipped += 1
            continue
        try:
            if import_puzzle(cursor, puzzle, type_ids):
                imported += 1
            else:
                errors += 1
        except Exception as e:
            print(f"[CHYBA] puzzle_number={num}: {e}", file=sys.stderr)
            errors += 1

        if i % 500 == 0:
            print(f"  {i}/{total} zpracováno ({imported} importováno, {skipped} přeskočeno, {errors} chyb)")

    cursor.close()
    conn.close()
    print(f"\nHotovo: {imported} importováno, {skipped} přeskočeno, {errors} chyb.")

if __name__ == "__main__":
    main()
