"""Pytest fixtures for application service tests.

Provides shared fixtures for testing application services including
meetings with segments, summaries, and mock executors.
"""

from __future__ import annotations

from typing import Any
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4

import pytest

from noteflow.application.services.webhook_service import WebhookService
from noteflow.domain.entities import Meeting, Segment, Summary
from noteflow.domain.entities.summary import ActionItem, KeyPoint
from noteflow.domain.utils.time import utc_now
from noteflow.domain.webhooks import WebhookConfig, WebhookDelivery, WebhookEventType
from noteflow.infrastructure.webhooks import WebhookExecutor

# =============================================================================
# Meeting fixtures with explicit segment creation (no loops)
# =============================================================================


def create_segment(segment_id: int, meeting_id: Any, text: str | None = None) -> Segment:
    """Create a single segment with deterministic timing."""
    segment_text = text or f"Segment {segment_id} content"
    return Segment(
        segment_id=segment_id,
        text=segment_text,
        start_time=float(segment_id * 10),
        end_time=float(segment_id * 10 + 9),
        meeting_id=meeting_id,
    )


@pytest.fixture
def completed_meeting() -> Meeting:
    """Create a meeting in completed state with 3 segments (explicit, no loop)."""
    meeting = Meeting.create(title="Q4 Planning Session")
    meeting.start_recording()

    # Add segments explicitly (no loop)
    segment_0 = create_segment(0, meeting.id)
    segment_1 = create_segment(1, meeting.id)
    segment_2 = create_segment(2, meeting.id)

    meeting.add_segment(segment_0)
    meeting.add_segment(segment_1)
    meeting.add_segment(segment_2)

    meeting.begin_stopping()
    meeting.stop_recording()
    return meeting


@pytest.fixture
def meeting_with_summary(completed_meeting: Meeting) -> Meeting:
    """Create a meeting with an attached summary."""
    summary = Summary(
        meeting_id=completed_meeting.id,
        executive_summary="This meeting covered Q4 planning topics.",
        key_points=[
            KeyPoint(text="Budget allocation"),
            KeyPoint(text="Timeline review"),
        ],
        action_items=[
            ActionItem(text="Send budget proposal"),
            ActionItem(text="Schedule follow-up"),
        ],
    )
    completed_meeting.summary = summary
    return completed_meeting


# =============================================================================
# Webhook executor fixtures
# =============================================================================


@pytest.fixture
def captured_payloads() -> list[dict[str, Any]]:
    """Store payloads passed to executor for verification."""
    return []


@pytest.fixture
def mock_executor(captured_payloads: list[dict[str, Any]]) -> MagicMock:
    """Create a mock executor that captures delivered payloads."""
    executor = MagicMock(spec=WebhookExecutor)

    async def capture_delivery(
        config: WebhookConfig,
        event_type: WebhookEventType,
        payload: dict[str, Any],
    ) -> WebhookDelivery:
        captured_payloads.append(payload)
        return WebhookDelivery(
            id=uuid4(),
            webhook_id=config.id,
            event_type=event_type,
            payload=payload,
            status_code=200,
            response_body=None,
            error_message=None,
            attempt_count=1,
            duration_ms=100,
            delivered_at=utc_now(),
        )

    executor.deliver = AsyncMock(side_effect=capture_delivery)
    executor.close = AsyncMock()
    return executor


@pytest.fixture
def webhook_service(mock_executor: MagicMock) -> WebhookService:
    """Create a WebhookService with mock executor."""
    return WebhookService(executor=mock_executor)


# =============================================================================
# Webhook configuration helpers (explicit, no loops)
# =============================================================================


def create_first_webhook() -> WebhookConfig:
    """Create first webhook for multi-webhook tests."""
    return WebhookConfig.create(
        workspace_id=uuid4(),
        url="https://first.example.com/hook",
        events=[WebhookEventType.MEETING_COMPLETED],
        name="First Webhook",
    )


def create_second_webhook() -> WebhookConfig:
    """Create second webhook for multi-webhook tests."""
    return WebhookConfig.create(
        workspace_id=uuid4(),
        url="https://second.example.com/hook",
        events=[WebhookEventType.MEETING_COMPLETED],
        name="Second Webhook",
    )


def create_failing_webhook() -> WebhookConfig:
    """Create webhook config for failure scenario."""
    return WebhookConfig.create(
        workspace_id=uuid4(),
        url="https://failing.example.com/hook",
        events=[WebhookEventType.MEETING_COMPLETED],
        name="Failing Webhook",
    )


def create_working_webhook() -> WebhookConfig:
    """Create webhook config for success scenario."""
    return WebhookConfig.create(
        workspace_id=uuid4(),
        url="https://working.example.com/hook",
        events=[WebhookEventType.MEETING_COMPLETED],
        name="Working Webhook",
    )
