"""Calendar platform for Mealie."""

from datetime import datetime
from typing import override

from aiomealie import Mealplan, MealplanEntryType
from awesomeversion import AwesomeVersion

from homeassistant.components.calendar import CalendarEntity, CalendarEvent
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .coordinator import MealieConfigEntry, MealieMealplanCoordinator
from .entity import MealieEntity

PARALLEL_UPDATES = 0


async def async_setup_entry(
    hass: HomeAssistant,
    entry: MealieConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up the calendar platform for entity."""
    coordinator = entry.runtime_data.mealplan_coordinator
    version = entry.runtime_data.version

    supported_mealplan_entry_types: list[MealplanEntryType]
    if version.valid and version < AwesomeVersion("v3.7.0"):
        # Prior to Mealie 3.7.0, only these mealplan entry types were supported
        supported_mealplan_entry_types = [
            MealplanEntryType.BREAKFAST,
            MealplanEntryType.DINNER,
            MealplanEntryType.LUNCH,
            MealplanEntryType.SIDE,
        ]
    else:
        # For Mealie 3.7.0 and newer and nightlies, add all current mealplan entry types
        supported_mealplan_entry_types = list(MealplanEntryType)

    async_add_entities(
        MealieMealplanCalendarEntity(coordinator, entry_type)
        for entry_type in supported_mealplan_entry_types
    )


def _get_event_from_mealplan(mealplan: Mealplan) -> CalendarEvent:
    """Create a CalendarEvent from a Mealplan."""
    description: str | None = mealplan.description
    name = mealplan.title or "No recipe"
    if mealplan.recipe:
        name = mealplan.recipe.name
        description = mealplan.recipe.description
    return CalendarEvent(
        start=mealplan.mealplan_date,
        end=mealplan.mealplan_date,
        summary=name,
        description=description,
    )


class MealieMealplanCalendarEntity(MealieEntity, CalendarEntity):
    """A calendar entity."""

    def __init__(
        self, coordinator: MealieMealplanCoordinator, entry_type: MealplanEntryType
    ) -> None:
        """Create the Calendar entity."""
        super().__init__(coordinator, entry_type.name.lower())
        self._entry_type = entry_type
        self._attr_translation_key = entry_type.name.lower()

    @property
    @override
    def event(self) -> CalendarEvent | None:
        """Return the next upcoming event."""
        mealplans = self.coordinator.data[self._entry_type]
        if not mealplans:
            return None
        sorted_mealplans = sorted(mealplans, key=lambda x: x.mealplan_date)
        return _get_event_from_mealplan(sorted_mealplans[0])

    @override
    async def async_get_events(
        self, hass: HomeAssistant, start_date: datetime, end_date: datetime
    ) -> list[CalendarEvent]:
        """Get all events in a specific time frame."""
        mealplans = (
            await self.coordinator.client.get_mealplans(
                start_date.date(), end_date.date()
            )
        ).items
        return [
            _get_event_from_mealplan(mealplan)
            for mealplan in mealplans
            if mealplan.entry_type is self._entry_type
        ]
