#!/usr/bin/env python3
"""Sync Hermes kanban board state to Gitea issue labels."""
import json
import os
import subprocess
import urllib.request

GITEA_API = os.getenv("GITEA_API", "http://127.0.0.1:3000/api/v1")
GITEA_TOKEN = os.getenv("GITEA_TOKEN", "")
REPO = os.getenv("GITEA_REPO", "stackchain/stackchain-hackathon")

LABEL_MAP = {
    "todo": "P1",
    "ready": "ready",
    "in_progress": "in_progress",
    "review": "review",
    "done": "done",
    "blocked": "blocked",
    "triage": "triage",
}


def _gitea(path, body=None, method="GET"):
    url = f"{GITEA_API}/{path}"
    data = json.dumps(body).encode() if body else None
    req = urllib.request.Request(url, data=data, method=method)
    req.add_header("Accept", "application/json")
    req.add_header("Authorization", f"token {GITEA_TOKEN}")
    if data:
        req.add_header("Content-Type", "application/json")
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read().decode())


def list_issues():
    return _gitea(f"repos/{REPO}/issues?state=all&limit=100")


def list_labels():
    return _gitea(f"repos/{REPO}/labels")


def find_label(name, labels):
    matches = [l for l in labels if l["name"] == name]
    return matches[0]["id"] if matches else None


def create_label(name):
    colors = {
        "P1": "00ccff",
        "P2": "cccccc",
        "ready": "0e8a16",
        "in_progress": "fbca04",
        "review": "d93f0b",
        "done": "00cc00",
        "blocked": "ff4444",
        "triage": "cccccc",
    }
    return _gitea(
        f"repos/{REPO}/labels",
        body={"name": name, "color": colors.get(name, "cccccc")},
        method="POST",
    )


def edit_issue(number, labels=None):
    if labels is None:
        return
    _gitea(
        f"repos/{REPO}/issues/{number}",
        body={"labels": labels},
        method="PATCH",
    )


def main():
    kanban_json = subprocess.check_output(
        ["hermes", "kanban", "list", "--json"], text=True
    )
    tasks = json.loads(kanban_json)
    labels = list_labels()
    label_ids = {l["name"]: l["id"] for l in labels}
    issues = {i["title"].split(" ", 1)[1].strip(): i for i in list_issues() if i.get("pull_request") is None}

    for t in tasks:
        title = t.get("title", "")
        issue_key = title.split(" ", 1)[1].strip() if title.startswith("#") else title
        prefix = LABEL_MAP.get(t.get("status", ""))
        if not prefix:
            continue
        gitea_label = label_ids.get(prefix)
        if gitea_label is None:
            create_label(prefix)
            label_ids[prefix] = find_label(prefix, list_labels()) or len(label_ids) + 1
        if issue_key in issues:
            issue = issues[issue_key]
            current = [l["id"] for l in issue.get("labels", [])]
            if gitea_label and gitea_label not in current:
                current.append(gitea_label)
            edit_issue(issue["number"], labels=list(set(current)))


if __name__ == "__main__":
    main()
