"""
Advanced visualization examples.
"""

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from quantumwalks import (
    DTQW1D, DTQW2D, GraphDTQW, SzegedyQW, 
    analyze_convergence, plot_convergence_analysis, compare_classical_quantum
)

def convergence_analysis_demo():
    """Demonstrate convergence analysis."""
    print("Running convergence analysis...")
    
    graph = nx.barabasi_albert_graph(30, 2)
    gqw = GraphDTQW(graph, coin_type='grover', initial_node=0)
    
    # Analyze convergence
    convergence_data = analyze_convergence(gqw, max_steps=50)
    
    # Plot convergence
    fig = plot_convergence_analysis(convergence_data)
    plt.show()

def multiple_coin_comparison():
    """Compare different coin operators."""
    print("Comparing coin operators...")
    
    graph = nx.karate_club_graph()
    
    coins = ['grover', 'fourier']
    results = {}
    
    for coin_type in coins:
        gqw = GraphDTQW(graph, coin_type=coin_type, initial_node=0)
        gqw.evolve(10)
        results[coin_type] = gqw.get_probabilities()
    
    # Plot comparison
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))
    
    for i, (coin_type, probs) in enumerate(results.items()):
        axes[i].bar(range(len(probs)), probs)
        axes[i].set_title(f'{coin_type.capitalize()} Coin')
        axes[i].set_xlabel('Node')
        axes[i].set_ylabel('Probability')
    
    plt.tight_layout()
    plt.show()

def quantum_classical_comparison():
    """Detailed quantum vs classical comparison."""
    print("Running quantum-classical comparison...")
    
    graph = nx.connected_caveman_graph(3, 8)
    
    # Compare methods
    comparison = compare_classical_quantum(graph)
    
    print(f"Correlation: {comparison['correlation']:.4f}")
    print(f"KL Divergence: {comparison['kl_divergence']:.4f}")
    
    # Plot detailed comparison
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
    
    nodes = sorted(graph.nodes())
    x_pos = np.arange(len(nodes))
    
    # Scores comparison
    width = 0.35
    ax1.bar(x_pos - width/2, comparison['classical_scores'], width, 
            label='Classical', alpha=0.7)
    ax1.bar(x_pos + width/2, comparison['quantum_scores'], width, 
            label='Quantum', alpha=0.7)
    ax1.set_xlabel('Node')
    ax1.set_ylabel('PageRank Score')
    ax1.set_title('Classical vs Quantum PageRank')
    ax1.legend()
    ax1.grid(True, alpha=0.3)
    
    # Rank comparison
    classical_ranks = {node: rank for rank, (node, _) in 
                      enumerate(comparison['sorted_classical'])}
    quantum_ranks = {node: rank for rank, (node, _) in 
                    enumerate(comparison['sorted_quantum'])}
    
    ax2.scatter([classical_ranks[n] for n in nodes], 
               [quantum_ranks[n] for n in nodes], alpha=0.7)
    ax2.plot([0, len(nodes)-1], [0, len(nodes)-1], 'r--', alpha=0.8)
    ax2.set_xlabel('Classical Rank')
    ax2.set_ylabel('Quantum Rank')
    ax2.set_title('Rank Comparison')
    ax2.grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    convergence_analysis_demo()
    multiple_coin_comparison()
    quantum_classical_comparison()