"""Member Management APIs — Phase 9.2."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, 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.schemas.members import (
    DigitalMembershipCreate,
    DigitalMembershipRead,
    DigitalMembershipUpdate,
    EmergencyContactCreate,
    EmergencyContactRead,
    EmergencyContactUpdate,
    FamilyMemberCreate,
    FamilyMemberRead,
    FamilyMemberUpdate,
    MedicalInformationRead,
    MedicalInformationUpsert,
    MemberCreate,
    MemberDocumentCreate,
    MemberDocumentRead,
    MemberDocumentUpdate,
    MembershipCardCreate,
    MembershipCardRead,
    MembershipCardUpdate,
    MemberRead,
    MemberUpdate,
    WaiverCreate,
    WaiverRead,
    WaiverSignRequest,
    WaiverUpdate,
)
from app.services.members import (
    DigitalMembershipService,
    EmergencyContactService,
    FamilyMemberService,
    MedicalInformationService,
    MemberDocumentService,
    MembershipCardService,
    MemberService,
    WaiverService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

members_router = APIRouter()
family_members_router = APIRouter()
emergency_contacts_router = APIRouter()
medical_router = APIRouter()
cards_router = APIRouter()
digital_router = APIRouter()
waivers_router = APIRouter()
documents_router = APIRouter()


@members_router.post("", response_model=MemberRead, status_code=status.HTTP_201_CREATED)
async def create_member(
    body: MemberCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MemberService(db).create(tenant_id, body, actor=user)


@members_router.get("", response_model=list[MemberRead])
async def list_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 MemberService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)


@members_router.get("/{member_id}", response_model=MemberRead)
async def get_member(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MemberService(db).get(tenant_id, member_id)


@members_router.patch("/{member_id}", response_model=MemberRead)
async def update_member(
    member_id: UUID,
    body: MemberUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MemberService(db).update(tenant_id, member_id, body, actor=user)


@members_router.post("/{member_id}/delete", response_model=MemberRead)
async def delete_member(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MemberService(db).soft_delete(tenant_id, member_id, actor=user)


@family_members_router.post("", response_model=FamilyMemberRead, status_code=status.HTTP_201_CREATED)
async def create_family_member(
    body: FamilyMemberCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await FamilyMemberService(db).create(tenant_id, body, actor=user)


@family_members_router.get("", response_model=list[FamilyMemberRead])
async def list_family_members(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await FamilyMemberService(db).list_by_member(
        tenant_id, member_id, offset=pagination.offset, limit=pagination.page_size
    )


@family_members_router.get("/{family_member_id}", response_model=FamilyMemberRead)
async def get_family_member(
    family_member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await FamilyMemberService(db).get(tenant_id, family_member_id)


@family_members_router.patch("/{family_member_id}", response_model=FamilyMemberRead)
async def update_family_member(
    family_member_id: UUID,
    body: FamilyMemberUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await FamilyMemberService(db).update(tenant_id, family_member_id, body, actor=user)


@family_members_router.post("/{family_member_id}/delete", response_model=FamilyMemberRead)
async def delete_family_member(
    family_member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await FamilyMemberService(db).soft_delete(tenant_id, family_member_id, actor=user)


@emergency_contacts_router.post("", response_model=EmergencyContactRead, status_code=status.HTTP_201_CREATED)
async def create_emergency_contact(
    body: EmergencyContactCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await EmergencyContactService(db).create(tenant_id, body, actor=user)


@emergency_contacts_router.get("", response_model=list[EmergencyContactRead])
async def list_emergency_contacts(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await EmergencyContactService(db).list_by_member(
        tenant_id, member_id, offset=pagination.offset, limit=pagination.page_size
    )


@emergency_contacts_router.get("/{contact_id}", response_model=EmergencyContactRead)
async def get_emergency_contact(
    contact_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await EmergencyContactService(db).get(tenant_id, contact_id)


@emergency_contacts_router.patch("/{contact_id}", response_model=EmergencyContactRead)
async def update_emergency_contact(
    contact_id: UUID,
    body: EmergencyContactUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await EmergencyContactService(db).update(tenant_id, contact_id, body, actor=user)


@emergency_contacts_router.post("/{contact_id}/delete", response_model=EmergencyContactRead)
async def delete_emergency_contact(
    contact_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await EmergencyContactService(db).soft_delete(tenant_id, contact_id, actor=user)


@medical_router.put("", response_model=MedicalInformationRead)
async def upsert_medical(
    body: MedicalInformationUpsert,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MedicalInformationService(db).upsert(tenant_id, body, actor=user)


@medical_router.get("/by-member/{member_id}", response_model=MedicalInformationRead)
async def get_medical(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MedicalInformationService(db).get_by_member(tenant_id, member_id)


@cards_router.post("", response_model=MembershipCardRead, status_code=status.HTTP_201_CREATED)
async def issue_card(
    body: MembershipCardCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MembershipCardService(db).create(tenant_id, body, actor=user)


@cards_router.get("", response_model=list[MembershipCardRead])
async def list_cards(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MembershipCardService(db).list_by_member(
        tenant_id, member_id, offset=pagination.offset, limit=pagination.page_size
    )


@cards_router.get("/{card_id}", response_model=MembershipCardRead)
async def get_card(
    card_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MembershipCardService(db).get(tenant_id, card_id)


@cards_router.patch("/{card_id}", response_model=MembershipCardRead)
async def update_card(
    card_id: UUID,
    body: MembershipCardUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MembershipCardService(db).update(tenant_id, card_id, body, actor=user)


@cards_router.post("/{card_id}/revoke", response_model=MembershipCardRead)
async def revoke_card(
    card_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MembershipCardService(db).revoke(tenant_id, card_id, actor=user)


@digital_router.post("", response_model=DigitalMembershipRead, status_code=status.HTTP_201_CREATED)
async def issue_digital(
    body: DigitalMembershipCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await DigitalMembershipService(db).create(tenant_id, body, actor=user)


@digital_router.get("", response_model=list[DigitalMembershipRead])
async def list_digital(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await DigitalMembershipService(db).list_by_member(
        tenant_id, member_id, offset=pagination.offset, limit=pagination.page_size
    )


@digital_router.get("/{digital_id}", response_model=DigitalMembershipRead)
async def get_digital(
    digital_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await DigitalMembershipService(db).get(tenant_id, digital_id)


@digital_router.patch("/{digital_id}", response_model=DigitalMembershipRead)
async def update_digital(
    digital_id: UUID,
    body: DigitalMembershipUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await DigitalMembershipService(db).update(tenant_id, digital_id, body, actor=user)


@waivers_router.post("", response_model=WaiverRead, status_code=status.HTTP_201_CREATED)
async def create_waiver(
    body: WaiverCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await WaiverService(db).create(tenant_id, body, actor=user)


@waivers_router.get("", response_model=list[WaiverRead])
async def list_waivers(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await WaiverService(db).list_by_member(
        tenant_id, member_id, offset=pagination.offset, limit=pagination.page_size
    )


@waivers_router.get("/{waiver_id}", response_model=WaiverRead)
async def get_waiver(
    waiver_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await WaiverService(db).get(tenant_id, waiver_id)


@waivers_router.patch("/{waiver_id}", response_model=WaiverRead)
async def update_waiver(
    waiver_id: UUID,
    body: WaiverUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await WaiverService(db).update(tenant_id, waiver_id, body, actor=user)


@waivers_router.post("/{waiver_id}/sign", response_model=WaiverRead)
async def sign_waiver(
    waiver_id: UUID,
    body: WaiverSignRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await WaiverService(db).sign(tenant_id, waiver_id, body, actor=user)


@documents_router.post("", response_model=MemberDocumentRead, status_code=status.HTTP_201_CREATED)
async def attach_document(
    body: MemberDocumentCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MemberDocumentService(db).create(tenant_id, body, actor=user)


@documents_router.get("", response_model=list[MemberDocumentRead])
async def list_documents(
    member_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MemberDocumentService(db).list_by_member(
        tenant_id, member_id, offset=pagination.offset, limit=pagination.page_size
    )


@documents_router.get("/{document_id}", response_model=MemberDocumentRead)
async def get_document(
    document_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MemberDocumentService(db).get(tenant_id, document_id)


@documents_router.patch("/{document_id}", response_model=MemberDocumentRead)
async def update_document(
    document_id: UUID,
    body: MemberDocumentUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MemberDocumentService(db).update(tenant_id, document_id, body, actor=user)


@documents_router.post("/{document_id}/delete", response_model=MemberDocumentRead)
async def delete_document(
    document_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MemberDocumentService(db).soft_delete(tenant_id, document_id, actor=user)
