"""Column definition utilities for database management."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any


@dataclass
class ColumnSpec:
    """Specification for database column definition."""

    name: str
    sql_type: str
    nullable: bool = True
    primary_key: bool = False
    unique: bool = False
    default_value: object = None
    description: str = ""

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary representation."""
        return {
            "name": self.name,
            "sql_type": self.sql_type,
            "nullable": self.nullable,
            "primary_key": self.primary_key,
            "unique": self.unique,
            "default_value": self.default_value,
            "description": self.description,
        }

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> ColumnSpec:
        """Create from dictionary."""
        return cls(
            name=data["name"],
            sql_type=data["sql_type"],
            nullable=data.get("nullable", True),
            primary_key=data.get("primary_key", False),
            unique=data.get("unique", False),
            default_value=data.get("default_value"),
            description=data.get("description", ""),
        )


class ColumnFactory:
    """Factory for creating standardized column definitions."""

    @staticmethod
    def create_id_column() -> ColumnSpec:
        """Create standard ID column."""
        return ColumnSpec(
            name="id",
            sql_type="INTEGER",
            nullable=False,
            primary_key=True,
            description="Primary key identifier",
        )

    @staticmethod
    def create_name_column(max_length: int = 255, *, unique: bool = False) -> ColumnSpec:
        """Create standard name column."""
        return ColumnSpec(
            name="name",
            sql_type=f"VARCHAR({max_length})",
            nullable=False,
            unique=unique,
            description="Entity name",
        )

    @staticmethod
    def create_description_column(max_length: int = 1000) -> ColumnSpec:
        """Create standard description column."""
        return ColumnSpec(
            name="description",
            sql_type=f"VARCHAR({max_length})",
            description="Description text",
        )

    @staticmethod
    def create_timestamp_columns() -> list[ColumnSpec]:
        """Create standard timestamp columns."""
        return [
            ColumnSpec(
                name="created_at",
                sql_type="DATETIME",
                nullable=False,
                default_value="CURRENT_TIMESTAMP",
                description="Creation timestamp",
            ),
            ColumnSpec(
                name="updated_at",
                sql_type="DATETIME",
                nullable=False,
                default_value="CURRENT_TIMESTAMP",
                description="Last update timestamp",
            ),
        ]

    @staticmethod
    def create_status_column(default_status: str = "active") -> ColumnSpec:
        """Create standard status column."""
        return ColumnSpec(
            name="status",
            sql_type="VARCHAR(50)",
            nullable=False,
            default_value=default_status,
            description="Entity status",
        )

    @staticmethod
    def create_version_column(default_version: str = "1.0.0") -> ColumnSpec:
        """Create standard version column."""
        return ColumnSpec(
            name="version",
            sql_type="VARCHAR(20)",
            nullable=False,
            default_value=default_version,
            description="Version identifier",
        )


# Predefined column sets for common entity types
PROJECT_COLUMNS = [
    ColumnFactory.create_id_column(),
    ColumnFactory.create_name_column(unique=True),
    ColumnFactory.create_description_column(),
    ColumnSpec("project_code", "VARCHAR(100)", unique=True, description="Project code"),
    ColumnSpec("category", "VARCHAR(100)", description="Project category"),
    ColumnFactory.create_status_column("active"),
    ColumnFactory.create_version_column(),
    *ColumnFactory.create_timestamp_columns(),
]

MATERIAL_COLUMNS = [
    ColumnFactory.create_id_column(),
    ColumnFactory.create_name_column(unique=True),
    ColumnFactory.create_description_column(),
    ColumnSpec("density", "FLOAT", description="Material density (kg/m³)"),
    ColumnSpec("young_modulus", "FLOAT", description="Young's modulus (Pa)"),
    ColumnSpec("poisson_ratio", "FLOAT", description="Poisson's ratio"),
    ColumnSpec("yield_strength", "FLOAT", description="Yield strength (Pa)"),
    ColumnSpec("category", "VARCHAR(100)", description="Material category"),
    ColumnFactory.create_status_column("active"),
    *ColumnFactory.create_timestamp_columns(),
]

SIMULATION_COLUMNS = [
    ColumnFactory.create_id_column(),
    ColumnFactory.create_name_column(),
    ColumnSpec("project_id", "INTEGER", nullable=False, description="Associated project ID"),
    ColumnSpec("analysis_type", "VARCHAR(50)", description="Type of analysis"),
    ColumnSpec("solver_type", "VARCHAR(50)", description="Solver used"),
    ColumnSpec(
        "status",
        "VARCHAR(50)",
        default_value="pending",
        description="Simulation status",
    ),
    ColumnSpec("start_time", "DATETIME", description="Simulation start time"),
    ColumnSpec("end_time", "DATETIME", description="Simulation end time"),
    ColumnSpec("result_path", "TEXT", description="Path to result files"),
    ColumnSpec("parameters", "TEXT", description="Simulation parameters (JSON)"),
    *ColumnFactory.create_timestamp_columns(),
]
