"""
Graph Query Interface - Usage Examples

Comprehensive examples demonstrating all query capabilities.

Story: KG-004
Date: 2026-01-24
"""

import sys
sys.path.insert(0, '/mnt/e/genesis-system/data/genesis-memory')

from graph_query import GraphQuery
from datetime import datetime


def example_1_basic_type_query():
    """Example 1: Query entities by type."""
    print("\n" + "=" * 60)
    print("Example 1: Query by Entity Type")
    print("=" * 60)

    with GraphQuery() as query:
        # Find all Learning entities
        results = query.by_type("Learning", limit=10)

        print(f"\nFound {len(results)} Learning entities:")
        for result in results:
            print(f"  - {result.name}")
            print(f"    Type: {result.entity_type}")
            print(f"    Importance: {result.relevance_score:.2f}")
            print(f"    Properties: {result.properties}")
            print()


def example_2_pagination():
    """Example 2: Paginated queries."""
    print("\n" + "=" * 60)
    print("Example 2: Pagination")
    print("=" * 60)

    with GraphQuery() as query:
        page_size = 5
        page_num = 0

        # Get first page
        page1 = query.by_type(
            "tradie_lead",
            limit=page_size,
            offset=page_num * page_size
        )

        print(f"\nPage 1 ({len(page1)} results):")
        for result in page1:
            print(f"  - {result.name}")

        # Get second page
        page_num = 1
        page2 = query.by_type(
            "tradie_lead",
            limit=page_size,
            offset=page_num * page_size
        )

        print(f"\nPage 2 ({len(page2)} results):")
        for result in page2:
            print(f"  - {result.name}")


def example_3_sorting_and_filtering():
    """Example 3: Sorting and filtering."""
    print("\n" + "=" * 60)
    print("Example 3: Sorting and Filtering")
    print("=" * 60)

    with GraphQuery() as query:
        # Get most important entities
        important = query.by_type(
            "strategic_concept",
            limit=10,
            sort_by="importance",
            sort_order="DESC",
            min_importance=0.5
        )

        print(f"\nMost important Strategic Concepts (importance >= 0.5):")
        for result in important:
            print(f"  - {result.name}: {result.relevance_score:.3f}")


def example_4_relationship_queries():
    """Example 4: Query by relationships."""
    print("\n" + "=" * 60)
    print("Example 4: Relationship Queries")
    print("=" * 60)

    with GraphQuery() as query:
        # Find all "depends_on" relationships
        dependencies = query.by_relationship(
            "depends_on",
            limit=10,
            min_strength=0.5
        )

        print(f"\nFound {len(dependencies)} dependency relationships:")
        for rel in dependencies:
            print(f"  {rel.source_id} → {rel.target_id}")
            print(f"    Type: {rel.relationship_type}")
            print(f"    Strength: {rel.strength:.2f}")
            print(f"    Confidence: {rel.confidence:.2f}")
            print()


def example_5_recent_entities():
    """Example 5: Query recent entities."""
    print("\n" + "=" * 60)
    print("Example 5: Recent Entities")
    print("=" * 60)

    with GraphQuery() as query:
        # Get entities updated in last 24 hours
        recent_24h = query.recent(hours=24, limit=10)

        print(f"\nEntities updated in last 24 hours: {len(recent_24h)}")
        for result in recent_24h:
            print(f"  - {result.name}")
            print(f"    Updated: {result.updated_at}")
            print()

        # Get recent learnings from last week
        recent_learnings = query.recent(
            hours=168,  # 1 week
            entity_type="Learning",
            limit=5
        )

        print(f"\nLearnings from last week: {len(recent_learnings)}")
        for result in recent_learnings:
            print(f"  - {result.name}")


def example_6_semantic_similarity():
    """Example 6: Vector similarity search."""
    print("\n" + "=" * 60)
    print("Example 6: Semantic Similarity")
    print("=" * 60)

    with GraphQuery() as query:
        # Find entities similar to a concept
        similar = query.similar_to(
            "knowledge graph",
            top_k=5,
            min_score=0.7
        )

        print(f"\nEntities similar to 'knowledge graph': {len(similar)}")
        for result in similar:
            print(f"  - {result.name}")
            print(f"    Similarity: {result.relevance_score:.2f}")
            print()


def example_7_custom_queries():
    """Example 7: Custom SQL queries."""
    print("\n" + "=" * 60)
    print("Example 7: Custom Queries")
    print("=" * 60)

    with GraphQuery() as query:
        # Get entity counts by type
        sql = """
            SELECT entity_type, COUNT(*) as count, AVG(importance) as avg_importance
            FROM semantic_entities
            GROUP BY entity_type
            HAVING COUNT(*) > 1
            ORDER BY count DESC
        """

        results = query.custom_query(sql, limit=10)

        print(f"\nEntity statistics:")
        print(f"{'Type':<30} {'Count':<10} {'Avg Importance':<15}")
        print("-" * 60)
        for row in results:
            print(f"{row['entity_type']:<30} {row['count']:<10} {row['avg_importance'] or 0:.3f}")


def example_8_comprehensive_search():
    """Example 8: Comprehensive multi-step search."""
    print("\n" + "=" * 60)
    print("Example 8: Comprehensive Search Workflow")
    print("=" * 60)

    with GraphQuery() as query:
        # Step 1: Find high-importance entities
        print("\nStep 1: Find high-importance entities")
        important = query.by_type(
            "strategic_concept",
            limit=5,
            min_importance=0.5,
            sort_by="importance",
            sort_order="DESC"
        )

        print(f"Found {len(important)} high-importance strategic concepts")

        if important:
            # Step 2: Get the most important one
            top_entity = important[0]
            print(f"\nStep 2: Examining top entity: {top_entity.name}")
            print(f"  Importance: {top_entity.relevance_score:.3f}")
            print(f"  Properties: {top_entity.properties}")

            # Step 3: Find related entities
            print(f"\nStep 3: Finding relationships for {top_entity.entity_id[:16]}...")
            relationships = query.by_relationship(
                "related",
                source=top_entity.entity_id[:8],
                limit=5
            )

            print(f"Found {len(relationships)} related entities")

            # Step 4: Get recent updates of same type
            print(f"\nStep 4: Recent updates of type {top_entity.entity_type}")
            recent = query.recent(
                hours=168,
                entity_type=top_entity.entity_type,
                limit=5
            )

            print(f"Found {len(recent)} recent updates")


def example_9_result_serialization():
    """Example 9: Serializing results."""
    print("\n" + "=" * 60)
    print("Example 9: Result Serialization")
    print("=" * 60)

    with GraphQuery() as query:
        results = query.by_type("technology_enabler", limit=3)

        print(f"\nSerialized results to JSON-compatible format:")
        for result in results:
            result_dict = result.to_dict()
            print(f"\n{result.name}:")
            for key, value in result_dict.items():
                if key == 'properties':
                    print(f"  {key}: {value}")
                else:
                    print(f"  {key}: {value}")


def example_10_caching_performance():
    """Example 10: Cache performance demonstration."""
    print("\n" + "=" * 60)
    print("Example 10: Caching Performance")
    print("=" * 60)

    import time

    with GraphQuery() as query:
        # Clear cache to start fresh
        query.cache.clear()

        # First query (uncached)
        start = time.time()
        results1 = query.by_type("tradie_lead", limit=10)
        time1 = time.time() - start

        # Second query (cached)
        start = time.time()
        results2 = query.by_type("tradie_lead", limit=10)
        time2 = time.time() - start

        print(f"\nFirst query (uncached): {time1*1000:.2f}ms")
        print(f"Second query (cached):  {time2*1000:.2f}ms")
        print(f"Speedup: {time1/time2:.1f}x faster" if time2 > 0 else "Instant")
        print(f"Results identical: {len(results1) == len(results2)}")


def example_11_error_handling():
    """Example 11: Error handling patterns."""
    print("\n" + "=" * 60)
    print("Example 11: Error Handling")
    print("=" * 60)

    with GraphQuery() as query:
        # Handle nonexistent entity type gracefully
        print("\nQuerying nonexistent entity type:")
        try:
            results = query.by_type("NonexistentType123", limit=10)
            print(f"  Returned {len(results)} results (empty is expected)")
        except Exception as e:
            print(f"  Caught exception: {e}")

        # Handle invalid parameters
        print("\nQuerying with negative limit:")
        try:
            results = query.by_type("strategic_concept", limit=-1)
            print(f"  Returned {len(results)} results")
        except Exception as e:
            print(f"  Caught exception: {type(e).__name__}")


def main():
    """Run all examples."""
    print("\n" + "=" * 60)
    print("GENESIS GRAPH QUERY - COMPREHENSIVE EXAMPLES")
    print("=" * 60)

    examples = [
        example_1_basic_type_query,
        example_2_pagination,
        example_3_sorting_and_filtering,
        example_4_relationship_queries,
        example_5_recent_entities,
        example_6_semantic_similarity,
        example_7_custom_queries,
        example_8_comprehensive_search,
        example_9_result_serialization,
        example_10_caching_performance,
        example_11_error_handling,
    ]

    for example_func in examples:
        try:
            example_func()
        except Exception as e:
            print(f"\nError in {example_func.__name__}: {e}")
            import traceback
            traceback.print_exc()

    print("\n" + "=" * 60)
    print("All examples completed!")
    print("=" * 60)


if __name__ == "__main__":
    main()
