"""
Delete transformation layer tool for the AGS SPARQL Agent.

This tool removes a transformation layer and all associated steps
from the graphmart configuration.
"""

import os
import sys

# Add src directory to path for imports
src_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
if src_dir not in sys.path:
    sys.path.insert(0, src_dir)

from ..base_tool import BaseToolMixin, handle_tool_errors, ToolError
from ...utils.agent_utils import get_agent, get_graphmart_uri


@handle_tool_errors
async def delete_transformation_layer(
    layer_name_or_uri: str,
    graphmart_uri: str = None,
    explanation: str = None,
    dry_run: bool = False
) -> str:
    """Delete a transformation layer and all its steps.
    
    This tool removes a transformation layer and all associated steps
    (both transformation steps and direct load steps) from the graphmart configuration.
    
    Args:
        layer_name_or_uri: Layer name or full URI to delete
        graphmart_uri: URI of the graphmart (optional, auto-detects)
        explanation: Human-readable description of the operation
        dry_run: If true, validate inputs without executing
        
    Returns:
        JSON response with deletion results
    """
    BaseToolMixin.validate_required_param(layer_name_or_uri, "layer_name_or_uri")
    
    # Auto-detect graphmart URI if not provided
    graphmart_uri = get_graphmart_uri(graphmart_uri)
    
    agent = await get_agent()
    
    # Resolve layer URI from name if needed
    layer_uri = None
    layer_ordered_item_uri = None
    
    if layer_name_or_uri.startswith("http://"):
        layer_uri = layer_name_or_uri
        # Find the ordered item for this layer
        ordered_item_query = f"""
        PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
        PREFIX anzo: <http://openanzo.org/ontologies/2008/07/Anzo#>
        
        SELECT ?orderedItem WHERE {{
            GRAPH <{graphmart_uri}> {{
                <{graphmart_uri}> gm:layer ?orderedItem .
                ?orderedItem anzo:orderedValue <{layer_uri}> .
            }}
        }}
        """
        result = agent.anzo_client.query_journal(ordered_item_query)
        table_results = result.as_table_results().as_list()
        
        if not table_results or len(table_results) == 0:
            raise ToolError(f"Layer URI '{layer_uri}' not found in graphmart")
        
        layer_ordered_item_uri = table_results[0][0]
    else:
        # Find layer by name
        layer_lookup_query = f"""
        PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
        PREFIX anzo: <http://openanzo.org/ontologies/2008/07/Anzo#>
        PREFIX dc: <http://purl.org/dc/elements/1.1/>
        
        SELECT ?layer ?orderedItem WHERE {{
            GRAPH <{graphmart_uri}> {{
                <{graphmart_uri}> gm:layer ?orderedItem .
                ?orderedItem anzo:orderedValue ?layer .
                ?layer dc:title "{layer_name_or_uri}" .
            }}
        }}
        """
        lookup_result = agent.anzo_client.query_journal(layer_lookup_query)
        table_results = lookup_result.as_table_results().as_list()
        
        if not table_results or len(table_results) == 0:
            raise ToolError(f"Layer '{layer_name_or_uri}' not found in graphmart")
        
        layer_uri = table_results[0][0]
        layer_ordered_item_uri = table_results[0][1]
    
    # Get all steps in this layer for deletion
    steps_query = f"""
    PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
    PREFIX anzo: <http://openanzo.org/ontologies/2008/07/Anzo#>
    PREFIX dc: <http://purl.org/dc/elements/1.1/>
    
    SELECT ?step ?stepOrderedItem ?stepName WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{layer_uri}> gm:step ?stepOrderedItem .
            ?stepOrderedItem anzo:orderedValue ?step .
            OPTIONAL {{ ?step dc:title ?stepName }}
        }}
    }}
    """
    
    steps_result = agent.anzo_client.query_journal(steps_query)
    steps_table = steps_result.as_table_results().as_list()
    
    # Dry run mode
    if dry_run:
        step_info = []
        for step_row in steps_table:
            step_info.append({
                "step_uri": step_row[0],
                "step_ordered_item_uri": step_row[1],
                "step_name": step_row[2] if len(step_row) > 2 else "Unknown"
            })
        
        return BaseToolMixin.create_success_response({
            "dry_run": True,
            "layer_name_or_uri": layer_name_or_uri,
            "resolved_layer_uri": layer_uri,
            "layer_ordered_item_uri": layer_ordered_item_uri,
            "steps_to_delete": step_info,
            "graphmart_uri": graphmart_uri,
            "explanation": explanation
        }, f"Layer deletion validated. Would delete {len(steps_table)} steps. Set dry_run=false to execute.")
    
    # Build individual deletion statements for all steps and the layer
    delete_sparql_statements = []
    
    # Delete all steps first
    for step_row in steps_table:
        step_uri = step_row[0]
        step_ordered_item_uri = step_row[1]
        
        # Each operation as a separate statement
        delete_sparql_statements.append(f"""
        DELETE WHERE {{
            GRAPH <{graphmart_uri}> {{
                <{step_uri}> ?stepProp ?stepValue .
            }}
        }}""")
        
        delete_sparql_statements.append(f"""
        DELETE WHERE {{
            GRAPH <{graphmart_uri}> {{
                <{step_ordered_item_uri}> ?stepOrderedProp ?stepOrderedValue .
            }}
        }}""")
        
        delete_sparql_statements.append(f"""
        PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
        
        DELETE WHERE {{
            GRAPH <{graphmart_uri}> {{
                <{layer_uri}> gm:step <{step_ordered_item_uri}> .
            }}
        }}""")
    
    # Delete the layer itself
    delete_sparql_statements.append(f"""
    DELETE WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{layer_uri}> ?layerProp ?layerValue .
        }}
    }}""")
    
    delete_sparql_statements.append(f"""
    DELETE WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{layer_ordered_item_uri}> ?layerOrderedProp ?layerOrderedValue .
        }}
    }}""")
    
    delete_sparql_statements.append(f"""
    PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
    
    DELETE WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{graphmart_uri}> gm:layer <{layer_ordered_item_uri}> .
        }}
    }}""")
    
    # Execute all deletions
    for delete_sparql in delete_sparql_statements:
        if delete_sparql.strip():
            agent.anzo_client.update_journal(delete_sparql)
    
    return BaseToolMixin.create_success_response({
        "layer_name_or_uri": layer_name_or_uri,
        "deleted_layer_uri": layer_uri,
        "deleted_layer_ordered_item_uri": layer_ordered_item_uri,
        "deleted_steps_count": len(steps_table),
        "graphmart_uri": graphmart_uri,
        "explanation": explanation
    }, f"Successfully deleted transformation layer '{layer_name_or_uri}' and {len(steps_table)} steps")