#!/usr/bin/env python3
"""
Advanced Analysis Showcase - Working Example

Demonstrates a complete working pipeline using the hidden-regime package:
- Data loading with FinancialDataLoader
- Observation generation with FinancialObservationGenerator
- HMM model training and prediction
- Financial analysis with comprehensive metrics
- Report generation with markdown output

This example uses the current working API and handles edge cases properly.
"""

import os
import sys

import matplotlib
import numpy as np
import pandas as pd

matplotlib.use("Agg")  # Use non-interactive backend
import warnings
from datetime import datetime, timedelta

import matplotlib.pyplot as plt

warnings.filterwarnings("ignore")

# Add the project root to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from hidden_regime.analysis.financial import FinancialAnalysis
from hidden_regime.analysis.indicator_comparison import IndicatorPerformanceComparator
from hidden_regime.analysis.performance import RegimePerformanceAnalyzer
from hidden_regime.config.analysis import FinancialAnalysisConfig
from hidden_regime.config.data import FinancialDataConfig
from hidden_regime.config.model import HMMConfig
from hidden_regime.config.observation import FinancialObservationConfig
from hidden_regime.config.report import ReportConfig

# Import using current working architecture
from hidden_regime.data.financial import FinancialDataLoader
from hidden_regime.models.hmm import HiddenMarkovModel
from hidden_regime.observations.financial import FinancialObservationGenerator
from hidden_regime.reports.markdown import MarkdownReportGenerator


def create_sample_data():
    """Create sample data for demonstration if yfinance fails."""
    print("Creating sample data for demonstration...")

    # Generate synthetic price data with regime-like behavior
    np.random.seed(42)
    n_days = 500

    dates = pd.date_range(start="2023-01-01", periods=n_days, freq="D")

    # Regime states (0=Bear, 1=Sideways, 2=Bull)
    regime_states = []
    current_regime = 1  # Start sideways
    regime_duration = 0

    for i in range(n_days):
        if regime_duration == 0:
            # Determine regime duration
            if current_regime == 0:  # Bear
                regime_duration = np.random.poisson(15) + 5
            elif current_regime == 1:  # Sideways
                regime_duration = np.random.poisson(25) + 10
            else:  # Bull
                regime_duration = np.random.poisson(20) + 8

        regime_states.append(current_regime)
        regime_duration -= 1

        if regime_duration == 0:
            # Transition to new regime
            if current_regime == 0:  # Bear -> Sideways or Bull
                current_regime = np.random.choice([1, 2], p=[0.6, 0.4])
            elif current_regime == 1:  # Sideways -> Bear or Bull
                current_regime = np.random.choice([0, 2], p=[0.3, 0.7])
            else:  # Bull -> Bear or Sideways
                current_regime = np.random.choice([0, 1], p=[0.4, 0.6])

    # Generate price data based on regimes
    prices = [100.0]  # Starting price

    for i in range(1, n_days):
        regime = regime_states[i]

        if regime == 0:  # Bear
            daily_return = np.random.normal(-0.002, 0.025)
        elif regime == 1:  # Sideways
            daily_return = np.random.normal(0.0001, 0.015)
        else:  # Bull
            daily_return = np.random.normal(0.0015, 0.020)

        new_price = prices[-1] * (1 + daily_return)
        prices.append(max(new_price, 1.0))  # Prevent negative prices

    # Create OHLCV data
    data = pd.DataFrame(
        {
            "open": prices,
            "high": [p * (1 + abs(np.random.normal(0, 0.01))) for p in prices],
            "low": [p * (1 - abs(np.random.normal(0, 0.01))) for p in prices],
            "close": prices,
            "volume": np.random.randint(1000000, 5000000, n_days),
        },
        index=dates,
    )

    # Ensure high >= close >= low and high >= open >= low
    data["high"] = data[["high", "close", "open"]].max(axis=1)
    data["low"] = data[["low", "close", "open"]].min(axis=1)

    return data


def main():
    """Main demonstration function."""
    print("🚀 Hidden Regime: Advanced Analysis Showcase (Phase 3)")
    print("=" * 60)

    # Configuration
    ticker = "AAPL"
    start_date = "2023-01-01"
    end_date = "2024-12-31"

    try:
        # Load market data
        print(f"\n📊 Loading market data for {ticker}...")
        data_loader = FinancialDataLoader(
            FinancialDataConfig(ticker=ticker, start_date=start_date, end_date=end_date)
        )

        raw_data = data_loader.update()

        if raw_data.empty:
            print("❌ No data retrieved, using sample data instead")
            raw_data = create_sample_data()
            ticker = "SAMPLE"
        else:
            print(f"✅ Loaded {len(raw_data)} days of {ticker} data")

    except Exception as e:
        print(f"❌ Data loading failed: {e}")
        print("📝 Using sample data instead")
        raw_data = create_sample_data()
        ticker = "SAMPLE"

    # Create observation component
    print("\n🔍 Creating observations...")
    observation_config = FinancialObservationConfig(generators=["log_return"])
    observation_component = FinancialObservationGenerator(observation_config)

    # Generate observations
    observations = observation_component.update(raw_data)
    print(f"✅ Generated {len(observations)} observations")

    # Create and train HMM model
    print("\n🤖 Training HMM model...")
    model_config = HMMConfig(n_states=3, random_seed=42)
    hmm_model = HiddenMarkovModel(model_config)

    # Train model
    model_output = hmm_model.update(observations)
    print(f"✅ Model trained, generated {len(model_output)} predictions")
    print(
        f"📊 Current regime: {model_output['predicted_state'].iloc[-1]} "
        f"(confidence: {model_output['confidence'].iloc[-1]:.1%})"
    )

    # Create enhanced analysis component (avoiding known bugs)
    print("\n🔬 Creating enhanced financial analysis...")
    analysis_config = FinancialAnalysisConfig(
        n_states=3,
        calculate_regime_statistics=True,
        include_duration_analysis=False,  # Disable due to implementation bug
        include_return_analysis=True,
        include_volatility_analysis=True,
        include_trading_signals=True,
        include_indicator_performance=True,
        indicator_comparisons=["rsi", "macd", "bollinger_bands", "moving_average"],
        risk_adjustment=True,
    )

    financial_analysis = FinancialAnalysis(analysis_config)

    # Run comprehensive analysis
    analysis_results = financial_analysis.update(model_output, raw_data=raw_data, model_component=hmm_model)
    print(f"✅ Analysis complete with {len(analysis_results.columns)} features")

    # Get comprehensive performance metrics
    print("\n📈 Generating comprehensive performance metrics...")
    performance_metrics = financial_analysis.get_comprehensive_performance_metrics()

    # Create indicator comparison analysis
    print("\n🔍 Running indicator performance comparison...")
    comparator = IndicatorPerformanceComparator()

    comparison_results = comparator.compare_regime_vs_indicators(
        analysis_results=analysis_results,
        raw_data=raw_data,
        indicators=["rsi", "macd", "bollinger_bands", "moving_average"],
    )

    print("✅ Indicator comparison complete")
    if "indicator_analysis" in comparison_results:
        print(f"📊 Analyzed {len(comparison_results['indicator_analysis'])} indicators")

        # Show performance ratings
        for indicator, analysis in comparison_results["indicator_analysis"].items():
            rating = analysis["performance_rating"]["rating"]
            score = analysis["performance_rating"]["composite_score"]
            print(f"   • {indicator.upper()}: {rating} (score: {score:.3f})")

    # Generate advanced report
    print("\n📝 Generating comprehensive report...")
    report_config = ReportConfig(
        include_summary=True,
        include_regime_analysis=True,
        include_performance_metrics=True,
        include_risk_analysis=True,
        include_trading_signals=True,
        include_data_quality=True,
    )

    report_generator = MarkdownReportGenerator(report_config)

    # Create comprehensive report
    full_report = report_generator.update(
        data=raw_data,
        observations=observations,
        model_output=model_output,
        analysis=analysis_results,
    )

    # Save report to output directory
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    output_dir = os.path.join(os.path.dirname(__file__), "..", "output")
    os.makedirs(os.path.join(output_dir, "reports"), exist_ok=True)
    report_filename = os.path.join(
        output_dir, "reports", f"advanced_analysis_report_{ticker}_{timestamp}.md"
    )

    with open(report_filename, "w") as f:
        f.write(full_report)

    print(f"✅ Report saved as: {report_filename}")

    # Create basic visualizations that work
    print("\n🎨 Creating visualizations...")

    try:
        # Basic price and regime plot
        print("   • Creating price and regime plot...")
        fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))

        # Price plot
        ax1.plot(raw_data.index, raw_data["close"], linewidth=1.5, label="Price")
        ax1.set_title(f"{ticker} Price Chart")
        ax1.set_ylabel("Price")
        ax1.legend()
        ax1.grid(True, alpha=0.3)

        # Regime plot
        regime_colors = ["red", "orange", "green"]
        for i, regime in enumerate([0, 1, 2]):
            mask = model_output["predicted_state"] == regime
            if mask.sum() > 0:  # Only plot if regime exists
                ax2.scatter(
                    model_output.index[mask],
                    [regime] * mask.sum(),
                    c=regime_colors[i],
                    alpha=0.7,
                    s=20,
                    label=f"Regime {regime}",
                )

        ax2.set_title("Regime Detection")
        ax2.set_ylabel("Regime")
        ax2.set_xlabel("Date")
        ax2.legend()
        ax2.grid(True, alpha=0.3)

        plt.tight_layout()
        os.makedirs(os.path.join(output_dir, "plots"), exist_ok=True)
        plot_filename = os.path.join(
            output_dir, "plots", f"basic_analysis_{ticker}_{timestamp}.png"
        )
        fig.savefig(plot_filename, dpi=300, bbox_inches="tight")
        plt.close(fig)

        print(f"   ✅ Visualization saved as: {plot_filename}")

    except Exception as e:
        print(f"   ❌ Visualization failed: {e}")
        plot_filename = None

    # Display key results
    print(f"\n📊 Key Results for {ticker}:")
    print("=" * 40)

    # Basic results display
    current_regime = model_output["predicted_state"].iloc[-1]
    current_confidence = (
        model_output["confidence"].iloc[-1]
        if not pd.isna(model_output["confidence"].iloc[-1])
        else 0.0
    )

    print(f"Current Regime: {current_regime}")
    print(f"Confidence: {current_confidence:.1%}")

    # Regime distribution
    regime_counts = model_output["predicted_state"].value_counts().sort_index()
    print(f"\nRegime Distribution:")
    for regime, count in regime_counts.items():
        percentage = count / len(model_output) * 100
        print(f"  Regime {regime}: {count} days ({percentage:.1f}%)")

    # Performance summary
    print(f"\nPerformance Summary:")
    if "summary" in performance_metrics:
        perf_summary = performance_metrics["summary"]
        quality_score = perf_summary.get("quality_score", 0)
        stability_rating = perf_summary.get("stability_rating", "Unknown")
        print(f"  Quality Score: {quality_score:.1%}")
        print(f"  Stability Rating: {stability_rating}")
    else:
        print("  Basic metrics calculated successfully")

    # Indicator results
    print(f"\nIndicator Analysis:")
    if (
        "indicator_analysis" in comparison_results
        and comparison_results["indicator_analysis"]
    ):
        indicator_count = len(comparison_results["indicator_analysis"])
        print(f"  Analyzed {indicator_count} technical indicators")
        print(f"  Results available in report")
    else:
        print(f"  Indicator analysis completed")

    print(f"\n🎉 Analysis Complete!")
    print(f"📁 Generated files:")
    print(f"   • Report: {report_filename}")
    if plot_filename:
        print(f"   • Visualization: {plot_filename}")

    print(f"\n🔧 Demonstrated capabilities:")
    print(f"   ✅ Data loading and processing")
    print(f"   ✅ HMM regime detection")
    print(f"   ✅ Financial analysis")
    print(f"   ✅ Performance metrics")
    print(f"   ✅ Report generation")
    print(f"   ✅ Basic visualizations")

    return {
        "analysis": analysis_results,
        "performance": performance_metrics,
        "indicators": comparison_results,
        "model_output": model_output,
        "raw_data": raw_data,
    }


if __name__ == "__main__":
    try:
        results = main()
        print("\n" + "=" * 60)
        print("🚀 Advanced Analysis Showcase: COMPLETE")
        print("=" * 60)
    except Exception as e:
        print(f"\n❌ Error running showcase: {e}")
        print("This may be due to known implementation bugs.")
        print("Check TODOS.md for bug resolution status.")
