"""Agent CRUD operations for authentication."""

from __future__ import annotations

import hashlib

import asyncpg

from loom.auth.models import Agent, AgentRole


def _hash_key(api_key: str) -> str:
    """Hash an API key using SHA-256."""
    return hashlib.sha256(api_key.encode()).hexdigest()


async def create_agent(
    pool: asyncpg.Pool,
    name: str,
    role: str = "worker",
    api_key: str = "",
    project_ids: list[str] | None = None,
) -> Agent:
    """Create a new agent with hashed API key."""
    key_hash = _hash_key(api_key)
    async with pool.acquire() as conn:
        row = await conn.fetchrow(
            """
            INSERT INTO agents (name, role, api_key_hash, project_ids)
            VALUES ($1, $2, $3, $4)
            RETURNING *
            """,
            name, role, key_hash, project_ids or [],
        )
    return Agent(
        id=row["id"],
        name=row["name"],
        role=AgentRole(row["role"]),
        project_ids=list(row["project_ids"]) if row["project_ids"] else [],
        active=row["active"],
        last_seen_at=str(row["last_seen_at"]) if row["last_seen_at"] else None,
    )


async def authenticate(pool: asyncpg.Pool, api_key: str) -> Agent | None:
    """Authenticate by API key hash. Returns Agent or None."""
    key_hash = _hash_key(api_key)
    async with pool.acquire() as conn:
        row = await conn.fetchrow(
            """
            UPDATE agents SET last_seen_at = NOW()
            WHERE api_key_hash = $1 AND active = TRUE
            RETURNING *
            """,
            key_hash,
        )
    if row is None:
        return None
    return Agent(
        id=row["id"],
        name=row["name"],
        role=AgentRole(row["role"]),
        project_ids=list(row["project_ids"]) if row["project_ids"] else [],
        active=row["active"],
        last_seen_at=str(row["last_seen_at"]) if row["last_seen_at"] else None,
    )


async def list_agents(pool: asyncpg.Pool) -> list[Agent]:
    """List all active agents."""
    async with pool.acquire() as conn:
        rows = await conn.fetch(
            "SELECT * FROM agents WHERE active = TRUE ORDER BY created_at"
        )
    return [
        Agent(
            id=r["id"],
            name=r["name"],
            role=AgentRole(r["role"]),
            project_ids=list(r["project_ids"]) if r["project_ids"] else [],
            active=r["active"],
            last_seen_at=str(r["last_seen_at"]) if r["last_seen_at"] else None,
        )
        for r in rows
    ]


async def deactivate_agent(pool: asyncpg.Pool, agent_id: str) -> None:
    """Soft-delete an agent by setting active=False."""
    async with pool.acquire() as conn:
        await conn.execute(
            "UPDATE agents SET active = FALSE WHERE id = $1",
            agent_id,
        )
