"""Adapter for formatting restructuring recommendations as SQL."""
from typing import Dict, Any, List, Optional
import os

from .base import BaseDataModelAdapter, register_model_adapter

@register_model_adapter
class SqlAdapter(BaseDataModelAdapter):
    """Adapter for formatting restructuring recommendations as SQL."""
    
    def format_recommendations(self, recommendations: List[Dict[str, Any]], metadata: Dict[str, Any], **kwargs) -> str:
        """
        Format restructuring recommendations as SQL statements.
        
        Args:
            recommendations: List of restructuring recommendations
            metadata: Metadata dictionary
            **kwargs: Additional parameters
            
        Returns:
            SQL statements as a string
        """
        # Sort recommendations by type and severity
        severity_order = {"high": 0, "medium": 1, "low": 2}
        sorted_recommendations = sorted(
            recommendations, 
            key=lambda x: (x.get("type", ""), severity_order.get(x.get("severity", "low"), 3))
        )
        
        # Group recommendations by type
        grouped: Dict[str, List[Dict[str, Any]]] = {}
        for rec in sorted_recommendations:
            rec_type = rec.get("type", "other")
            if rec_type not in grouped:
                grouped[rec_type] = []
            grouped[rec_type].append(rec)
        
        # Build SQL script
        sql_lines = [
            "-- SQL Script for Database Restructuring",
            "-- Generated by csvdiffgpt",
            f"-- Original file: {os.path.basename(kwargs.get('file_path', 'data.csv'))}",
            f"-- Total recommendations: {len(recommendations)}",
            "",
            "-- IMPORTANT: Review and modify this script before execution",
            "-- All table names should be replaced with your actual table names",
            "-- Tables are referred to as 'your_table' by default",
            ""
        ]
        
        # Add table creation statement based on current structure
        sql_lines.append(self._generate_table_creation(metadata, kwargs.get('table_name', 'your_table')))
        sql_lines.append("")
        
        # Add recommendations grouped by type
        for group_type, group_recs in grouped.items():
            sql_lines.append(f"-- {group_type.upper()} CHANGES")
            sql_lines.append("-- " + "=" * 50)
            sql_lines.append("")
            
            for i, rec in enumerate(group_recs):
                # Add recommendation header
                sql_lines.append(f"-- Recommendation {i+1}: {rec.get('description', '')}")
                sql_lines.append(f"-- Severity: {rec.get('severity', 'low')}")
                sql_lines.append("")
                
                # Add the SQL code from the recommendation
                sql_code = rec.get("sql_code", "-- No SQL code provided for this recommendation")
                sql_lines.append(sql_code)
                
                # Add separator between recommendations
                sql_lines.append("")
                sql_lines.append("-- " + "-" * 50)
                sql_lines.append("")
        
        return "\n".join(sql_lines)
    
    def _generate_table_creation(self, metadata: Dict[str, Any], table_name: str) -> str:
        """
        Generate a CREATE TABLE statement based on the current structure.
        
        Args:
            metadata: Metadata dictionary
            table_name: Name for the table
            
        Returns:
            CREATE TABLE statement as a string
        """
        lines = [
            f"-- Current table structure",
            f"CREATE TABLE {table_name} ("
        ]
        
        # Process columns
        for i, (col_name, col_info) in enumerate(metadata.get("columns", {}).items()):
            col_type = col_info.get("type", "")
            
            # Map pandas dtype to SQL type
            sql_type = "VARCHAR(255)"  # Default
            if "int" in col_type:
                sql_type = "INTEGER"
            elif "float" in col_type:
                sql_type = "NUMERIC"
            elif "bool" in col_type:
                sql_type = "BOOLEAN"
            elif "datetime" in col_type:
                sql_type = "TIMESTAMP"
            elif "date" in col_type:
                sql_type = "DATE"
            elif col_type == "object" or "string" in col_type:
                # Adjust VARCHAR length based on max length if available
                if "max_length" in col_info:
                    # Add some buffer to the max length
                    max_len = int(col_info["max_length"] * 1.5) + 10
                    max_len = min(max_len, 4000)  # Cap at 4000 chars
                    sql_type = f"VARCHAR({max_len})"
            
            # Add NULL constraint if the column has no nulls
            nullability = "NOT NULL" if col_info.get("nulls", 1) == 0 else ""
            
            # Add comma for all but the last column
            comma = "," if i < len(metadata.get("columns", {}).items()) - 1 else ""
            
            lines.append(f"    {col_name} {sql_type} {nullability}{comma}")
        
        lines.append(");")
        
        return "\n".join(lines)