"""
Async CRUD repository generator.

Generates repository pattern classes with async SQLAlchemy operations.
"""

from ...base import BaseGenerator
from ....ir.models import GeneratedFile, ParsedModel
from ._methods import (
    generate_count,
    generate_create,
    generate_create_many,
    generate_delete,
    generate_exists,
    generate_get_all,
    generate_get_by_id,
    generate_get_by_ids,
    generate_update,
)
from ._vector import generate_vector_search


class CRUDGenerator(BaseGenerator):
    """
    Generates async CRUD repository classes.

    Creates repository pattern implementation for each model
    with standard CRUD operations using AsyncSession.
    """

    def generate(self) -> list[GeneratedFile]:
        """Generate CRUD files for all apps."""
        files: list[GeneratedFile] = []

        for app_label, models in self.context.group_models_by_app().items():
            content = self._generate_crud_file(app_label, models)
            files.append(self.create_file(f"{app_label}/crud.py", content))

        return files

    def _generate_crud_file(self, app_label: str, models: list[ParsedModel]) -> str:
        """Generate crud.py content for an app."""
        model_names = [m.name for m in models]
        model_imports = ", ".join(model_names)

        lines = [
            '"""',
            f"Async CRUD repositories for {app_label}.",
            "",
            "Auto-generated by django-cfg FastAPI ORM Generator.",
            '"""',
            "",
            "from typing import List, Optional, Sequence",
            "",
            "from sqlalchemy import select",
            "from sqlalchemy.ext.asyncio import AsyncSession",
            "",
            f"from .models import {model_imports}",
            "",
            "",
        ]

        for model in models:
            lines.append(self._generate_repository(model))

        return "\n".join(lines)

    def _generate_repository(self, model: ParsedModel) -> str:
        """Generate repository class for a model."""
        suffix = self.config.repository_suffix
        class_name = f"{model.name}{suffix}"

        lines = []
        lines.append(f"class {class_name}:")
        if self.config.add_docstrings:
            lines.append(f'    """Repository for {model.name} CRUD operations."""')
        lines.append("")

        for generator_fn in (
            generate_get_by_id,
            generate_get_all,
            generate_get_by_ids,
            generate_create,
            generate_create_many,
            generate_update,
            generate_delete,
            generate_exists,
            generate_count,
        ):
            lines.extend(generator_fn(model))
            lines.append("")

        vector_fields = [f for f in model.fields if f.is_vector]
        if vector_fields:
            lines.extend(generate_vector_search(model, vector_fields[0]))
            lines.append("")

        lines.append("")
        return "\n".join(lines)
