#!/usr/bin/env python3
"""
metrics - Track arbitrary metrics over time

Log numeric values and see trends.
"""

import json
import sys
from datetime import datetime, timedelta
from pathlib import Path
from statistics import mean, stdev

WORKSPACE = Path("/home/wdjones/.openclaw/workspace")
METRICS_FILE = WORKSPACE / "data" / "metrics.json"

def load_metrics() -> dict:
    """Load metrics data."""
    METRICS_FILE.parent.mkdir(parents=True, exist_ok=True)
    if METRICS_FILE.exists():
        with open(METRICS_FILE) as f:
            return json.load(f)
    return {'metrics': {}}

def save_metrics(data: dict):
    """Save metrics data."""
    with open(METRICS_FILE, 'w') as f:
        json.dump(data, f, indent=2)

def define_metric(name: str, unit: str = '', description: str = ''):
    """Define a new metric to track."""
    data = load_metrics()
    
    key = name.lower().replace(' ', '_')
    if key in data['metrics']:
        print(f"Metric already exists: {name}")
        return
    
    data['metrics'][key] = {
        'name': name,
        'unit': unit,
        'description': description,
        'entries': [],
        'created': datetime.now().isoformat(),
    }
    
    save_metrics(data)
    print(f"📊 Created metric: {name}")

def log_value(name: str, value: float, note: str = None):
    """Log a value for a metric."""
    data = load_metrics()
    key = name.lower().replace(' ', '_')
    
    # Find metric by partial match
    matches = [k for k in data['metrics'] if key in k]
    if not matches:
        print(f"Metric not found: {name}")
        print("Create with: metrics define <name>")
        return
    
    key = matches[0]
    metric = data['metrics'][key]
    
    entry = {
        'value': value,
        'timestamp': datetime.now().isoformat(),
        'note': note,
    }
    
    metric['entries'].append(entry)
    save_metrics(data)
    
    unit = metric.get('unit', '')
    print(f"📈 {metric['name']}: {value}{unit}")

def show_metric(name: str, days: int = 7):
    """Show metric details and trend."""
    data = load_metrics()
    key = name.lower().replace(' ', '_')
    
    matches = [k for k in data['metrics'] if key in k]
    if not matches:
        print(f"Metric not found: {name}")
        return
    
    key = matches[0]
    metric = data['metrics'][key]
    entries = metric['entries']
    
    print(f"\n📊 {metric['name']}")
    if metric.get('description'):
        print(f"   {metric['description']}")
    print("=" * 40)
    
    if not entries:
        print("No data yet")
        return
    
    # Filter to date range
    cutoff = datetime.now() - timedelta(days=days)
    recent = [e for e in entries if datetime.fromisoformat(e['timestamp']) > cutoff]
    
    if not recent:
        print(f"No data in last {days} days")
        return
    
    values = [e['value'] for e in recent]
    unit = metric.get('unit', '')
    
    # Stats
    avg = mean(values)
    latest = values[-1]
    high = max(values)
    low = min(values)
    
    print(f"\n  Last {days} days ({len(recent)} entries):")
    print(f"  Latest:  {latest}{unit}")
    print(f"  Average: {avg:.1f}{unit}")
    print(f"  High:    {high}{unit}")
    print(f"  Low:     {low}{unit}")
    
    # Trend
    if len(values) >= 2:
        first_half = mean(values[:len(values)//2])
        second_half = mean(values[len(values)//2:])
        if second_half > first_half * 1.05:
            print(f"  Trend:   📈 Up")
        elif second_half < first_half * 0.95:
            print(f"  Trend:   📉 Down")
        else:
            print(f"  Trend:   ➡️ Stable")
    
    # Recent entries
    print(f"\n  Recent:")
    for e in recent[-5:]:
        date = e['timestamp'][:10]
        note = f" ({e['note']})" if e.get('note') else ""
        print(f"    {date}: {e['value']}{unit}{note}")
    
    print()

def list_metrics():
    """List all metrics."""
    data = load_metrics()
    
    if not data['metrics']:
        print("No metrics defined yet")
        print("Create with: metrics define <name> [unit] [description]")
        return
    
    print(f"\n📊 Metrics ({len(data['metrics'])})")
    print("=" * 40)
    
    for key, metric in data['metrics'].items():
        entries = len(metric['entries'])
        unit = metric.get('unit', '')
        
        if entries > 0:
            latest = metric['entries'][-1]['value']
            print(f"  {metric['name']}: {latest}{unit} ({entries} entries)")
        else:
            print(f"  {metric['name']}: (no data)")
    
    print()

def main():
    if len(sys.argv) < 2:
        print("Usage:")
        print("  metrics define <name> [unit] [description]")
        print("  metrics log <name> <value> [note]")
        print("  metrics show <name> [days]")
        print("  metrics list")
        print("")
        print("Examples:")
        print("  metrics define weight kg")
        print("  metrics log weight 75.5")
        print("  metrics show weight 30")
        list_metrics()
        return
    
    cmd = sys.argv[1]
    
    if cmd == 'define' and len(sys.argv) > 2:
        name = sys.argv[2]
        unit = sys.argv[3] if len(sys.argv) > 3 else ''
        desc = ' '.join(sys.argv[4:]) if len(sys.argv) > 4 else ''
        define_metric(name, unit, desc)
    
    elif cmd == 'log' and len(sys.argv) > 3:
        name = sys.argv[2]
        value = float(sys.argv[3])
        note = ' '.join(sys.argv[4:]) if len(sys.argv) > 4 else None
        log_value(name, value, note)
    
    elif cmd == 'show' and len(sys.argv) > 2:
        name = sys.argv[2]
        days = int(sys.argv[3]) if len(sys.argv) > 3 else 7
        show_metric(name, days)
    
    elif cmd == 'list':
        list_metrics()
    
    else:
        print("Unknown command. Run 'metrics' for help.")

if __name__ == "__main__":
    main()
