"""Custom exceptions for VibeDB with helpful error messages."""


class VibeDBError(Exception):
    """Base exception for all VibeDB errors."""

    def explain(self) -> str:
        """Return a human-readable explanation of the error with hints."""
        return str(self)


class ValidationError(VibeDBError):
    """Schema validation failed."""

    def __init__(self, field: str, constraint: str, value, message: str = None):
        self.field = field
        self.constraint = constraint
        self.value = value
        self.message = message or f"Validation failed for field '{field}'"
        super().__init__(self.message)

    def explain(self) -> str:
        """Provide detailed explanation of validation failure."""
        msg = f"Field '{self.field}' failed validation: {self.constraint}\n"
        msg += f"Value: {self.value}\n"
        msg += f"\nHint: Check your schema definition for the '{self.field}' field."
        return msg


class SlowQueryWarning(VibeDBError):
    """Query execution was slow and could benefit from optimization."""

    def __init__(self, query: dict, time_ms: float, threshold_ms: float, suggestions: list = None):
        self.query = query
        self.time_ms = time_ms
        self.threshold_ms = threshold_ms
        self.suggestions = suggestions or []
        super().__init__(f"Query took {time_ms}ms (threshold: {threshold_ms}ms)")

    def explain(self) -> str:
        """Provide detailed explanation with index suggestions."""
        msg = f"⚠️  Query took {self.time_ms:.1f}ms (threshold: {self.threshold_ms}ms)\n"
        msg += f"Query: {self.query}\n\n"

        if self.suggestions:
            msg += "💡 Suggestions to improve performance:\n"
            for suggestion in self.suggestions:
                fields = suggestion.get("fields", [])
                speedup = suggestion.get("estimated_speedup", "unknown")
                msg += f"  • Create index on {fields}\n"
                msg += f"    Expected speedup: {speedup}\n"
                msg += f"    Run: collection.create_index({fields})\n"
        else:
            msg += "No automatic suggestions available. Consider creating indexes on frequently queried fields.\n"

        return msg


class IndexError(VibeDBError):
    """Index operation failed."""

    def __init__(self, message: str, index_name: str = None):
        self.index_name = index_name
        super().__init__(message)

    def explain(self) -> str:
        """Provide detailed explanation of index error."""
        msg = str(self)
        if self.index_name:
            msg += f"\nIndex name: {self.index_name}"
        msg += "\n\nHint: Use collection.list_indexes() to see existing indexes."
        return msg


class QueryError(VibeDBError):
    """Query syntax or execution error."""

    def __init__(self, message: str, query: dict = None):
        self.query = query
        super().__init__(message)

    def explain(self) -> str:
        """Provide detailed explanation with query syntax help."""
        msg = f"❌ Query Error: {self}\n"

        if self.query:
            msg += f"\nQuery: {self.query}\n"

        msg += "\nHint: Check VibeDB query syntax documentation.\n"
        msg += "Common operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists\n"
        msg += "String ops: $prefix, $contains\n"
        msg += "Array ops: $has, $hasAny, $hasAll\n"
        msg += "\nOr use Q builder: Q.gte('age', 25) & Q.contains('email', '@example.com')"

        return msg


class DocumentNotFoundError(VibeDBError):
    """Document was not found."""

    def __init__(self, doc_id: str, collection: str = None):
        self.doc_id = doc_id
        self.collection = collection
        message = f"Document with _id '{doc_id}' not found"
        if collection:
            message += f" in collection '{collection}'"
        super().__init__(message)


class CollectionNotFoundError(VibeDBError):
    """Collection was not found."""

    def __init__(self, collection_name: str):
        self.collection_name = collection_name
        super().__init__(f"Collection '{collection_name}' not found")

    def explain(self) -> str:
        """Provide helpful message about collection creation."""
        msg = f"Collection '{self.collection_name}' does not exist.\n"
        msg += "\nHint: Collections are automatically created when you first access them:\n"
        msg += f"  collection = db.collection('{self.collection_name}')"
        return msg


class DatabaseError(VibeDBError):
    """General database operation error."""

    def __init__(self, message: str, original_error: Exception = None):
        self.original_error = original_error
        super().__init__(message)

    def explain(self) -> str:
        """Provide detailed explanation including original error."""
        msg = str(self)
        if self.original_error:
            msg += f"\n\nOriginal error: {type(self.original_error).__name__}: {self.original_error}"
        return msg
