"""ResolutionFlow system service account.

This module manages the platform-level service account used as the author
for system/default content (seeded trees, synced step library entries, etc.).

The service account ID is resolved once at startup and cached on app.state
so that sync operations can use it without a DB query per request.
"""
from __future__ import annotations

import uuid
import logging

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

from app.core.admin_database import _admin_session_factory

logger = logging.getLogger(__name__)

SERVICE_ACCOUNT_EMAIL = "noreply@resolutionflow.com"
SERVICE_ACCOUNT_NAME = "ResolutionFlow"

# Well-known UUID for the platform account — owns all default/global content.
# Created by migration 3a40fe11b427_create_global_content_tables.
PLATFORM_ACCOUNT_ID = uuid.UUID("00000000-0000-0000-0000-000000000001")
SYSTEM_ACCOUNT_NAME = "ResolutionFlow System"
SYSTEM_ACCOUNT_DISPLAY_CODE = "RF-SYS-1"


async def _ensure_system_account(db: AsyncSession) -> uuid.UUID:
    """Get or create the ResolutionFlow system account. Returns its ID."""
    from app.models.account import Account
    from sqlalchemy import text

    result = await db.execute(
        select(Account).where(Account.display_code == SYSTEM_ACCOUNT_DISPLAY_CODE)
    )
    account = result.scalar_one_or_none()
    if account is not None:
        return account.id

    new_account = Account(
        id=uuid.uuid4(),
        name=SYSTEM_ACCOUNT_NAME,
        display_code=SYSTEM_ACCOUNT_DISPLAY_CODE,
    )
    db.add(new_account)
    await db.flush()
    logger.info(f"[service_account] Created system account (id={new_account.id})")
    return new_account.id


async def ensure_service_account(db: AsyncSession) -> uuid.UUID:
    """Ensure the ResolutionFlow service account exists and return its ID.

    Idempotent — safe to call on every startup. This lookup must bypass RLS
    because startup runs before any request-scoped tenant context exists and
    the users table is tenant-isolated in Phase 4. The service account is
    normally created by Alembic migration 1490781700bc; the runtime create path
    remains as a self-healing fallback for environments that predate that seed.
    """
    _ = db  # Retained for call-site compatibility in app lifespan startup.

    from app.models.user import User

    async with _admin_session_factory() as admin_db:
        result = await admin_db.execute(
            select(User).where(User.email == SERVICE_ACCOUNT_EMAIL)
        )
        user = result.scalar_one_or_none()

        if user is not None:
            if not user.is_service_account:
                user.is_service_account = True
                await admin_db.commit()
            return user.id

        account_id = await _ensure_system_account(admin_db)

        new_user = User(
            id=uuid.uuid4(),
            email=SERVICE_ACCOUNT_EMAIL,
            name=SERVICE_ACCOUNT_NAME,
            password_hash="!service-account-no-login",  # bcrypt can't produce this prefix
            role="engineer",
            is_super_admin=False,
            is_team_admin=False,
            is_active=True,
            is_service_account=True,
            must_change_password=False,
            account_id=account_id,
            account_role="engineer",
        )
        admin_db.add(new_user)
        await admin_db.commit()
        logger.info(f"[service_account] Created service account (id={new_user.id})")
        return new_user.id
