#!/usr/bin/env python3
"""Serveur Mes Tâches (VPS) — sert les fichiers + API modification TASKS.md."""

import json
import os
import re
from http.server import HTTPServer, SimpleHTTPRequestHandler
from socketserver import ThreadingMixIn

SERVE_DIR = "/root/tasks"
TASKS_FILE = os.path.join(SERVE_DIR, "TASKS.md")
PORT = 8888

SECTIONS = ["Active", "Waiting On", "Someday", "Done"]


class TaskHandler(SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=SERVE_DIR, **kwargs)

    def do_OPTIONS(self):
        self.send_response(200)
        self._cors()
        self.end_headers()

    def do_POST(self):
        if not self.path.startswith("/api/task"):
            self.send_response(404)
            self.end_headers()
            return
        try:
            length = int(self.headers.get("Content-Length", 0))
            body = json.loads(self.rfile.read(length))
            action = body.get("action", "")
            title = body.get("title", "").strip()
            to_section = body.get("toSection", "").strip()

            if action == "done":
                ok, msg = move_task(title, "Done")
            elif action == "delete":
                ok, msg = delete_task(title)
            elif action == "move":
                ok, msg = move_task(title, to_section)
            elif action == "add":
                due = body.get("due", "").strip()
                notes = body.get("notes", "").strip()
                ok, msg = add_task(title, to_section or "Active", due, notes)
            else:
                ok, msg = False, f"Action inconnue : {action}"

            status = 200 if ok else 400
        except Exception as e:
            ok, msg, status = False, str(e), 500

        self.send_response(status)
        self._cors()
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.end_headers()
        self.wfile.write(json.dumps({"ok": ok, "msg": msg}).encode("utf-8"))

    def _cors(self):
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type")

    def log_message(self, fmt, *args):
        pass  # Logs gérés par systemd (journalctl)


def read_lines():
    with open(TASKS_FILE, encoding="utf-8") as f:
        return f.readlines()


def write_lines(lines):
    with open(TASKS_FILE, "w", encoding="utf-8", newline="\n") as f:
        f.writelines(lines)


def find_task(lines, title):
    pattern = re.compile(r"^- \[[ x]\] \*\*" + re.escape(title) + r"\*\*")
    for i, line in enumerate(lines):
        if pattern.match(line):
            return i
    return -1


def get_block_end(lines, idx):
    j = idx + 1
    while j < len(lines) and lines[j].startswith("   "):
        j += 1
    return j


def move_task(title, to_section):
    if to_section not in SECTIONS:
        return False, f"Section invalide : {to_section}"

    lines = read_lines()
    idx = find_task(lines, title)
    if idx < 0:
        return False, f"Tâche introuvable : {title}"

    end = get_block_end(lines, idx)
    block = lines[idx:end]

    if to_section == "Done":
        block[0] = block[0].replace("- [ ]", "- [x]", 1)
    else:
        block[0] = block[0].replace("- [x]", "- [ ]", 1)

    del lines[idx:end]

    header = f"## {to_section}"
    target_idx = next((i for i, l in enumerate(lines) if l.strip() == header), -1)
    if target_idx < 0:
        return False, f"Section introuvable : {header}"

    insert_at = target_idx + 1
    if insert_at < len(lines) and lines[insert_at].strip() == "":
        insert_at += 1

    for k, bl in enumerate(block):
        lines.insert(insert_at + k, bl)

    write_lines(lines)
    return True, f"Tâche déplacée vers {to_section}"


def add_task(title, section, due="", notes=""):
    if not title:
        return False, "Titre vide"
    if section not in SECTIONS:
        section = "Active"

    lines = read_lines()

    due_part = f" — due {due}" if due else ""
    task_line = f"- [ ] **{title}**{due_part}\n"
    if notes:
        task_line += f"   {notes}\n"

    header = f"## {section}"
    target_idx = next((i for i, l in enumerate(lines) if l.strip() == header), -1)
    if target_idx < 0:
        return False, f"Section introuvable : {header}"

    insert_at = target_idx + 1
    if insert_at < len(lines) and lines[insert_at].strip() == "":
        insert_at += 1

    lines.insert(insert_at, task_line)
    write_lines(lines)
    return True, f"Tâche ajoutée dans {section}"


def delete_task(title):
    lines = read_lines()
    idx = find_task(lines, title)
    if idx < 0:
        return False, f"Tâche introuvable : {title}"

    end = get_block_end(lines, idx)
    del lines[idx:end]
    write_lines(lines)
    return True, "Tâche supprimée"


class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    daemon_threads = True


if __name__ == "__main__":
    os.chdir(SERVE_DIR)
    print(f"Task-server démarré sur port {PORT}")
    ThreadedHTTPServer(("", PORT), TaskHandler).serve_forever()
