"""Nexus — Platform & Node Repository (Async SQLAlchemy)"""

from typing import Optional, List
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from server.domain.models import Platform, Node


class PlatformRepositoryImpl:
    def __init__(self, session: AsyncSession):
        self.session = session

    async def get_by_id(self, id: int) -> Optional[Platform]:
        result = await self.session.execute(select(Platform).where(Platform.id == id))
        return result.scalar_one_or_none()

    async def get_all(self) -> List[Platform]:
        result = await self.session.execute(select(Platform).order_by(Platform.id))
        return list(result.scalars().all())

    async def get_by_type(self, platform_type: str) -> Optional[Platform]:
        result = await self.session.execute(select(Platform).where(Platform.type == platform_type))
        return result.scalar_one_or_none()

    async def create(self, platform: Platform) -> Platform:
        self.session.add(platform)
        await self.session.commit()
        return platform

    async def update(self, platform: Platform) -> Platform:
        await self.session.commit()
        return platform

    async def delete(self, id: int) -> bool:
        platform = await self.get_by_id(id)
        if platform:
            await self.session.delete(platform)
            await self.session.commit()
            return True
        return False


class NodeRepositoryImpl:
    def __init__(self, session: AsyncSession):
        self.session = session

    async def get_by_id(self, id: int) -> Optional[Node]:
        result = await self.session.execute(select(Node).where(Node.id == id))
        return result.scalar_one_or_none()

    async def get_all(self) -> List[Node]:
        result = await self.session.execute(select(Node).order_by(Node.sort_order, Node.id))
        return list(result.scalars().all())

    async def get_children(self, parent_id: int) -> List[Node]:
        result = await self.session.execute(
            select(Node).where(Node.parent_id == parent_id).order_by(Node.sort_order, Node.id)
        )
        return list(result.scalars().all())

    async def get_root_nodes(self) -> List[Node]:
        result = await self.session.execute(
            select(Node).where(Node.parent_id.is_(None)).order_by(Node.sort_order, Node.id)
        )
        return list(result.scalars().all())

    async def create(self, node: Node) -> Node:
        self.session.add(node)
        await self.session.commit()
        return node

    async def update(self, node: Node) -> Node:
        await self.session.commit()
        return node

    async def delete(self, id: int) -> bool:
        node = await self.get_by_id(id)
        if node:
            await self.session.delete(node)
            await self.session.commit()
            return True
        return False