"""ansel models — build forecast models."""

from __future__ import annotations

import sys
import time
from pathlib import Path
from typing import cast

from ..auth import get_token
from ..client import get_json, post_resume, post_stream
from ..output import on_models_event, print_models_result
from ..parse import JSONObject
from . import resolve_csv_files


def _require_token() -> str | None:
    """Get auth token or print error."""
    token = get_token()
    if not token:
        print(
            'error: no credentials found. Set ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN.',
            file=sys.stderr,
        )
    return token


def _parse_flags(args: list[str]) -> tuple[list[str], dict[str, str]]:
    """Separate positional args from --flag value pairs."""
    positional: list[str] = []
    flags: dict[str, str] = {}
    i = 0
    while i < len(args):
        if args[i].startswith('--') and i + 1 < len(args):
            flags[args[i][2:]] = args[i + 1]
            i += 2
        else:
            positional.append(args[i])
            i += 1
    return positional, flags


def _build_params(_flags: dict[str, str]) -> dict[str, str]:
    """Build query params from parsed flags."""
    return {}


def _run_models_path(token: str, path: Path, params: dict[str, str]) -> int:
    """ansel models --data <path> — upload CSVs and train models."""
    csv_files = resolve_csv_files(path)
    if csv_files is None:
        return 1

    files_data = [('file', csv_file.name, csv_file.read_text()) for csv_file in csv_files]
    start = time.monotonic()
    result = post_stream(
        '/models', token, files=files_data, params=params, on_event=on_models_event
    )
    elapsed = time.monotonic() - start
    return print_models_result(result, elapsed)


def _run_models_ids(token: str, file_ids: list[str], params: dict[str, str]) -> int:
    """ansel models <file_id...> — train models from pre-uploaded files."""
    start = time.monotonic()
    result = post_stream(
        '/models',
        token,
        json_body={'file_ids': file_ids},
        params=params,
        on_event=on_models_event,
    )
    elapsed = time.monotonic() - start
    return print_models_result(result, elapsed)


def _run_resume(token: str, run_id: str) -> int:
    """ansel models <run_id> — resume from a prior run."""
    start = time.monotonic()
    result = post_resume('models', run_id, token, on_event=on_models_event)
    elapsed = time.monotonic() - start
    return print_models_result(result, elapsed)


def _run_list(token: str) -> int:
    """ansel models list"""
    from ..output import format_model_line

    data = get_json(token, '/models')
    if data is None:
        print('error: failed to fetch models', file=sys.stderr)
        return 1

    raw_models = data.get('models', [])
    models_list: list[JSONObject] = (
        [cast(JSONObject, m) for m in cast(list[object], raw_models) if isinstance(m, dict)]
        if isinstance(raw_models, list)
        else []
    )
    if not models_list:
        print('no models found')
        return 0

    for m in models_list:
        print(format_model_line(m))
    return 0


def run(args: list[str]) -> int:
    """Execute the models command."""
    if not args:
        print('models: build forecast models')
        print()
        print('  models                     Train models from CSVs in current directory')
        print('  models --data <path>       Train models from CSV file or directory')
        print('  models <fil_id...>         Train from pre-uploaded files')
        print('  models list                List trained models')
        print()
        print('Options:')
        print('  --data PATH       CSV file or directory (default: .)')
        return 1

    positional, flags = _parse_flags(args)
    params = _build_params(flags)

    token = _require_token()
    if not token:
        return 1

    # Subcommands
    if positional and positional[0] == 'list':
        return _run_list(token)

    # Positional IDs: run_ prefix → resume, fil_ prefix → pre-uploaded files
    if positional:
        if len(positional) == 1 and positional[0].startswith('run_'):
            return _run_resume(token, positional[0])

        if all(arg.startswith('fil_') for arg in positional):
            return _run_models_ids(token, positional, params)

        print(f"error: unknown argument '{positional[0]}'", file=sys.stderr)
        return 1

    # --data flag or default to cwd
    path = Path(flags.get('data', '.'))
    if not path.exists():
        print(f'error: {path} not found', file=sys.stderr)
        return 1
    return _run_models_path(token, path, params)
