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

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_step(
    step_name_or_uri: str,
    layer_name_or_uri: str = None,
    graphmart_uri: str = None,
    explanation: str = None,
    dry_run: bool = False
) -> str:
    """Delete a transformation step or direct load step.
    
    This tool removes any type of step (transformation or direct load) from its layer.
    Works for both SPARQL transformation steps and direct JSON file loading steps.
    
    Args:
        step_name_or_uri: Step name or full URI to delete
        layer_name_or_uri: Layer name or URI (optional, helps with lookup)
        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(step_name_or_uri, "step_name_or_uri")
    
    # Auto-detect graphmart URI if not provided
    graphmart_uri = get_graphmart_uri(graphmart_uri)
    
    agent = await get_agent()
    
    # Resolve step URI from name if needed
    step_uri = None
    step_ordered_item_uri = None
    parent_layer_uri = None
    
    if step_name_or_uri.startswith("http://"):
        step_uri = step_name_or_uri
        # Find the ordered item and parent layer for this step
        step_lookup_query = f"""
        PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
        PREFIX anzo: <http://openanzo.org/ontologies/2008/07/Anzo#>
        
        SELECT ?orderedItem ?layer WHERE {{
            GRAPH <{graphmart_uri}> {{
                ?layer gm:step ?orderedItem .
                ?orderedItem anzo:orderedValue <{step_uri}> .
            }}
        }}
        """
    else:
        # Find step by name, optionally within a specific layer
        if layer_name_or_uri:
            # Resolve layer URI first if provided
            layer_uri = None
            if layer_name_or_uri.startswith("http://"):
                layer_uri = layer_name_or_uri
            else:
                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 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]
            
            # Find step by name within the specific layer
            step_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 ?step ?orderedItem ?layer WHERE {{
                GRAPH <{graphmart_uri}> {{
                    <{layer_uri}> gm:step ?orderedItem .
                    ?orderedItem anzo:orderedValue ?step .
                    ?step dc:title "{step_name_or_uri}" .
                    BIND(<{layer_uri}> AS ?layer)
                }}
            }}
            """
        else:
            # Find step by name across all layers
            step_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 ?step ?orderedItem ?layer WHERE {{
                GRAPH <{graphmart_uri}> {{
                    ?layer gm:step ?orderedItem .
                    ?orderedItem anzo:orderedValue ?step .
                    ?step dc:title "{step_name_or_uri}" .
                }}
            }}
            """
    
    lookup_result = agent.anzo_client.query_journal(step_lookup_query)
    table_results = lookup_result.as_table_results().as_list()
    
    if not table_results or len(table_results) == 0:
        raise ToolError(f"Step '{step_name_or_uri}' not found in graphmart")
    
    if len(table_results) > 1:
        layer_names = []
        for result in table_results:
            layer_names.append(result[2] if len(result) > 2 else "Unknown")
        raise ToolError(f"Multiple steps named '{step_name_or_uri}' found in layers: {layer_names}. Please specify layer_name_or_uri.")
    
    if not step_uri:
        step_uri = table_results[0][0]
    step_ordered_item_uri = table_results[0][1]
    parent_layer_uri = table_results[0][2]
    
    # Dry run mode
    if dry_run:
        return BaseToolMixin.create_success_response({
            "dry_run": True,
            "step_name_or_uri": step_name_or_uri,
            "resolved_step_uri": step_uri,
            "step_ordered_item_uri": step_ordered_item_uri,
            "parent_layer_uri": parent_layer_uri,
            "graphmart_uri": graphmart_uri,
            "explanation": explanation
        }, "Step deletion validated. Set dry_run=false to execute.")
    
    # Delete the step and its ordered item (execute as separate operations)
    delete_step_sparql = f"""
    PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
    
    DELETE WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{step_uri}> ?stepProp ?stepValue .
        }}
    }}
    """
    
    delete_ordered_item_sparql = f"""
    PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
    
    DELETE WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{step_ordered_item_uri}> ?stepOrderedProp ?stepOrderedValue .
        }}
    }}
    """
    
    delete_relationship_sparql = f"""
    PREFIX gm: <http://cambridgesemantics.com/ontologies/Graphmarts#>
    
    DELETE WHERE {{
        GRAPH <{graphmart_uri}> {{
            <{parent_layer_uri}> gm:step <{step_ordered_item_uri}> .
        }}
    }}
    """
    
    # Execute the deletions in sequence
    agent.anzo_client.update_journal(delete_step_sparql)
    agent.anzo_client.update_journal(delete_ordered_item_sparql)
    agent.anzo_client.update_journal(delete_relationship_sparql)
    
    return BaseToolMixin.create_success_response({
        "step_name_or_uri": step_name_or_uri,
        "deleted_step_uri": step_uri,
        "deleted_step_ordered_item_uri": step_ordered_item_uri,
        "parent_layer_uri": parent_layer_uri,
        "graphmart_uri": graphmart_uri,
        "explanation": explanation
    }, f"Successfully deleted transformation step '{step_name_or_uri}'")