from fastapi import APIRouter, HTTPException, Query, Depends
from datetime import datetime, date
from typing import List, Optional
import pandas as pd
import numpy as np

from ...analytics.performance import PerformanceAnalyzer
from ...analytics.regime import RegimeDetector
from ..app import get_performance_analyzer, get_regime_detector

router = APIRouter()

@router.get("/performance/{portfolio_id}")
async def get_performance_metrics(
    portfolio_id: str,
    start_date: datetime = Query(..., description="Start date for analysis"),
    end_date: datetime = Query(..., description="End date for analysis"),
    analyzer: PerformanceAnalyzer = Depends(get_performance_analyzer)
):
    """
    Calculate comprehensive performance metrics for a portfolio
    """
    try:
        # In real implementation, would fetch data from database
        # For now, using mock data
        metrics = analyzer.calculate_metrics(
            portfolio_id=portfolio_id,
            start_date=start_date,
            end_date=end_date
        )
        
        return metrics
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to calculate performance metrics: {str(e)}")

@router.get("/risk/{portfolio_id}")
async def get_risk_metrics(
    portfolio_id: str,
    window: int = Query(252, description="Rolling window for risk calculations"),
    analyzer: PerformanceAnalyzer = Depends(get_performance_analyzer)
):
    """
    Calculate risk metrics including VaR and CVaR
    """
    try:
        risk_metrics = analyzer.calculate_risk_metrics(
            portfolio_id=portfolio_id,
            window=window
        )
        
        return risk_metrics
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to calculate risk metrics: {str(e)}")

@router.get("/regime")
async def detect_market_regime(
    lookback_days: int = Query(60, description="Days to look back for regime detection"),
    detector: RegimeDetector = Depends(get_regime_detector)
):
    """
    Detect current market regime using various indicators
    """
    try:
        regime = detector.detect_current_regime(lookback_days=lookback_days)
        
        return {
            "regime": regime['regime'],
            "confidence": regime['confidence'],
            "indicators": regime['indicators'],
            "timestamp": datetime.utcnow().isoformat()
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to detect market regime: {str(e)}")

@router.post("/correlation")
async def calculate_correlation_matrix(
    symbols: List[str],
    start_date: Optional[date] = None,
    end_date: Optional[date] = None,
    method: str = Query("pearson", pattern="^(pearson|spearman|kendall)$")
):
    """
    Calculate correlation matrix for given symbols
    """
    try:
        # In real implementation, would fetch price data
        # For now, return mock correlation matrix
        n = len(symbols)
        
        # Generate realistic correlation matrix
        np.random.seed(42)
        A = np.random.randn(n, n)
        correlation_matrix = np.dot(A, A.T)
        
        # Normalize to correlation
        D = np.sqrt(np.diag(np.diag(correlation_matrix)))
        correlation_matrix = np.linalg.inv(D) @ correlation_matrix @ np.linalg.inv(D)
        
        return {
            "symbols": symbols,
            "matrix": correlation_matrix.tolist(),
            "method": method
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to calculate correlation: {str(e)}")

@router.get("/backtest/{backtest_id}")
async def analyze_backtest_results(
    backtest_id: str,
    analyzer: PerformanceAnalyzer = Depends(get_performance_analyzer)
):
    """
    Analyze results from a completed backtest
    """
    try:
        analysis = analyzer.analyze_backtest(backtest_id)
        
        return {
            "backtest_id": backtest_id,
            "metrics": analysis['metrics'],
            "statistics": analysis['statistics'],
            "risk_analysis": analysis['risk_analysis'],
            "trade_analysis": analysis['trade_analysis']
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to analyze backtest: {str(e)}")

@router.post("/attribution")
async def performance_attribution(
    portfolio_id: str,
    benchmark: str,
    start_date: date,
    end_date: date,
    method: str = Query("brinson", pattern="^(brinson|factor|risk)$")
):
    """
    Perform performance attribution analysis
    """
    try:
        # Placeholder for attribution analysis
        return {
            "portfolio_id": portfolio_id,
            "benchmark": benchmark,
            "period": {
                "start": start_date.isoformat(),
                "end": end_date.isoformat()
            },
            "method": method,
            "attribution": {
                "allocation_effect": 0.0023,
                "selection_effect": 0.0045,
                "interaction_effect": 0.0001,
                "total_effect": 0.0069
            }
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to perform attribution: {str(e)}")