"""Ejecuta N simulaciones de mercado con parámetros variables para análisis Monte Carlo."""

import sys
import os
import json


def monte_carlo_market(
    n_simulations: int = 100,
    base_params: dict | None = None,
    vary_params: dict | None = None,
    seed_start: int = 0,
) -> list[dict]:
    """Ejecuta N simulaciones variando parámetros.

    base_params: parámetros fijos para run_market_sim
    vary_params: dict de param_name -> (min, max) para variar uniformemente

    Retorna lista de dicts, cada uno con los params usados + métricas resumen.
    """
    import numpy as np

    sys.path.insert(0, os.path.join(os.environ.get('FN_REGISTRY_ROOT', os.path.expanduser('~/fn_registry')), 'python', 'functions'))
    sys.path.insert(0, os.path.join(os.environ.get('FN_REGISTRY_ROOT', os.path.expanduser('~/fn_registry')), 'python', 'functions', 'pipelines'))
    from run_market_sim import run_market_sim

    if base_params is None:
        base_params = {}
    if vary_params is None:
        vary_params = {}

    rng = np.random.default_rng(seed_start)
    results = []

    for i in range(n_simulations):
        params = dict(base_params)
        params['seed'] = seed_start + i

        # Variar parámetros
        varied = {}
        for pname, (pmin, pmax) in vary_params.items():
            val = rng.uniform(pmin, pmax)
            params[pname] = round(val, 6)
            varied[pname] = params[pname]

        sim = run_market_sim(**params)

        # Métricas resumen
        spreads = sim['spreads']
        trade_prices = sim['trade_prices']
        n_per_tick = sim['n_trades_per_tick']

        result = {
            'sim_id': i,
            'seed': params['seed'],
            **varied,
            'total_trades': sim['total_trades'],
            'mean_spread': round(np.mean(spreads), 6) if spreads else 0,
            'std_spread': round(np.std(spreads), 6) if spreads else 0,
            'mean_trades_per_tick': round(np.mean(n_per_tick), 2),
            'price_return': round((sim['fundamental_prices'][-1] / sim['fundamental_prices'][0] - 1) * 100, 4),
            'maker_total_pnl': round(sum(sim['maker_pnls']), 2),
        }

        if trade_prices:
            tp = np.array(trade_prices)
            log_ret = np.diff(np.log(tp[tp > 0]))
            if len(log_ret) > 1:
                result['realized_vol'] = round(float(np.std(log_ret)), 6)

        results.append(result)

        if (i + 1) % max(1, n_simulations // 10) == 0:
            print(f'  {i+1}/{n_simulations} simulaciones completadas')

    return results


if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('-n', type=int, default=10)
    args = parser.parse_args()

    results = monte_carlo_market(
        n_simulations=args.n,
        base_params={'n_ticks': 200},
        vary_params={'sigma': (0.005, 0.05), 'gamma': (0.01, 1.0)},
    )
    print(json.dumps(results[-1], indent=2))
    print(f'\n{len(results)} simulaciones completadas')
