import argparse
import sys
from typing import List
from datetime import date

from config.settings import (
    DEFAULT_START_DATE,
    DEFAULT_END_DATE,
    MAX_WORKERS,
)
from utils.dates import validate_date_range
from utils.logging import get_logger, configure_logging

from ocf.pipelines.pipeline import PipelineConfig, run_pipeline
from io.readers import load_raw_bloomberg_inputs



# Argument Parsing
def parse_args(argv: List[str]) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        prog="ocf",
        description="Options Chain Framework (OCF) CLI",
    )

    parser.add_argument(
        "--tickers",
        required=True,
        help="Comma-separated list of tickers (e.g. AAPL,MSFT,SPY)",
    )

    parser.add_argument(
        "--start",
        default=DEFAULT_START_DATE,
        help="Start date (YYYY-MM-DD)",
    )

    parser.add_argument(
        "--end",
        default=DEFAULT_END_DATE,
        help="End date (YYYY-MM-DD). Defaults to today.",
    )

    parser.add_argument(
        "--max-workers",
        type=int,
        default=MAX_WORKERS,
        help="Maximum parallel workers (not yet parallelized)",
    )

    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Validate inputs without executing pipelines",
    )

    return parser.parse_args(argv)


# Helpers
def parse_tickers(value: str) -> List[str]:
    tickers = [t.strip().upper() for t in value.split(",")]
    if not tickers or any(not t for t in tickers):
        raise ValueError("Invalid ticker list")
    return tickers



# Orchestration
def run_for_ticker(
    *,
    ticker: str,
    start,
    end,
    dry_run: bool = False,
) -> None:
    """
    Execute the OCF pipeline for a single ticker.
    """
    logger = get_logger(__name__, ticker=ticker)
    logger.info("Starting pipeline execution")

    if dry_run:
        logger.info("Dry run enabled — skipping execution")
        return

    # IO boundary
    raw_inputs = load_raw_bloomberg_inputs(
        symbol=ticker,
        start=start,
        end=end,
    )

    config = PipelineConfig(
        symbol=ticker,
        snapshot_date=date.today(),
        build_per_option=True,
    )

    outputs = run_pipeline(
        config=config,
        raw_inputs=raw_inputs,
    )

    logger.info(
        "Pipeline completed successfully "
        f"(outputs: {list(outputs.keys())})"
    )

# Main Entrypoint
def main(argv: List[str] | None = None) -> int:
    configure_logging()

    args = parse_args(argv or sys.argv[1:])
    logger = get_logger(__name__)

    try:
        tickers = parse_tickers(args.tickers)
        start, end = validate_date_range(args.start, args.end)
    except Exception as exc:
        logger.error(f"Invalid arguments: {exc}")
        return 1

    logger.info(
        f"Running OCF for {len(tickers)} ticker(s) "
        f"from {start} to {end or 'today'}"
    )

    if args.dry_run:
        logger.info("Dry-run mode enabled")

    # Sequential execution (parallelism later)
    for ticker in tickers:
        try:
            run_for_ticker(
                ticker=ticker,
                start=start,
                end=end,
                dry_run=args.dry_run,
            )
        except Exception as exc:
            logger.error(f"Ticker {ticker} failed: {exc}")

    logger.info("OCF run finished")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())