"""Ticket mutation service — wraps PSA provider, resolves is_rf_user flag."""
from __future__ import annotations

import logging
from uuid import UUID

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.psa_connection import PsaConnection
from app.models.psa_member_mapping import PsaMemberMapping
from app.schemas.psa_tickets import (
    PSAResourceSchema,
    PSATicketCreatedSchema,
    PSATicketStatusUpdateSchema,
)
from app.services.psa.registry import get_provider_for_account
from app.services.psa.types import TicketCreatePayload

logger = logging.getLogger(__name__)


async def _get_mapped_member_ids(account_id: UUID, db: AsyncSession) -> set[int]:
    """Return set of external_member_id ints that are mapped to RF users."""
    conn_result = await db.execute(
        select(PsaConnection).where(PsaConnection.account_id == account_id)
    )
    conn = conn_result.scalar_one_or_none()
    if not conn:
        return set()
    mappings = await db.execute(
        select(PsaMemberMapping).where(PsaMemberMapping.psa_connection_id == conn.id)
    )
    return {int(m.external_member_id) for m in mappings.scalars().all() if m.external_member_id}


async def list_resources(
    account_id: UUID, ticket_id: int, db: AsyncSession
) -> list[PSAResourceSchema]:
    provider = await get_provider_for_account(account_id, db)
    mapped_ids = await _get_mapped_member_ids(account_id, db)
    resources = await provider.list_resources(ticket_id)
    return [
        PSAResourceSchema(
            member_id=r.member_id,
            member_name=r.member_name,
            member_identifier=r.member_identifier,
            is_rf_user=r.member_id in mapped_ids,
        )
        for r in resources
    ]


async def add_resource(
    account_id: UUID, ticket_id: int, member_id: int, db: AsyncSession
) -> PSAResourceSchema:
    provider = await get_provider_for_account(account_id, db)
    mapped_ids = await _get_mapped_member_ids(account_id, db)
    resource = await provider.add_resource(ticket_id, member_id)
    return PSAResourceSchema(
        member_id=resource.member_id,
        member_name=resource.member_name,
        member_identifier=resource.member_identifier,
        is_rf_user=resource.member_id in mapped_ids,
    )


async def remove_resource(
    account_id: UUID, ticket_id: int, member_id: int, db: AsyncSession
) -> None:
    provider = await get_provider_for_account(account_id, db)
    await provider.remove_resource(ticket_id, member_id)


async def update_status(
    account_id: UUID, ticket_id: int, status_id: int, db: AsyncSession
) -> PSATicketStatusUpdateSchema:
    provider = await get_provider_for_account(account_id, db)
    # get current status before updating
    ticket = await provider.get_ticket(str(ticket_id))
    previous_status = ticket.status_name or ""
    await provider.update_ticket_status(str(ticket_id), status_id)
    # get new status name from statuses list
    statuses = await provider.get_ticket_statuses(ticket.board_id or 0)
    new_status = next((s.name for s in statuses if s.id == status_id), str(status_id))
    return PSATicketStatusUpdateSchema(
        ticket_id=ticket_id,
        previous_status=previous_status,
        new_status=new_status,
        new_status_id=status_id,
    )


async def create_ticket(
    account_id: UUID, payload: TicketCreatePayload, db: AsyncSession
) -> PSATicketCreatedSchema:
    provider = await get_provider_for_account(account_id, db)
    mapped_ids = await _get_mapped_member_ids(account_id, db)
    result = await provider.create_ticket(payload)
    return PSATicketCreatedSchema(
        id=result.id,
        summary=result.summary,
        board_name=result.board_name,
        status_name=result.status_name,
        priority_name=result.priority_name,
        company_name=result.company_name,
        resources=[
            PSAResourceSchema(
                member_id=r.member_id,
                member_name=r.member_name,
                member_identifier=r.member_identifier,
                is_rf_user=r.member_id in mapped_ids,
            )
            for r in result.resources
        ],
    )
