#!/usr/bin/env python3
"""
dev_weekly.py – Wochenbericht: Gesamtstunden der aktuellen Woche + letzte DEVLOG-Einträge.
Aufruf: python3 dev_weekly.py
"""

import json
import os
import re
from datetime import datetime, timezone, timedelta

BASE_DIR  = os.path.dirname(os.path.abspath(__file__))
DATA_FILE = os.path.expanduser("~/.claude/timetrack.json")
DEVLOG    = os.path.join(BASE_DIR, "DEVLOG.md")

# ANSI colors
RESET   = "\033[0m"
BOLD    = "\033[1m"
DIM     = "\033[2m"
RED     = "\033[91m"
GREEN   = "\033[92m"
YELLOW  = "\033[93m"
BLUE    = "\033[94m"
MAGENTA = "\033[95m"
CYAN    = "\033[96m"
WHITE   = "\033[97m"


def c(*codes: str) -> str:
    """Return ANSI prefix string."""
    return "".join(codes)


def colorize(text: str, *codes: str) -> str:
    return "".join(codes) + text + RESET


def parse_iso(s: str) -> datetime:
    if s.endswith("Z"):
        s = s[:-1] + "+00:00"
    return datetime.fromisoformat(s)


def format_duration(seconds: float) -> str:
    seconds = int(seconds)
    h = seconds // 3600
    m = (seconds % 3600) // 60
    if h > 0:
        return f"{h}h {m:02d}m"
    return f"{m}m"


def current_week_range() -> tuple[datetime, datetime]:
    """Return (monday_00:00 local, sunday_23:59 local) for the current ISO week."""
    now = datetime.now(timezone.utc).astimezone()
    monday = (now - timedelta(days=now.weekday())).replace(
        hour=0, minute=0, second=0, microsecond=0
    )
    sunday_end = monday + timedelta(days=7)
    return monday, sunday_end


def weekly_stats(data: dict) -> tuple[float, int, dict[str, float]]:
    """Return (total_seconds, session_count, {date: seconds}) for this week."""
    week_start, week_end = current_week_range()
    total = 0.0
    count = 0
    per_day: dict[str, float] = {}

    for s in data.get("sessions", []):
        start_dt = parse_iso(s["start"])
        loc = start_dt.astimezone()
        if not (week_start <= loc < week_end):
            continue
        if s.get("end") is not None:
            end_dt = parse_iso(s["end"])
            elapsed = (end_dt - start_dt).total_seconds()
        else:
            elapsed = (datetime.now(timezone.utc) - start_dt).total_seconds()
        day_key = loc.strftime("%Y-%m-%d")
        per_day[day_key] = per_day.get(day_key, 0.0) + elapsed
        total += elapsed
        count += 1

    return total, count, per_day


def get_last_devlog_entries(n: int = 5) -> list[str]:
    """
    Parse DEVLOG.md and return the last n section blocks
    (everything between ## headings).
    """
    if not os.path.exists(DEVLOG):
        return []

    with open(DEVLOG, "r", encoding="utf-8") as f:
        content = f.read()

    # Split on ## headings (session entries)
    parts = re.split(r"(?=^## )", content, flags=re.MULTILINE)
    # Filter out non-entry parts (header, blanks)
    entries = [p.strip() for p in parts if p.strip().startswith("## ")]
    return entries[-n:]


def print_separator(char: str = "─", width: int = 60) -> None:
    print(colorize(char * width, DIM))


def print_weekly_report() -> None:
    if not os.path.exists(DATA_FILE):
        print(colorize("Keine Timetrack-Daten gefunden.", DIM))
        return

    with open(DATA_FILE, "r", encoding="utf-8") as f:
        data = json.load(f)

    total_sec, count, per_day = weekly_stats(data)
    week_start, _ = current_week_range()
    week_num = week_start.isocalendar()[1]
    week_label = (
        f"KW {week_num}  "
        f"({week_start.strftime('%d.%m.')} – "
        f"{(week_start + timedelta(days=6)).strftime('%d.%m.%Y')})"
    )

    print()
    print(colorize(f"  TimeMaster – Wochenbericht {week_label}", BOLD, BLUE))
    print_separator()

    if not per_day:
        print(colorize("  Keine Sessions diese Woche.", DIM))
    else:
        # Day-by-day breakdown
        DAYS_DE = {
            0: "Mo", 1: "Di", 2: "Mi", 3: "Do", 4: "Fr", 5: "Sa", 6: "So"
        }
        for day_str in sorted(per_day):
            dt = datetime.fromisoformat(day_str)
            day_name = DAYS_DE.get(dt.weekday(), "??")
            dur = format_duration(per_day[day_str])
            print(
                f"  {colorize(day_name, WHITE, BOLD)}  "
                f"{colorize(day_str, DIM)}  "
                f"{colorize(dur, YELLOW)}"
            )

        print_separator()
        print(
            f"  {'Gesamt':.<20} "
            + colorize(format_duration(total_sec), CYAN, BOLD)
            + colorize(f"  ({count} Sessions)", DIM)
        )

    print()
    print_separator("═")
    print(colorize("  Letzte Einträge im Dev Log", BOLD, MAGENTA))
    print_separator("═")

    entries = get_last_devlog_entries(5)
    if not entries:
        print(colorize("  Keine Einträge in DEVLOG.md.", DIM))
    else:
        for entry in entries:
            lines = entry.splitlines()
            if not lines:
                continue
            # Header line (## date time – time (dur))
            header = lines[0]
            print()
            print(colorize(f"  {header}", BOLD, GREEN))
            # Print remaining lines, indented, max 8 lines to keep it compact
            body_lines = [l for l in lines[1:] if l.strip()][:8]
            for bl in body_lines:
                # Dim section headers, normal for bullets
                if bl.startswith("###"):
                    print(colorize(f"    {bl}", DIM))
                elif bl.startswith("-"):
                    print(f"    {colorize(bl, WHITE)}")
                elif bl.startswith("**"):
                    print(f"    {colorize(bl, CYAN)}")
                else:
                    print(f"    {colorize(bl, DIM)}")

    print()
    print_separator()
    print()


if __name__ == "__main__":
    try:
        print_weekly_report()
    except Exception as e:
        print(f"Fehler: {e}")
