from __future__ import annotations
from datetime import datetime, timezone
from typing import Optional
from uuid import UUID
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from src.domain.domains.models import WorkspaceDomain, DomainAssignment, DomainEvent


class DomainRepository:
    def __init__(self, db: AsyncSession): self.db = db

    async def get(self, domain_id: UUID, workspace_id: UUID) -> Optional[WorkspaceDomain]:
        r = await self.db.execute(select(WorkspaceDomain).where(WorkspaceDomain.id == domain_id, WorkspaceDomain.workspace_id == workspace_id))
        return r.scalar_one_or_none()

    async def get_by_name(self, normalized: str) -> Optional[WorkspaceDomain]:
        r = await self.db.execute(select(WorkspaceDomain).where(WorkspaceDomain.normalized_domain == normalized))
        return r.scalar_one_or_none()

    async def list(self, workspace_id: UUID) -> list[WorkspaceDomain]:
        r = await self.db.execute(select(WorkspaceDomain).where(WorkspaceDomain.workspace_id == workspace_id).order_by(WorkspaceDomain.domain_name))
        return list(r.scalars().all())

    async def assignments(self, domain_id: UUID) -> list[DomainAssignment]:
        r = await self.db.execute(select(DomainAssignment).where(DomainAssignment.domain_id == domain_id).order_by(DomainAssignment.hostname))
        return list(r.scalars().all())

    async def active_hostname(self, hostname: str) -> Optional[DomainAssignment]:
        r = await self.db.execute(select(DomainAssignment).where(DomainAssignment.hostname == hostname, DomainAssignment.assignment_status.in_(("pending", "active"))))
        return r.scalar_one_or_none()

    async def add_event(self, workspace_id: UUID, event_type: str, actor_id: UUID, domain_id: Optional[UUID], payload: dict) -> None:
        self.db.add(DomainEvent(workspace_id=workspace_id, domain_id=domain_id, event_type=event_type, actor_id=actor_id, payload_json=payload))
