"""Generate Pydantic models from EntitySchema definitions."""

from __future__ import annotations

from pathlib import Path

from ninja_core.schema.entity import EntitySchema

from .base import build_fields_meta, get_template_env, write_generated_file


def _has_field_type(entity: EntitySchema, *type_names: str) -> bool:
    """Check if any field in the entity uses one of the given type names."""
    return any(f.field_type.value in type_names for f in entity.fields)


def generate_model(entity: EntitySchema, output_dir: Path) -> Path:
    """Generate a Pydantic model file for a single entity.

    Args:
        entity: The entity schema to generate from.
        output_dir: Directory to write the generated file into.

    Returns:
        Path to the generated file.
    """
    env = get_template_env()
    template = env.get_template("model.py.j2")

    content = template.render(
        entity=entity,
        fields_meta=build_fields_meta(entity),
        has_uuid=_has_field_type(entity, "uuid"),
        has_datetime=_has_field_type(entity, "datetime"),
        has_date=_has_field_type(entity, "date"),
        has_constraints=any(f.constraints for f in entity.fields),
    )

    file_path = output_dir / f"{entity.name.lower()}.py"
    write_generated_file(file_path, content)
    return file_path


def generate_models(entities: list[EntitySchema], output_dir: Path) -> list[Path]:
    """Generate Pydantic models for all entities.

    Args:
        entities: List of entity schemas.
        output_dir: Base directory for generated model files.

    Returns:
        List of paths to generated files.
    """
    models_dir = output_dir / "_generated" / "models"
    paths: list[Path] = []

    # Generate __init__.py that re-exports all models
    init_lines = [
        "# AUTO-GENERATED by ninja-codegen — DO NOT EDIT",
        "",
    ]
    for entity in entities:
        path = generate_model(entity, models_dir)
        paths.append(path)
        init_lines.append(f"from .{entity.name.lower()} import {entity.name}")

    if entities:
        init_lines.append("")
        all_names = ", ".join(repr(e.name) for e in entities)
        init_lines.append(f"__all__ = [{all_names}]")
        init_lines.append("")

    init_path = models_dir / "__init__.py"
    write_generated_file(init_path, "\n".join(init_lines))
    paths.append(init_path)

    return paths
