"""
Version History - Manages version and branch records in the database.

Provides the VersionHistory class for creating versions, querying history,
and managing branches. Requires a database session.
"""

from __future__ import annotations

import uuid
from typing import Any

from pycharter.wiki.shared.errors import VersioningError
from pycharter.wiki.versioning.models import BranchInfo, VersionInfo


class VersionHistory:
    """
    Manages version history for ontology artifacts.

    Uses a database session to create and query versions and branches.

    Args:
        session: SQLAlchemy session
    """

    def __init__(self, session=None):
        self._session = session

    def get_version(self, version_id: str) -> VersionInfo | None:
        """
        Get a specific version by ID.

        Args:
            version_id: UUID of the version

        Returns:
            VersionInfo or None if not found
        """
        if self._session is None:
            raise VersioningError("No database session configured")

        from pycharter.db.models.wiki.contract_version import ContractVersionModel

        row = (
            self._session.query(ContractVersionModel)
            .filter(ContractVersionModel.id == uuid.UUID(version_id))
            .first()
        )
        if row is None:
            return None
        return VersionInfo(
            version_id=str(row.id),
            contract_id=row.contract_id,
            parent_id=str(row.parent_id) if row.parent_id else None,
            message=row.message,
            author=row.author,
            created_at=str(row.created_at) if row.created_at else None,
        )

    def get_latest(
        self, contract_id: str, branch: str | None = None
    ) -> VersionInfo | None:
        """
        Get the latest version for a contract.

        Args:
            contract_id: Contract identifier
            branch: Optional branch name to filter by

        Returns:
            VersionInfo or None if no versions exist
        """
        if self._session is None:
            raise VersioningError("No database session configured")

        from pycharter.db.models.wiki.contract_version import ContractVersionModel

        query = (
            self._session.query(ContractVersionModel)
            .filter(ContractVersionModel.contract_id == contract_id)
            .order_by(ContractVersionModel.created_at.desc())
        )
        row = query.first()
        if row is None:
            return None
        return VersionInfo(
            version_id=str(row.id),
            contract_id=row.contract_id,
            parent_id=str(row.parent_id) if row.parent_id else None,
            message=row.message,
            author=row.author,
            created_at=str(row.created_at) if row.created_at else None,
        )

    def get_history(
        self,
        contract_id: str,
        branch: str | None = None,
        limit: int = 50,
    ) -> list[VersionInfo]:
        """
        Get version history for a contract.

        Args:
            contract_id: Contract identifier
            branch: Optional branch name to filter by
            limit: Max number of versions to return

        Returns:
            List of VersionInfo, newest first
        """
        if self._session is None:
            raise VersioningError("No database session configured")

        from pycharter.db.models.wiki.contract_version import ContractVersionModel

        query = (
            self._session.query(ContractVersionModel)
            .filter(ContractVersionModel.contract_id == contract_id)
            .order_by(ContractVersionModel.created_at.desc())
            .limit(limit)
        )
        return [
            VersionInfo(
                version_id=str(row.id),
                contract_id=row.contract_id,
                parent_id=str(row.parent_id) if row.parent_id else None,
                message=row.message,
                author=row.author,
                created_at=str(row.created_at) if row.created_at else None,
            )
            for row in query.all()
        ]

    def create_version(
        self,
        contract_id: str,
        content: dict[str, Any],
        message: str,
        author: str,
        parent_id: str | None = None,
        branch_id: str | None = None,
    ) -> str:
        """
        Create a new version.

        Args:
            contract_id: Contract identifier
            content: Ontology content as dict (stored as JSONB)
            message: Version message
            author: Author name
            parent_id: Parent version UUID (optional)
            branch_id: Branch UUID (optional)

        Returns:
            UUID string of the created version
        """
        if self._session is None:
            raise VersioningError("No database session configured")

        from pycharter.db.models.wiki.contract_version import ContractVersionModel

        version = ContractVersionModel(
            contract_id=contract_id,
            content=content,
            message=message,
            author=author,
            parent_id=uuid.UUID(parent_id) if parent_id else None,
            branch_id=uuid.UUID(branch_id) if branch_id else None,
            created_by=author,
        )
        self._session.add(version)
        self._session.flush()
        return str(version.id)

    def list_branches(self, contract_id: str) -> list[BranchInfo]:
        """
        List all branches for a contract.

        Args:
            contract_id: Contract identifier

        Returns:
            List of BranchInfo
        """
        if self._session is None:
            raise VersioningError("No database session configured")

        from pycharter.db.models.wiki.branch import BranchModel

        rows = (
            self._session.query(BranchModel)
            .filter(BranchModel.contract_id == contract_id)
            .all()
        )
        return [
            BranchInfo(
                branch_id=str(row.id),
                contract_id=row.contract_id,
                name=row.name,
                base_version_id=(
                    str(row.base_version_id) if row.base_version_id else None
                ),
                status=row.status,
                created_at=str(row.created_at) if row.created_at else None,
                created_by=row.created_by,
            )
            for row in rows
        ]

    def create_branch(
        self,
        contract_id: str,
        name: str,
        base_version_id: str | None = None,
        created_by: str | None = None,
    ) -> str:
        """
        Create a new branch.

        Args:
            contract_id: Contract identifier
            name: Branch name
            base_version_id: Version to branch from (optional)
            created_by: Branch creator

        Returns:
            UUID string of the created branch
        """
        if self._session is None:
            raise VersioningError("No database session configured")

        from pycharter.db.models.wiki.branch import BranchModel

        branch = BranchModel(
            contract_id=contract_id,
            name=name,
            base_version_id=uuid.UUID(base_version_id) if base_version_id else None,
            created_by=created_by,
        )
        self._session.add(branch)
        self._session.flush()
        return str(branch.id)
