"""Test factories for BA-managed and domain entities.

Use for unit tests that construct entities in memory. Integration tests can
insert these into a real DB via the standard session.add(...) pattern.
"""

import uuid
from datetime import UTC, datetime
from typing import Any

from app.models.auth_mirror import Member, Organization, Team, TeamMember
from app.models.restaurant import Restaurant
from app.models.user import User


def _now() -> datetime:
    return datetime.now(UTC)


def make_user(
    *,
    email: str = "test@dineo.dev",
    name: str = "Test User",
    id: str | None = None,
) -> User:
    return User(
        id=id or uuid.uuid4().hex,
        name=name,
        email=email,
        email_verified=True,
        image=None,
        created_at=_now(),
        updated_at=_now(),
    )


def make_org(
    *,
    name: str = "Test Org",
    slug: str = "test-org",
    id: str | None = None,
) -> Organization:
    return Organization(
        id=id or uuid.uuid4().hex,
        name=name,
        slug=slug,
        logo=None,
        metadata_={"plan": "free"},
        created_at=_now(),
    )


def make_member(
    *,
    user_id: str,
    organization_id: str,
    role: str = "owner",
    id: str | None = None,
) -> Member:
    return Member(
        id=id or uuid.uuid4().hex,
        user_id=user_id,
        organization_id=organization_id,
        role=role,
        created_at=_now(),
    )


def make_team(*, organization_id: str, name: str = "Test Team", id: str | None = None) -> Team:
    return Team(
        id=id or uuid.uuid4().hex,
        name=name,
        organization_id=organization_id,
        created_at=_now(),
        updated_at=_now(),
    )


def make_team_member(*, team_id: str, user_id: str, id: str | None = None) -> TeamMember:
    return TeamMember(
        id=id or uuid.uuid4().hex,
        team_id=team_id,
        user_id=user_id,
        created_at=_now(),
    )


def make_restaurant(
    *,
    team_id: str,
    name: str = "Test Restaurant",
    slug: str | None = None,
    settings: dict[str, Any] | None = None,
    id: str | None = None,
    phone: str | None = None,
    timezone: str = "Europe/Brussels",
) -> Restaurant:
    return Restaurant(
        id=id or uuid.uuid4().hex,
        name=name,
        slug=slug or f"slug-{uuid.uuid4().hex[:8]}",
        phone=phone,
        timezone=timezone,
        team_id=team_id,
        settings=settings or {},
    )
