"""Basic usage example for pyfortis."""

from pathlib import Path

from pyfortis import Order, Position, RiskEngine, Side

# Load engine from config
config_path = Path(__file__).parent / "risk_config.yaml"
engine = RiskEngine.from_yaml(config_path)
print(f"Loaded: {engine}")
print(f"Validators: {engine.validator_names}")
print(f"Calculators: {engine.calculator_names}")
print()

# Register a custom handler
@engine.handler("notify")
def notify(breach, ctx):
    print(f"  ALERT [{breach.severity.value}]: {breach.message}")


# ── 1. Stateless order validation ──────────────────────────────────────

print("=== Stateless Order Validation ===")

# Good order — should be approved
order_ok = Order(
    order_id="o-001",
    instrument="AAPL",
    side=Side.BUY,
    quantity=100,
    price=150.0,
    portfolio="default",
)
result = engine.validate_order(order_ok)
print(f"Order {order_ok.order_id}: {result.verdict.value} — {result.message}")

# Bad order — exceeds position limit
order_bad = Order(
    order_id="o-002",
    instrument="AAPL",
    side=Side.BUY,
    quantity=20000,
    price=150.0,
    portfolio="default",
)
result = engine.validate_order(order_bad)
print(f"Order {order_bad.order_id}: {result.verdict.value} — {result.message}")
for b in result.breaches:
    print(f"  Breach: [{b.severity.value}] {b.limit_name}: {b.message}")
print()

# ── 2. Stateful monitor ───────────────────────────────────────────────

print("=== Stateful Monitor ===")
monitor = engine.create_monitor()

# Add positions
monitor.update_position(
    Position(instrument="AAPL", quantity=5000, avg_price=145.0, current_price=150.0)
)
monitor.update_position(
    Position(instrument="GOOGL", quantity=200, avg_price=2800.0, current_price=2850.0)
)

# Validate order against existing positions
order = Order(
    order_id="o-003",
    instrument="AAPL",
    side=Side.BUY,
    quantity=6000,
    price=150.0,
)
result = monitor.validate_order(order)
print(f"Order {order.order_id}: {result.verdict.value} — {result.message}")
for b in result.breaches:
    print(f"  Breach: [{b.severity.value}] {b.limit_name}: {b.message}")

# Check circuit breakers
monitor.update_pnl(daily_pnl=-60000, current_value=900000)
tripped = monitor.check_circuit_breakers()
if tripped:
    print(f"Circuit breakers tripped: {[cb.name for cb in tripped]}")
    print(f"Monitor halted: {monitor.is_halted}")

# Try order while halted
result = monitor.validate_order(
    Order(order_id="o-004", instrument="MSFT", side=Side.BUY, quantity=10, price=300.0)
)
print(f"Order o-004 while halted: {result.verdict.value} — {result.message}")
print()

# ── 3. Orchestrator with stores ────────────────────────────────────────

print("=== Orchestrator ===")
orchestrator = engine.create_orchestrator()

# Add a position
orchestrator.on_position_update(
    Position(instrument="TSLA", quantity=500, avg_price=200.0, current_price=210.0)
)

# Validate order through orchestrator
result = orchestrator.validate_order(
    Order(order_id="o-005", instrument="TSLA", side=Side.BUY, quantity=100, price=210.0)
)
print(f"Order o-005: {result.verdict.value} — {result.message}")

# Compute metrics
returns = [0.01, -0.02, 0.015, -0.005, 0.008, -0.01, 0.02, -0.03, 0.005, 0.01]
metrics = orchestrator.run_metrics(returns_data=returns)
for m in metrics:
    print(f"  {m.metric_name}: {m.value:.4f} — {m.message}")

print("\nDone!")
