"""
Build context payload for POST and render/write .dryft/context.md from GET response.
PRD §7.1: template with Last synced, Project, Last Activity, Guidelines, severity; §7.4: ~200 line cap.
"""

from datetime import datetime, timezone
from pathlib import Path
from typing import Any

CONTEXT_LINE_CAP = 200  # PRD §7.4, §17.4

GUIDELINES_BLOCK = """
## Guidelines for AI Agent

### Before Starting Any Task
- Read this entire file.
- Check if any files you plan to modify are listed under "Currently Active Changes" or "Files They Plan to Modify Next."
- If overlap exists, inform your developer immediately before proceeding.

### If You Share a File With the Other Agent
- Read "What they changed" to understand exactly which functions/sections they are modifying.
- Work in DIFFERENT functions or sections of the same file where possible.
- If you must modify the SAME function they are working on, STOP and inform your developer — this is a high-conflict risk.
- Do not change function signatures, interfaces, or exports that the other agent's code depends on.

### During Work
- If this file updates with a new warning, pause and inform your developer.
- If the other developer completes changes to files you depend on, suggest pulling latest.
- Keep your .dryft/intent.md updated after every file modification so the other agent can see your progress.
""".strip()


def _time_ago(iso: str) -> str:
    try:
        then = datetime.fromisoformat(iso.replace("Z", "+00:00")).timestamp()
        sec = int(datetime.now(timezone.utc).timestamp() - then)
        if sec < 60:
            return "just now"
        if sec < 3600:
            return f"{sec // 60} min ago"
        if sec < 86400:
            return f"{sec // 3600} h ago"
        return f"{sec // 86400} d ago"
    except (ValueError, TypeError):
        return ""


def build_payload(
    developer: str,
    git_changes: list[dict],
    intent: dict | None,
    project_id: str | None = None,
) -> dict:
    active_changes = [
        {
            "file": c["file"],
            "functions_modified": c.get("functionsModified", []),
            "change_type": c.get("changeType", "modification"),
        }
        for c in git_changes
    ]
    payload: dict[str, Any] = {
        "developer": developer,
        "timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
        "active_changes": active_changes,
    }
    if intent and intent.get("dependencies"):
        payload["dependencies_affected"] = intent["dependencies"]
    if intent:
        payload["intent"] = {}
        if intent.get("plannedFiles"):
            payload["intent"]["planned_files"] = intent["plannedFiles"]
        if intent.get("currentTask"):
            payload["intent"]["current_task"] = intent["currentTask"]
        if intent.get("dependencies"):
            payload["intent"]["dependencies"] = intent["dependencies"]
    if project_id:
        payload["project_id"] = project_id
    return payload


def render_context_md(server_state: dict, my_developer_id: str) -> str:
    developers = server_state.get("developers") or {}
    warnings = server_state.get("warnings") or []
    now = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
    project_id = server_state.get("project_id") or ""

    lines = [
        "# Dryft — Shared Development Context",
        "",
        f"> Last synced: {now}",
    ]
    if project_id:
        lines.append(f"> Project: {project_id}")
    lines.append("")

    others = [(k, v) for k, v in developers.items() if k != my_developer_id]
    if not others:
        lines.append("> No other developers in context yet.")
    else:
        for dev_id, dev in others:
            lines.append(f"## Other Developer Activity ({dev_id})")
            lines.append("")
            if dev.get("last_update"):
                ago = _time_ago(dev["last_update"])
                if ago:
                    lines.append("### Last Activity")
                    lines.append("")
                    lines.append(f"{dev_id} last active — {ago}")
                    lines.append("")
            planned = dev.get("intent") or {}
            if planned.get("current_task"):
                lines.append("### Current Task")
                lines.append("")
                lines.append(str(planned["current_task"]))
                lines.append("")
            changes = dev.get("active_changes") or []
            if changes:
                lines.append("### Currently Active Changes")
                lines.append("")
                for c in changes:
                    funcs = c.get("functions_modified") or []
                    func_str = f" — {', '.join(funcs)}" if funcs else ""
                    lines.append(f"- **{c.get('file', '?')}** — {c.get('change_type', 'change')}{func_str}")
                    if c.get("summary"):
                        lines.append(f"  - Why: {c['summary']}")
                lines.append("")
            planned_files = planned.get("planned_files") or []
            if planned_files:
                lines.append("### Files They Plan to Modify Next")
                lines.append("")
                for f in planned_files:
                    lines.append(f"- {f}")
                lines.append("")
            deps = dev.get("dependencies_affected") or []
            if deps:
                lines.append("### Dependencies Affected")
                lines.append("")
                for d in deps:
                    lines.append(f"- {d}")
                lines.append("")
    if warnings:
        lines.append("---")
        lines.append("")
        lines.append("## Warnings")
        lines.append("")
        for w in warnings:
            severity = "WARNING" if w.get("type") == "overlap" else "INFO"
            detail = w.get("detail") or ", ".join(w.get("developers") or [])
            lines.append(f"- **{severity}** — {w.get('file', '?')}: {detail}")
        lines.append("")
    last_push = server_state.get("last_push")
    if last_push and last_push.get("at"):
        lines.append("---")
        lines.append("")
        dev = last_push.get("developer")
        lines.append(f"**Last push:** {last_push['at']}" + (f" by {dev}" if dev else ""))
        lines.append("")
    lines.append("---")
    lines.append("")
    lines.append(GUIDELINES_BLOCK)

    out = "\n".join(lines)
    line_list = out.split("\n")
    if len(line_list) > CONTEXT_LINE_CAP:
        kept = line_list[: CONTEXT_LINE_CAP - 2]
        kept.append("")
        kept.append("... (context truncated to 200 lines)")
        return "\n".join(kept)
    return out


def write_context_file(cwd: str, content: str) -> None:
    path = Path(cwd) / ".dryft" / "context.md"
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(content, encoding="utf-8")
