"""Contributor workflow for Nbench.

Prints everything a Claude Code session needs to optimise a project:
- Project description and current metric
- Experiment history (what's been tried, what worked)
- The actual training code
- Clear instructions for what to do
"""
from __future__ import annotations

import os
import subprocess

from .client import NbenchClient
from .config import load_config


def _sync_repo(repo_path="."):
    """Pull latest main and rebase current branch on it."""
    subprocess.run(["git", "fetch", "origin"], cwd=repo_path, capture_output=True)
    result = subprocess.run(["git", "branch", "--show-current"],
                          cwd=repo_path, capture_output=True, text=True)
    branch = result.stdout.strip()
    if branch == "main" or branch == "master":
        subprocess.run(["git", "pull", "origin", branch], cwd=repo_path, capture_output=True)
        print(f"[sync] Updated {branch} to latest")
    else:
        subprocess.run(["git", "rebase", "origin/main"], cwd=repo_path, capture_output=True)
        print(f"[sync] Rebased {branch} on latest main")


def _parse_last_metric(results_file):
    """Parse the last metric value from results.tsv."""
    if not os.path.exists(results_file):
        return None
    with open(results_file) as f:
        lines = [l.strip() for l in f.readlines() if l.strip()]
    if not lines:
        return None
    parts = lines[-1].split("\t")
    if len(parts) >= 2:
        try:
            return float(parts[1])
        except ValueError:
            pass
    return None


def run_contribute(api_url, api_key, project_slug, repo_path=".", sync=False, auto_submit=False):
    """Print everything Claude Code needs to optimise this project."""
    client = NbenchClient(api_url=api_url, api_key=api_key)
    config = load_config(repo_path)

    if sync:
        _sync_repo(repo_path)

    project = client.get_project(project_slug)
    experiments = client.get_experiments(project_slug, limit=20)
    branches = client.get_branches(project_slug)

    # Get contributor's handle
    handle = "contributor"
    try:
        account = client.get_account()
        handle = account.get("handle", "contributor")
    except Exception:
        pass

    direction = project.get("direction", config.get("direction", "minimize"))
    train_cmd = config.get("train", "python train.py")
    results_file = config.get("results", "results.tsv")
    current_best = project.get("current_best_val_bpb", "?")
    better = "lower" if direction == "minimize" else "higher"

    merged = [b for b in branches if b["status"] == "merged"]

    # === Print context ===

    print(f"\n{'=' * 60}")
    print(f"  {project.get('name', '?')}")
    print(f"  {project.get('description', '')}")
    print(f"{'=' * 60}")
    print(f"  Metric:       {current_best} ({better} is better)")
    print(f"  Experiments:  {project.get('total_experiments', 0)}")
    print(f"  Keeps:        {project.get('total_keeps', 0)}")
    if merged:
        print(f"  Merged:       {len(merged)} contributions")

    # Experiment history
    if experiments:
        print(f"\n  Experiment history ({better} is better):")
        for exp in experiments[:15]:
            status = exp.get("status", "?")
            bpb = exp.get("val_bpb")
            bpb_str = f"{bpb:.6f}" if bpb is not None else "crash"
            desc = exp.get("description", "")[:50]
            marker = " <<<" if status == "keep" else ""
            print(f"    #{exp.get('experiment_number', '?'):3d} {bpb_str}  {status:7s}  {desc}{marker}")

    # Show the training code
    train_file = train_cmd.split()[-1] if train_cmd else "train.py"
    train_path = os.path.join(repo_path, train_file)
    if os.path.exists(train_path):
        with open(train_path) as f:
            code = f.read()
        line_count = len(code.split("\n"))
        print(f"\n  Code ({train_file}, {line_count} lines):")
        print(f"  {'─' * 56}")
        for line in code.split("\n")[:80]:
            print(f"    {line}")
        if line_count > 80:
            print(f"    ... ({line_count - 80} more lines)")
        print(f"  {'─' * 56}")

    # Instructions
    print(f"\n{'=' * 60}")
    print(f"  YOUR GOAL: make the metric {better}")
    print(f"  Current best: {current_best}")
    print(f"")
    print(f"  1. Edit {train_file}")
    print(f"  2. Run: {train_cmd}")
    print(f"  3. Check result: {results_file}")
    print(f"  4. If improved, run: nbench submit --metric <value>")
    print(f"     (auto-creates branch, commits, pushes, registers)")
    print(f"")
    print(f"  Credits: 1% improvement = 1 credit")
    print(f"{'=' * 60}")
