"""Form engine — orchestrates definition loading, rendering, validation, and submission."""

from __future__ import annotations

import json
from typing import Any

import click

from corpo.forms.definitions import FormDefinition, get_form_definition, form_definition_to_dict
from corpo.forms.renderer import InteractiveRenderer
from corpo.forms.schema import generate_json_schema
from corpo.forms.validator import validate_form_data


class FormEngine:
    """High-level form engine used by CLI commands."""

    def __init__(self, form_id: str = "entity-formation"):
        self.form = get_form_definition(form_id)
        if not self.form:
            raise ValueError(f"Unknown form type: {form_id}")

    def run_interactive(self, *, show_hints: bool = True) -> dict[str, Any] | None:
        """Run the interactive Q&A flow. Returns form data or None if cancelled."""
        renderer = InteractiveRenderer(self.form, show_hints=show_hints)
        return renderer.run()

    def dump_schema(self) -> dict:
        """Return JSON schema for non-interactive / programmatic use."""
        return generate_json_schema(self.form)

    def dump_definition(self) -> dict:
        """Return the full form definition as a dict."""
        return form_definition_to_dict(self.form)

    def validate(self, data: dict) -> list[dict]:
        """Validate form data against the definition. Returns list of errors."""
        return validate_form_data(self.form, data)

    def submit(self, data: dict, *, client=None, api_key: str = "") -> dict:
        """Validate and submit form data via the quote→pay flow.

        Returns the API result or raises on validation errors.
        """
        errors = self.validate(data)
        if errors:
            return {"valid": False, "errors": errors}

        # Wire to quote→pay flow
        if client is None:
            from corpo.client import get_client
            from corpo.auth_config import get_api_key, get_api_url, load_auth_config
            cfg = load_auth_config()
            api_url = get_api_url(cfg)
            key = api_key or get_api_key(cfg)
            if not key:
                return {"valid": True, "errors": [], "error": "No API key configured. Run `corpo register` first."}
            client = get_client(api_url, api_key=key)

        entity_name = data.get("entity_name", "")
        entity_type = data.get("entity_type", "dao_llc")

        try:
            quote = client.create_quote(entity_name, entity_type)
        except Exception as e:
            return {"valid": True, "errors": [], "submitted": False, "error": str(e)}

        return {
            "valid": True,
            "errors": [],
            "submitted": True,
            "quote": quote,
            "form_data": data,
        }
