from __future__ import annotations

from inspect import Signature
from typing import Dict

from ...docstring import Docstring
from ..book_poll_descriptor import BookPollDescriptor
from ..concept_descriptor import ConceptDescriptor
from .parameter_concept import ParameterConceptFactory


class BookPollFactory:
    @classmethod
    def create(
        cls,
        identifier: str,
        name: str,
        description: str,
        python_signature: Signature,
        docstring: Docstring,
        configuration_params: list[str],
    ) -> BookPollDescriptor:
        """
        Create a BookPollDescriptor from a poll function.

        Args:
            identifier: Unique identifier for the poll
            name: Display name for the poll
            description: Description of what the poll does (from decorator or docstring)
            python_signature: Python signature of the poll function
            docstring: Parsed docstring from the poll function
            configuration_params: Parameter names for configuration (from poll function)

        Returns:
            BookPollDescriptor instance
        """
        # Build configuration map from poll function parameters
        configuration: Dict[str, ConceptDescriptor] = {}
        for param_name in configuration_params:
            parameter = python_signature.parameters[param_name]
            param_description = docstring.param_description_by_name(param_name)
            parameter_concept = ParameterConceptFactory.from_parameter(parameter, description=param_description)
            # Use the first concept from the parameter concept
            if parameter_concept.concepts:
                concept = parameter_concept.concepts[0]
                if not concept.description and param_description:
                    concept.description = param_description
                configuration[param_name] = concept

        # Use provided description, or fall back to docstring if description is empty
        if not description:
            description = (
                (docstring.short_description.strip() if docstring.short_description else "")
                + (" " if docstring.short_description and docstring.long_description else "")
                + (docstring.long_description.strip() if docstring.long_description else "")
            )

        # Build event map - initially empty, will be populated by book decorator
        # when it analyzes the poll function's yielded type
        event: Dict[str, ConceptDescriptor] = {}

        return BookPollDescriptor(
            id=identifier,
            name=name,
            description=description,
            configuration=configuration,
            event=event,
        )
