---
// MiniKnowledgeGraph.astro - Inline version that replaces the Tags section
// Designed to work within the existing sidebar structure

export interface GraphNode {
  id: string;
  label: string;
  type: 'post' | 'tag' | 'category';
  url?: string;
}

export interface GraphEdge {
  source: string;
  target: string;
  type: 'post-tag' | 'post-post';
}

interface Props {
  currentPost?: any; // Made optional
  relatedPosts?: any[];
  graphData?: { nodes: GraphNode[], edges: GraphEdge[] }; // New optional prop for pre-defined graph data
  height?: string; // Optional height prop for customizing the graph height
}

const { currentPost, relatedPosts = [], graphData: initialGraphData, height = "200px" } = Astro.props;

// Generate unique ID for the graph container
const graphId = `mini-cy-${Math.random().toString(36).substring(2, 9)}`;

// Prepare graph data
let nodes: GraphNode[] = [];
let edges: GraphEdge[] = [];
const addedTagIds = new Set<string>();
const addedPostIds = new Set<string>();

// Check if we have pre-defined graph data
if (initialGraphData && initialGraphData.nodes && initialGraphData.edges) {
  // Use the provided graph data
  nodes = initialGraphData.nodes;
  edges = initialGraphData.edges;
} else if (currentPost) {
  // Generate graph data from currentPost and relatedPosts
  // Ensure currentPost has necessary properties
  const safeCurrentPost = {
    id: currentPost.slug || 'current-post',
    title: currentPost.data?.title || 'Current Post',
    tags: currentPost.data?.tags || [],
    category: currentPost.data?.category || 'Uncategorized',
  };

  // Add current post node
  nodes.push({
    id: safeCurrentPost.id,
    label: safeCurrentPost.title,
    type: 'post',
    url: `/posts/${safeCurrentPost.id}/`
  });
  addedPostIds.add(safeCurrentPost.id);

  // Add tags from current post
  safeCurrentPost.tags.forEach((tag: string) => {
    const tagId = `tag-${tag}`;
    
    // Only add if not already added
    if (!addedTagIds.has(tagId)) {
      nodes.push({
        id: tagId,
        label: tag,
        type: 'tag',
        url: `/tag/${tag}/`
      });
      addedTagIds.add(tagId);
    }
    
    // Add edge from current post to tag
    edges.push({
      source: safeCurrentPost.id,
      target: tagId,
      type: 'post-tag'
    });
  });

  // Add related posts and their connections
  if (relatedPosts && relatedPosts.length > 0) {
    relatedPosts.forEach(post => {
      if (!post) return;
      
      const postId = post.slug || `post-${Math.random().toString(36).substring(2, 9)}`;
      
      // Skip if already added or is the current post
      if (addedPostIds.has(postId) || postId === safeCurrentPost.id) {
        return;
      }
      
      // Add related post node
      nodes.push({
        id: postId,
        label: post.data?.title || 'Related Post',
        type: 'post',
        url: `/posts/${postId}/`
      });
      addedPostIds.add(postId);
      
      // Add edge from current post to related post
      edges.push({
        source: safeCurrentPost.id,
        target: postId,
        type: 'post-post'
      });
      
      // Add shared tags and their connections
      const postTags = post.data?.tags || [];
      postTags.forEach((tag: string) => {
        // Only add connections for tags that the current post also has
        if (safeCurrentPost.tags.includes(tag)) {
          const tagId = `tag-${tag}`;
          
          // Add edge from related post to shared tag
          edges.push({
            source: postId,
            target: tagId,
            type: 'post-tag'
          });
        }
      });
    });
  }
}

// Generate final graph data
const graphData = { nodes, edges };

// Determine if we have a valid central node (first node)
const hasCentralNode = nodes.length > 0;
---

<div class="sidebar-card knowledge-graph-card">
  <h3 class="sidebar-title">Post Connections</h3>
  <div class="mini-knowledge-graph">
    <div id={graphId} class="mini-cy" style={`height: ${height};`}></div>
  </div>
</div>

<style>
  .knowledge-graph-card {
    margin-bottom: 1.5rem;
  }
  
  .sidebar-title {
    margin-bottom: 1rem;
    font-size: 1.1rem;
    color: var(--text-primary);
  }
  
  .mini-knowledge-graph {
    position: relative;
    width: 100%;
    height: auto; /* Height will be set by the inline style */
  }
  
  .mini-cy {
    width: 100%;
    height: 100%;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--card-border, rgba(56, 189, 248, 0.2));
    background: rgba(15, 23, 42, 0.2);
  }
</style>

<script define:vars={{ graphId, graphData, hasCentralNode }}>
  // Initialize the miniature knowledge graph
  function initializeMiniGraph() {
    // Ensure Cytoscape is available
    if (typeof cytoscape === 'undefined') {
      console.error('[MiniKnowledgeGraph] Cytoscape library not loaded.');
      return;
    }

    // Find the container
    const container = document.getElementById(graphId);
    if (!container) {
      console.error(`[MiniKnowledgeGraph] Container #${graphId} not found.`);
      return;
    }

    try {
      // Check if we have any nodes to display
      if (!graphData.nodes || graphData.nodes.length === 0) {
        console.warn('[MiniKnowledgeGraph] No nodes to display.');
        container.innerHTML = '<div style="display:flex;height:100%;align-items:center;justify-content:center;color:var(--text-secondary);">No connections available</div>';
        return;
      }

      // Create the style array with base styles
      const styleArray = [
        // Node styling
        {
          selector: 'node',
          style: {
            'background-color': '#3B82F6', // Default blue for posts
            'label': 'data(label)',
            'width': 15,
            'height': 15,
            'font-size': '8px',
            'color': '#E2E8F0',
            'text-valign': 'bottom',
            'text-halign': 'center',
            'text-margin-y': 4,
            'text-wrap': 'ellipsis',
            'text-max-width': '60px',
            'border-width': 1,
            'border-color': '#0F1219',
            'border-opacity': 0.8
          }
        },
        // Post node specific styles
        {
          selector: 'node[type="post"]',
          style: {
            'background-color': '#3B82F6', // Blue for posts
            'shape': 'ellipse',
            'width': 18,
            'height': 18
          }
        },
        // Tag node specific styles
        {
          selector: 'node[type="tag"]',
          style: {
            'background-color': '#10B981', // Green for tags
            'shape': 'diamond',
            'width': 15,
            'height': 15
          }
        },
        // Edge styles
        {
          selector: 'edge',
          style: {
            'width': 1,
            'line-color': 'rgba(226, 232, 240, 0.4)',
            'curve-style': 'bezier',
            'opacity': 0.6
          }
        },
        // Post-tag edge specific styles
        {
          selector: 'edge[type="post-tag"]',
          style: {
            'line-color': 'rgba(16, 185, 129, 0.6)', // Green
            'line-style': 'dashed'
          }
        },
        // Post-post edge specific styles
        {
          selector: 'edge[type="post-post"]',
          style: {
            'line-color': 'rgba(59, 130, 246, 0.6)', // Blue
            'line-style': 'solid',
            'width': 1.5
          }
        },
        // Hover styles
        {
          selector: 'node:hover',
          style: {
            'background-color': '#F59E0B', // Amber on hover
            'border-color': '#FFFFFF',
            'border-width': 2,
            'cursor': 'pointer'
          }
        }
      ];

      // Only add the central node styling if we have a valid central node
      // (This addresses the optional refinement in the requirements)
      if (hasCentralNode) {
        styleArray.push({
          selector: `#${graphData.nodes[0]?.id}`,
          style: {
            'background-color': '#06B6D4', // Cyan for current post
            'width': 25,
            'height': 25,
            'border-width': 2,
            'border-color': '#E2E8F0'
          }
        });
      }

      // Initialize Cytoscape with improved layout parameters for small space
      const cy = cytoscape({
        container,
        elements: [
          ...graphData.nodes.map(node => ({
            data: {
              id: node.id,
              label: node.label,
              type: node.type,
              url: node.url
            }
          })),
          ...graphData.edges.map((edge, index) => ({
            data: {
              id: `e${index}`,
              source: edge.source,
              target: edge.target,
              type: edge.type
            }
          }))
        ],
        style: styleArray,
        // Use a compact layout for sidebar
        layout: {
          name: 'cose',
          animate: false,
          fit: true,
          padding: 5,
          nodeRepulsion: function(node) {
            return 10000; // Stronger repulsion to prevent overlap in small space
          },
          idealEdgeLength: 50,
          edgeElasticity: 0.45,
          nestingFactor: 0.1,
          gravity: 0.25,
          numIter: 1500,
          initialTemp: 1000,
          coolingFactor: 0.99,
          minTemp: 1.0
        }
      });

      // Add click event for nodes
      cy.on('tap', 'node', function(evt) {
        const node = evt.target;
        const url = node.data('url');
        if (url) {
          window.location.href = url;
        }
      });

      // Center the graph
      cy.fit(undefined, 10);

    } catch (error) {
      console.error('[MiniKnowledgeGraph] Error initializing Cytoscape:', error);
      container.innerHTML = '<div style="padding:10px;color:var(--text-secondary);">Error loading graph</div>';
    }
  }

  // Wait for DOM to be ready and ensure proper initialization
  document.addEventListener('DOMContentLoaded', function() {
    // Delay initialization slightly to ensure container has dimensions
    setTimeout(initializeMiniGraph, 100);
  });

  // Also handle the case where the script loads after DOMContentLoaded
  if (document.readyState === 'complete' || document.readyState === 'interactive') {
    setTimeout(initializeMiniGraph, 100);
  }
</script>