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

from typing import Sequence
from uuid import UUID

from sqlalchemy import select

from app.models.members import (
    DigitalMembership,
    EmergencyContact,
    FamilyMember,
    MedicalInformation,
    Member,
    MemberDocument,
    MembershipCard,
    Waiver,
)
from app.repositories.base import TenantBaseRepository


class MemberRepository(TenantBaseRepository[Member]):
    model = Member

    async def get_by_member_number(
        self, tenant_id: UUID, member_number: str
    ) -> Member | None:
        stmt = select(Member).where(
            Member.tenant_id == tenant_id,
            Member.member_number == member_number,
            Member.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_center(
        self, tenant_id: UUID, sports_center_id: UUID, *, offset: int = 0, limit: int = 20
    ) -> Sequence[Member]:
        stmt = (
            select(Member)
            .where(
                Member.tenant_id == tenant_id,
                Member.sports_center_id == sports_center_id,
                Member.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class FamilyMemberRepository(TenantBaseRepository[FamilyMember]):
    model = FamilyMember

    async def list_by_member(
        self, tenant_id: UUID, member_id: UUID, *, offset: int = 0, limit: int = 50
    ) -> Sequence[FamilyMember]:
        stmt = (
            select(FamilyMember)
            .where(
                FamilyMember.tenant_id == tenant_id,
                FamilyMember.member_id == member_id,
                FamilyMember.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class EmergencyContactRepository(TenantBaseRepository[EmergencyContact]):
    model = EmergencyContact

    async def list_by_member(
        self, tenant_id: UUID, member_id: UUID, *, offset: int = 0, limit: int = 50
    ) -> Sequence[EmergencyContact]:
        stmt = (
            select(EmergencyContact)
            .where(
                EmergencyContact.tenant_id == tenant_id,
                EmergencyContact.member_id == member_id,
                EmergencyContact.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class MedicalInformationRepository(TenantBaseRepository[MedicalInformation]):
    model = MedicalInformation

    async def get_by_member(
        self, tenant_id: UUID, member_id: UUID
    ) -> MedicalInformation | None:
        stmt = select(MedicalInformation).where(
            MedicalInformation.tenant_id == tenant_id,
            MedicalInformation.member_id == member_id,
            MedicalInformation.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class MembershipCardRepository(TenantBaseRepository[MembershipCard]):
    model = MembershipCard

    async def get_by_card_number(
        self, tenant_id: UUID, card_number: str
    ) -> MembershipCard | None:
        stmt = select(MembershipCard).where(
            MembershipCard.tenant_id == tenant_id,
            MembershipCard.card_number == card_number,
            MembershipCard.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_member(
        self, tenant_id: UUID, member_id: UUID, *, offset: int = 0, limit: int = 50
    ) -> Sequence[MembershipCard]:
        stmt = (
            select(MembershipCard)
            .where(
                MembershipCard.tenant_id == tenant_id,
                MembershipCard.member_id == member_id,
                MembershipCard.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class DigitalMembershipRepository(TenantBaseRepository[DigitalMembership]):
    model = DigitalMembership

    async def get_by_pass_code(
        self, tenant_id: UUID, pass_code: str
    ) -> DigitalMembership | None:
        stmt = select(DigitalMembership).where(
            DigitalMembership.tenant_id == tenant_id,
            DigitalMembership.pass_code == pass_code,
            DigitalMembership.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_member(
        self, tenant_id: UUID, member_id: UUID, *, offset: int = 0, limit: int = 50
    ) -> Sequence[DigitalMembership]:
        stmt = (
            select(DigitalMembership)
            .where(
                DigitalMembership.tenant_id == tenant_id,
                DigitalMembership.member_id == member_id,
                DigitalMembership.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class WaiverRepository(TenantBaseRepository[Waiver]):
    model = Waiver

    async def list_by_member(
        self, tenant_id: UUID, member_id: UUID, *, offset: int = 0, limit: int = 50
    ) -> Sequence[Waiver]:
        stmt = (
            select(Waiver)
            .where(
                Waiver.tenant_id == tenant_id,
                Waiver.member_id == member_id,
                Waiver.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class MemberDocumentRepository(TenantBaseRepository[MemberDocument]):
    model = MemberDocument

    async def list_by_member(
        self, tenant_id: UUID, member_id: UUID, *, offset: int = 0, limit: int = 50
    ) -> Sequence[MemberDocument]:
        stmt = (
            select(MemberDocument)
            .where(
                MemberDocument.tenant_id == tenant_id,
                MemberDocument.member_id == member_id,
                MemberDocument.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()
