"""Phase 6.3 collaboration repositories."""
from __future__ import annotations

from uuid import UUID

from sqlalchemy import select

from app.models.collaboration import (
    ActivityParticipant,
    ActivityPriorityDefinition,
    ActivityReminder,
    ActivityStatusDefinition,
    ActivityTypeDefinition,
    Bookmark,
    CallLog,
    CallOutcome,
    Comment,
    CommentVersion,
    CrmNotificationPreference,
    EmailMessage,
    EmailThread,
    Favorite,
    Meeting,
    MeetingAttendee,
    Mention,
    SalesCollaborationAudit,
    SalesTask,
    SalesTeamMember,
    SalesTimelineEvent,
    TaskChecklistItem,
    TeamAssignment,
    TeamRole,
    TimelineEventLink,
)
from app.models.types import CollaborationEntityType
from app.repositories.base import TenantBaseRepository
from app.repositories.foundation import SalesActivityRepository

__all__ = ["SalesActivityRepository"]


class ActivityTypeDefinitionRepository(TenantBaseRepository[ActivityTypeDefinition]):
    model = ActivityTypeDefinition


class ActivityStatusDefinitionRepository(TenantBaseRepository[ActivityStatusDefinition]):
    model = ActivityStatusDefinition


class ActivityPriorityDefinitionRepository(
    TenantBaseRepository[ActivityPriorityDefinition]
):
    model = ActivityPriorityDefinition


class ActivityParticipantRepository(TenantBaseRepository[ActivityParticipant]):
    model = ActivityParticipant


class ActivityReminderRepository(TenantBaseRepository[ActivityReminder]):
    model = ActivityReminder


class SalesTaskRepository(TenantBaseRepository[SalesTask]):
    model = SalesTask


class TaskChecklistRepository(TenantBaseRepository[TaskChecklistItem]):
    model = TaskChecklistItem

    async def list_by_task(self, tenant_id: UUID, task_id: UUID):
        stmt = (
            select(TaskChecklistItem)
            .where(
                TaskChecklistItem.tenant_id == tenant_id,
                TaskChecklistItem.task_id == task_id,
            )
            .order_by(TaskChecklistItem.position.asc())
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class MeetingRepository(TenantBaseRepository[Meeting]):
    model = Meeting


class MeetingAttendeeRepository(TenantBaseRepository[MeetingAttendee]):
    model = MeetingAttendee


class CallOutcomeRepository(TenantBaseRepository[CallOutcome]):
    model = CallOutcome

    async def get_by_code(self, tenant_id: UUID, code: str) -> CallOutcome | None:
        stmt = select(CallOutcome).where(
            CallOutcome.tenant_id == tenant_id, CallOutcome.code == code
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class CallLogRepository(TenantBaseRepository[CallLog]):
    model = CallLog


class EmailThreadRepository(TenantBaseRepository[EmailThread]):
    model = EmailThread


class EmailMessageRepository(TenantBaseRepository[EmailMessage]):
    model = EmailMessage


class SalesTimelineRepository(TenantBaseRepository[SalesTimelineEvent]):
    model = SalesTimelineEvent

    async def list_for_entity(
        self,
        tenant_id: UUID,
        entity_type: CollaborationEntityType,
        entity_id: UUID,
        *,
        limit: int = 100,
    ):
        stmt = (
            select(SalesTimelineEvent)
            .where(
                SalesTimelineEvent.tenant_id == tenant_id,
                SalesTimelineEvent.entity_type == entity_type,
                SalesTimelineEvent.entity_id == entity_id,
            )
            .order_by(SalesTimelineEvent.occurred_at.desc())
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()

    async def list_for_opportunity(
        self, tenant_id: UUID, opportunity_id: UUID, *, limit: int = 100
    ):
        stmt = (
            select(SalesTimelineEvent)
            .where(
                SalesTimelineEvent.tenant_id == tenant_id,
                SalesTimelineEvent.related_opportunity_id == opportunity_id,
            )
            .order_by(SalesTimelineEvent.occurred_at.desc())
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class TimelineEventLinkRepository(TenantBaseRepository[TimelineEventLink]):
    model = TimelineEventLink


class CommentRepository(TenantBaseRepository[Comment]):
    model = Comment

    async def list_for_entity(
        self,
        tenant_id: UUID,
        entity_type: CollaborationEntityType,
        entity_id: UUID,
    ):
        stmt = (
            select(Comment)
            .where(
                Comment.tenant_id == tenant_id,
                Comment.entity_type == entity_type,
                Comment.entity_id == entity_id,
                Comment.is_deleted.is_(False),
            )
            .order_by(Comment.created_at.asc())
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class CommentVersionRepository(TenantBaseRepository[CommentVersion]):
    model = CommentVersion


class MentionRepository(TenantBaseRepository[Mention]):
    model = Mention

    async def list_unread_for_user(self, tenant_id: UUID, user_id: str):
        stmt = select(Mention).where(
            Mention.tenant_id == tenant_id,
            Mention.mentioned_user_id == user_id,
            Mention.is_read.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class BookmarkRepository(TenantBaseRepository[Bookmark]):
    model = Bookmark

    async def get_user_bookmark(
        self,
        tenant_id: UUID,
        user_id: str,
        entity_type: CollaborationEntityType,
        entity_id: UUID,
    ) -> Bookmark | None:
        stmt = select(Bookmark).where(
            Bookmark.tenant_id == tenant_id,
            Bookmark.user_id == user_id,
            Bookmark.entity_type == entity_type,
            Bookmark.entity_id == entity_id,
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class FavoriteRepository(TenantBaseRepository[Favorite]):
    model = Favorite


class TeamRoleRepository(TenantBaseRepository[TeamRole]):
    model = TeamRole


class SalesTeamMemberRepository(TenantBaseRepository[SalesTeamMember]):
    model = SalesTeamMember


class TeamAssignmentRepository(TenantBaseRepository[TeamAssignment]):
    model = TeamAssignment


class CrmNotificationPreferenceRepository(
    TenantBaseRepository[CrmNotificationPreference]
):
    model = CrmNotificationPreference

    async def get_for_user(
        self, tenant_id: UUID, user_id: str
    ) -> CrmNotificationPreference | None:
        stmt = select(CrmNotificationPreference).where(
            CrmNotificationPreference.tenant_id == tenant_id,
            CrmNotificationPreference.user_id == user_id,
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class SalesCollaborationAuditRepository(
    TenantBaseRepository[SalesCollaborationAudit]
):
    model = SalesCollaborationAudit
