"""Memory repository implementations for core domain entities.

Provides repository interfaces over the in-memory MeetingStore for
uniform access pattern with database implementations.
"""

from __future__ import annotations

from collections.abc import Sequence
from datetime import datetime
from typing import TYPE_CHECKING
from uuid import UUID

from noteflow.domain.entities import Meeting, Segment, Summary
from noteflow.domain.value_objects import MeetingId, MeetingState

if TYPE_CHECKING:
    from noteflow.grpc.meeting_store import MeetingStore


class MemoryMeetingRepository:
    """Meeting repository backed by MeetingStore."""

    def __init__(self, store: MeetingStore) -> None:
        """Initialize with meeting store."""
        self._store = store

    async def create(self, meeting: Meeting) -> Meeting:
        """Persist a new meeting."""
        return self._store.insert(meeting)

    async def get(self, meeting_id: MeetingId) -> Meeting | None:
        """Retrieve a meeting by ID."""
        return self._store.get(str(meeting_id))

    async def update(self, meeting: Meeting) -> Meeting:
        """Update an existing meeting."""
        return self._store.update(meeting)

    async def delete(self, meeting_id: MeetingId) -> bool:
        """Delete a meeting and all associated data."""
        return self._store.delete(str(meeting_id))

    async def list_all(
        self,
        states: list[MeetingState] | None = None,
        limit: int = 100,
        offset: int = 0,
        sort_desc: bool = True,
        project_id: UUID | None = None,
    ) -> tuple[Sequence[Meeting], int]:
        """List meetings via in-memory store with optional state filtering."""
        project_filter = str(project_id) if project_id else None
        return self._store.list_all(states, limit, offset, sort_desc, project_filter)

    async def count_by_state(self, state: MeetingState) -> int:
        """Count meetings in a specific state."""
        return self._store.count_by_state(state)

    async def find_older_than(self, cutoff: datetime) -> Sequence[Meeting]:
        """Find completed meetings older than cutoff date."""
        return self._store.find_older_than(cutoff)


class MemorySegmentRepository:
    """Segment repository backed by MeetingStore."""

    def __init__(self, store: MeetingStore) -> None:
        """Initialize with meeting store."""
        self._store = store

    async def add(self, meeting_id: MeetingId, segment: Segment) -> Segment:
        """Add a segment to a meeting."""
        self._store.add_segment(str(meeting_id), segment)
        return segment

    async def add_batch(
        self,
        meeting_id: MeetingId,
        segments: Sequence[Segment],
    ) -> Sequence[Segment]:
        """Add segments to meeting via in-memory store (no DB batching)."""
        for segment in segments:
            self._store.add_segment(str(meeting_id), segment)
        return segments

    async def get_by_meeting(
        self,
        meeting_id: MeetingId,
        include_words: bool = True,
    ) -> Sequence[Segment]:
        """Fetch segments from in-memory store (include_words ignored)."""
        return self._store.fetch_segments(str(meeting_id))

    async def search_semantic(
        self,
        query_embedding: list[float],
        limit: int = 10,
        meeting_id: MeetingId | None = None,
    ) -> Sequence[tuple[Segment, float]]:
        """Return empty - semantic search requires database with pgvector."""
        return []

    async def update_embedding(
        self,
        segment_db_id: int,
        embedding: list[float],
    ) -> None:
        """No-op: embeddings require database with pgvector extension."""

    async def update_speaker(
        self,
        segment_db_id: int,
        speaker_id: str | None,
        speaker_confidence: float,
    ) -> None:
        """No-op: in-memory segments update speaker directly on entity."""

    async def compute_next_segment_id(self, meeting_id: MeetingId) -> int:
        """Compute next available segment ID (0 if meeting has no segments)."""
        return self._store.compute_next_segment_id(str(meeting_id))


class MemorySummaryRepository:
    """Summary repository backed by MeetingStore."""

    def __init__(self, store: MeetingStore) -> None:
        """Initialize with meeting store."""
        self._store = store

    async def save(self, summary: Summary) -> Summary:
        """Save or update a meeting summary."""
        self._store.set_summary(str(summary.meeting_id), summary)
        return summary

    async def get_by_meeting(self, meeting_id: MeetingId) -> Summary | None:
        """Get summary for a meeting."""
        return self._store.get_summary(str(meeting_id))

    async def delete_by_meeting(self, meeting_id: MeetingId) -> bool:
        """Delete summary for a meeting."""
        return self._store.clear_summary(str(meeting_id))


class MemoryAssetRepository:
    """In-memory asset repository (no-op)."""

    async def delete_meeting_assets(
        self,
        meeting_id: MeetingId,
        asset_path: str | None = None,
    ) -> None:
        """No-op for memory mode."""
        pass
