"""
Database Operations Schemas

Pydantic models for WordPress database operations including:
- Database export/import
- Backup/restore
- Optimization and repair
- Search and query operations
"""

from typing import Any

from pydantic import BaseModel, Field, field_validator


class DatabaseExportParams(BaseModel):
    """Parameters for database export"""

    tables: list[str] | None = Field(
        default=None, description="Specific tables to export (default: all tables)"
    )
    exclude_tables: list[str] | None = Field(
        default=None, description="Tables to exclude from export"
    )
    add_drop_table: bool = Field(default=True, description="Include DROP TABLE statements")

    @classmethod
    @field_validator("tables", "exclude_tables")
    def validate_table_names(cls, v):
        """Validate table names - no special characters"""
        if v:
            for table in v:
                if not table.replace("_", "").isalnum():
                    raise ValueError(f"Invalid table name: {table}")
        return v


class DatabaseImportParams(BaseModel):
    """Parameters for database import"""

    file_path: str | None = Field(default=None, description="Path to SQL file on server")
    url: str | None = Field(default=None, description="URL to download SQL file from")
    skip_optimization: bool = Field(
        default=False, description="Skip database optimization after import"
    )

    @classmethod
    @field_validator("url")
    def validate_url(cls, v):
        """Validate URL format"""
        if v and not v.startswith(("http://", "https://")):
            raise ValueError("URL must start with http:// or https://")
        return v


class DatabaseBackupParams(BaseModel):
    """Parameters for creating database backup"""

    description: str | None = Field(
        default=None, max_length=255, description="Optional description for this backup"
    )
    compress: bool = Field(default=True, description="Compress backup with gzip")
    include_uploads: bool = Field(
        default=False, description="Also backup wp-content/uploads directory"
    )


class DatabaseRestoreParams(BaseModel):
    """Parameters for restoring database"""

    backup_id: str | None = Field(default=None, description="Backup ID to restore")
    timestamp: str | None = Field(
        default=None, description="Backup timestamp (alternative to backup_id)"
    )
    confirm: bool = Field(default=False, description="Confirmation required (safety check)")

    @classmethod
    @field_validator("confirm")
    def validate_confirmation(cls, v):
        """Require explicit confirmation for restore"""
        if not v:
            raise ValueError("Confirmation required: set confirm=true")
        return v


class DatabaseSearchParams(BaseModel):
    """Parameters for searching database"""

    search_string: str = Field(
        ..., min_length=1, max_length=255, description="String to search for in database"
    )
    tables: list[str] | None = Field(
        default=None, description="Specific tables to search (default: all tables)"
    )
    regex: bool = Field(default=False, description="Use regex pattern matching")
    case_sensitive: bool = Field(default=False, description="Case-sensitive search")
    max_results: int = Field(default=100, ge=1, le=1000, description="Maximum results to return")


class DatabaseQueryParams(BaseModel):
    """Parameters for executing SQL query"""

    query: str = Field(
        ..., min_length=1, max_length=10000, description="SQL query to execute (SELECT only)"
    )
    max_rows: int = Field(default=1000, ge=1, le=10000, description="Maximum rows to return")

    @classmethod
    @field_validator("query")
    def validate_query(cls, v):
        """
        Validate query is safe (read-only SELECT)

        Security: Only allow SELECT, SHOW, DESCRIBE statements
        Prevent: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, etc.
        """
        query_upper = v.strip().upper()

        # Allowed statement types
        allowed_starts = ("SELECT", "SHOW", "DESCRIBE", "DESC", "EXPLAIN")

        if not any(query_upper.startswith(cmd) for cmd in allowed_starts):
            raise ValueError("Only SELECT, SHOW, DESCRIBE, and EXPLAIN queries allowed")

        # Forbidden keywords (prevent nested destructive queries)
        forbidden = [
            "INSERT",
            "UPDATE",
            "DELETE",
            "DROP",
            "ALTER",
            "CREATE",
            "TRUNCATE",
            "REPLACE",
            "GRANT",
            "REVOKE",
        ]

        for keyword in forbidden:
            if keyword in query_upper:
                raise ValueError(f"Forbidden keyword in query: {keyword}")

        return v


class DatabaseSizeResponse(BaseModel):
    """Response model for database size information"""

    total_size_mb: float = Field(description="Total database size in MB")
    tables: list[dict[str, Any]] = Field(description="List of tables with size information")
    row_count: int = Field(description="Total row count across all tables")


class DatabaseTableInfo(BaseModel):
    """Information about a database table"""

    name: str
    engine: str
    rows: int
    data_size_mb: float
    index_size_mb: float
    total_size_mb: float
    collation: str


class DatabaseRepairResult(BaseModel):
    """Result of database repair operation"""

    table: str
    status: str  # 'OK', 'Repaired', 'Failed'
    message: str | None = None


class DatabaseBackupInfo(BaseModel):
    """Information about a database backup"""

    backup_id: str
    timestamp: str
    size_mb: float
    compressed: bool
    description: str | None = None
    location: str
    tables_count: int
