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

from uuid import UUID

from fastapi import APIRouter, Body, Depends, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_pagination, require_tenant
from app.core.security import get_current_user
from app.models.types import CollaborationEntityType
from app.schemas.collaboration import (
    BookmarkCreate,
    BookmarkRead,
    CallLogCreate,
    CallLogRead,
    ChecklistItemCreate,
    ChecklistItemRead,
    CommentCreate,
    CommentRead,
    CommentUpdate,
    EmailMessageCreate,
    EmailMessageRead,
    EmailThreadCreate,
    EmailThreadRead,
    FavoriteCreate,
    FavoriteRead,
    MeetingAttendeeCreate,
    MeetingAttendeeRead,
    MeetingCreate,
    MeetingFinishRequest,
    MeetingRead,
    MentionRead,
    NotificationPreferenceRead,
    NotificationPreferenceUpsert,
    ParticipantCreate,
    ParticipantRead,
    ReminderCreate,
    ReminderRead,
    TaskCreate,
    TaskRead,
    TeamAssignmentCreate,
    TeamAssignmentRead,
    TeamMemberCreate,
    TeamMemberRead,
    TeamRoleCreate,
    TeamRoleRead,
    TimelineEventRead,
)
from app.services.collaboration_services import (
    BookmarkService,
    CallService,
    CommentService,
    EmailMetadataService,
    MeetingService,
    MentionService,
    SalesActivityService,
    SalesTeamService,
    TaskService,
    TimelineService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

router = APIRouter()


@router.post(
    "/activity-participants",
    response_model=ParticipantRead,
    status_code=status.HTTP_201_CREATED,
)
async def add_participant(
    body: ParticipantCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await SalesActivityService(db).add_participant(tenant_id, body)


@router.post(
    "/activity-reminders",
    response_model=ReminderRead,
    status_code=status.HTTP_201_CREATED,
)
async def add_reminder(
    body: ReminderCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await SalesActivityService(db).add_reminder(tenant_id, body)


@router.post("/tasks", response_model=TaskRead, status_code=status.HTTP_201_CREATED)
async def create_task(
    body: TaskCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TaskService(db).create(tenant_id, body)


@router.get("/tasks", response_model=list[TaskRead])
async def list_tasks(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TaskService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@router.post(
    "/tasks/checklist",
    response_model=ChecklistItemRead,
    status_code=status.HTTP_201_CREATED,
)
async def add_checklist_item(
    body: ChecklistItemCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TaskService(db).add_checklist_item(tenant_id, body)


@router.post("/tasks/checklist/{item_id}/complete", response_model=ChecklistItemRead)
async def complete_checklist_item(
    item_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TaskService(db).complete_checklist_item(tenant_id, item_id)


@router.post("/tasks/{task_id}/complete", response_model=TaskRead)
async def complete_task(
    task_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TaskService(db).complete(tenant_id, task_id)


@router.post(
    "/meetings", response_model=MeetingRead, status_code=status.HTTP_201_CREATED
)
async def create_meeting(
    body: MeetingCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MeetingService(db).create(tenant_id, body)


@router.get("/meetings", response_model=list[MeetingRead])
async def list_meetings(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MeetingService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@router.post(
    "/meetings/attendees",
    response_model=MeetingAttendeeRead,
    status_code=status.HTTP_201_CREATED,
)
async def add_meeting_attendee(
    body: MeetingAttendeeCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MeetingService(db).add_attendee(tenant_id, body)


@router.post("/meetings/{meeting_id}/finish", response_model=MeetingRead)
async def finish_meeting(
    meeting_id: UUID,
    body: MeetingFinishRequest | None = Body(default=None),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MeetingService(db).finish(tenant_id, meeting_id, body)


@router.post(
    "/calls", response_model=CallLogRead, status_code=status.HTTP_201_CREATED
)
async def log_call(
    body: CallLogCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await CallService(db).log(tenant_id, body)


@router.get("/calls", response_model=list[CallLogRead])
async def list_calls(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await CallService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@router.post(
    "/email-threads",
    response_model=EmailThreadRead,
    status_code=status.HTTP_201_CREATED,
)
async def create_email_thread(
    body: EmailThreadCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await EmailMetadataService(db).create_thread(tenant_id, body)


@router.post(
    "/emails", response_model=EmailMessageRead, status_code=status.HTTP_201_CREATED
)
async def add_email_message(
    body: EmailMessageCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await EmailMetadataService(db).add_message(tenant_id, body)


@router.get("/timeline", response_model=list[TimelineEventRead])
async def list_timeline(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TimelineService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@router.get(
    "/timeline/opportunities/{opportunity_id}",
    response_model=list[TimelineEventRead],
)
async def list_opportunity_timeline(
    opportunity_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TimelineService(db).list_for_opportunity(tenant_id, opportunity_id)


@router.post(
    "/comments", response_model=CommentRead, status_code=status.HTTP_201_CREATED
)
async def create_comment(
    body: CommentCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await CommentService(db).create(tenant_id, body, actor=user)


@router.get("/comments", response_model=list[CommentRead])
async def list_comments(
    entity_type: CollaborationEntityType,
    entity_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await CommentService(db).list_for_entity(tenant_id, entity_type, entity_id)


@router.patch("/comments/{comment_id}", response_model=CommentRead)
async def update_comment(
    comment_id: UUID,
    body: CommentUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await CommentService(db).update(tenant_id, comment_id, body, actor=user)


@router.get("/mentions/unread", response_model=list[MentionRead])
async def list_unread_mentions(
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MentionService(db).list_unread(tenant_id, user.user_id)


@router.post("/mentions/{mention_id}/read", response_model=MentionRead)
async def mark_mention_read(
    mention_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MentionService(db).mark_read(tenant_id, mention_id)


@router.post(
    "/bookmarks", response_model=BookmarkRead, status_code=status.HTTP_201_CREATED
)
async def add_bookmark(
    body: BookmarkCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await BookmarkService(db).add_bookmark(tenant_id, user.user_id, body)


@router.get("/bookmarks", response_model=list[BookmarkRead])
async def list_bookmarks(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await BookmarkService(db).list_bookmarks(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@router.post(
    "/favorites", response_model=FavoriteRead, status_code=status.HTTP_201_CREATED
)
async def add_favorite(
    body: FavoriteCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await BookmarkService(db).add_favorite(tenant_id, user.user_id, body)


@router.post(
    "/team-roles", response_model=TeamRoleRead, status_code=status.HTTP_201_CREATED
)
async def create_team_role(
    body: TeamRoleCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await SalesTeamService(db).create_role(tenant_id, body)


@router.post(
    "/team-members",
    response_model=TeamMemberRead,
    status_code=status.HTTP_201_CREATED,
)
async def add_team_member(
    body: TeamMemberCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await SalesTeamService(db).add_member(tenant_id, body)


@router.get("/team-members", response_model=list[TeamMemberRead])
async def list_team_members(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await SalesTeamService(db).list_members(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@router.post(
    "/team-assignments",
    response_model=TeamAssignmentRead,
    status_code=status.HTTP_201_CREATED,
)
async def create_team_assignment(
    body: TeamAssignmentCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await SalesTeamService(db).assign(tenant_id, body, actor=user)


@router.put(
    "/collaboration-preferences/{user_id}",
    response_model=NotificationPreferenceRead,
)
async def upsert_notification_preferences(
    user_id: str,
    body: NotificationPreferenceUpsert,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await SalesTeamService(db).upsert_preferences(tenant_id, user_id, body)
