import logging
from typing import Optional, Callable
from datetime import datetime

logger = logging.getLogger(__name__)


class Migration:
    """Represents a database migration."""

    def __init__(
        self,
        version: str,
        name: str,
        up: Optional[Callable] = None,
        down: Optional[Callable] = None,
    ):
        """
        Initialize a migration.

        Args:
            version: Migration version (timestamp or sequential number)
            name: Descriptive name of the migration
            up: Function to apply the migration
            down: Function to rollback the migration
        """
        self.version = version
        self.name = name
        self.up = up
        self.down = down
        self.applied_at: Optional[datetime] = None

    def apply(self, db) -> None:
        """Apply the migration."""
        if self.up is None:
            raise ValueError(f"Migration {self.version}_{self.name} has no up function")

        logger.info(f"Applying migration: {self.version}_{self.name}")
        self.up(db)
        self.applied_at = datetime.now()

    def rollback(self, db) -> None:
        """Rollback the migration."""
        if self.down is None:
            raise ValueError(
                f"Migration {self.version}_{self.name} has no down function"
            )

        logger.info(f"Rolling back migration: {self.version}_{self.name}")
        self.down(db)
        self.applied_at = None

    def __repr__(self) -> str:
        status = "applied" if self.applied_at else "pending"
        return f"<Migration {self.version}_{self.name} ({status})>"

    def __lt__(self, other: "Migration") -> bool:
        """Compare migrations by version for sorting."""
        return self.version < other.version
