"""Planka service provider — webhook-based implementation of ServiceProvider."""

from __future__ import annotations

import logging
from typing import Any

import aiohttp

from notify_bridge_core.models.events import ServiceEvent
from notify_bridge_core.providers.base import ServiceProvider, ServiceProviderType
from notify_bridge_core.templates.variables import TemplateVariableDefinition

from .client import PlankaClient

_LOGGER = logging.getLogger(__name__)


# Planka-specific template variables
PLANKA_VARIABLES: list[TemplateVariableDefinition] = [
    TemplateVariableDefinition(
        name="sender",
        type="string",
        description="Username of the user who triggered the event",
        example="alexei",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="sender_name",
        type="string",
        description="Display name of the sender",
        example="Alexei",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="board_name",
        type="string",
        description="Board name",
        example="My Project",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="board_id",
        type="string",
        description="Board ID",
        example="123456",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="board_url",
        type="string",
        description="URL to the board",
        example="https://planka.example.com/boards/123456",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="card_name",
        type="string",
        description="Card name",
        example="Fix login bug",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="card_id",
        type="string",
        description="Card ID",
        example="789012",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="card_url",
        type="string",
        description="URL to the card",
        example="https://planka.example.com/cards/789012",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="card_description",
        type="string",
        description="Card description text",
        example="Users cannot log in with SSO",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="card_due_date",
        type="string",
        description="Card due date (if set)",
        example="2026-04-01T00:00:00.000Z",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="list_name",
        type="string",
        description="Current list name",
        example="In Progress",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="old_list_name",
        type="string",
        description="Previous list name (card move events)",
        example="To Do",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="new_list_name",
        type="string",
        description="New list name (card move events)",
        example="In Progress",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="comment_text",
        type="string",
        description="Comment body text",
        example="Looks good, ready for review!",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="task_name",
        type="string",
        description="Task/checklist item name",
        example="Write unit tests",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="task_completed",
        type="bool",
        description="Whether the task is completed",
        example="true",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="attachment_name",
        type="string",
        description="Attachment filename",
        example="screenshot.png",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="label_name",
        type="string",
        description="Label name",
        example="bug",
        provider_type=ServiceProviderType.PLANKA,
    ),
    TemplateVariableDefinition(
        name="label_color",
        type="string",
        description="Label color",
        example="berry-red",
        provider_type=ServiceProviderType.PLANKA,
    ),
]


class PlankaServiceProvider(ServiceProvider):
    """Planka webhook-based provider.

    Like Gitea, Planka pushes events to us via webhooks.
    The poll() method is a no-op — events are parsed from incoming
    webhook payloads by event_parser.parse_webhook().
    """

    provider_type = ServiceProviderType.PLANKA

    def __init__(
        self,
        session: aiohttp.ClientSession,
        url: str,
        api_key: str,
        name: str = "Planka",
    ) -> None:
        self._client = PlankaClient(session, url, api_key)
        self._name = name

    @property
    def client(self) -> PlankaClient:
        return self._client

    async def connect(self) -> bool:
        return await self._client.ping()

    async def disconnect(self) -> None:
        pass  # session lifecycle managed by caller

    async def poll(
        self,
        collection_ids: list[str],
        tracker_state: dict[str, Any],
    ) -> tuple[list[ServiceEvent], dict[str, Any]]:
        # Planka is webhook-based — poll() is not used.
        # Events arrive via the /api/webhooks/planka route.
        return [], tracker_state

    def get_available_variables(self) -> list[TemplateVariableDefinition]:
        return list(PLANKA_VARIABLES)

    def get_provider_config_schema(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "Planka server URL",
                    "example": "https://planka.example.com",
                },
                "api_key": {
                    "type": "string",
                    "description": "Planka API key or JWT token (for API access)",
                    "secret": True,
                },
                "webhook_secret": {
                    "type": "string",
                    "description": "Bearer token used by Planka for webhook authentication",
                    "secret": True,
                },
            },
            "required": ["url", "webhook_secret"],
        }

    async def list_collections(self) -> list[dict[str, Any]]:
        boards = await self._client.get_boards()
        return [
            {
                "id": str(b.get("id", "")),
                "name": b.get("name", ""),
            }
            for b in boards
        ]

    async def test_connection(self) -> dict[str, Any]:
        ok = await self._client.ping()
        if ok:
            return {"ok": True, "message": "Connected to Planka"}
        return {"ok": False, "message": "Failed to connect to Planka"}
