"""Portfolio routes - asset overview and active queues.

Option C: Portfolio page always shows ALL assets (crypto + stock combined),
unlike other pages which are filtered by the crypto/stock toggle.
"""
from __future__ import annotations

from collections import OrderedDict

from flask import Blueprint, render_template
from flask_login import login_required, current_user
from app.helpers.auth import get_current_user_id

from app.extensions import db
from app.models.asset import Asset, AssetProfile
from app.models.portfolio import Portfolio, TradeHistory
from app.models.prediction_queue import PredictionQueue

portfolio_bp = Blueprint('portfolio', __name__)


@portfolio_bp.route('/')
@login_required
def index():
    """Portfolio overview — shows ALL assets (crypto + stock combined)."""

    # --- 1. Portfolio positions (ALL assets — no asset_mode filter) ---
    positions = Portfolio.query.join(Asset, Portfolio.asset_id == Asset.id)\
        .filter(Portfolio.user_id == get_current_user_id(),
                Portfolio.total_quantity > 0).all()

    portfolio_items = []
    total_invested = 0
    total_current = 0
    total_realized = 0
    # Per-asset-type subtotals for summary cards
    subtotals = {'crypto': {'invested': 0, 'current': 0, 'realized': 0, 'count': 0},
                 'stock': {'invested': 0, 'current': 0, 'realized': 0, 'count': 0}}

    for p in positions:
        qty = float(p.total_quantity or 0)
        avg_buy = float(p.avg_buy_price or 0)
        invested = float(p.total_invested_idr or 0)
        realized = float(p.realized_pnl or 0)

        profile = AssetProfile.query.filter_by(
            asset_id=p.asset_id
        ).order_by(AssetProfile.fetched_at.desc()).first()

        current_price = float(profile.current_price_idr) if profile and profile.current_price_idr else 0
        current_value = current_price * qty
        unrealized = current_value - (avg_buy * qty) if avg_buy > 0 else 0
        pnl_pct = (unrealized / invested * 100) if invested > 0 else 0

        coin_obj = db.session.get(Asset, p.asset_id)
        asset_type = coin_obj.asset_type if coin_obj else 'crypto'

        portfolio_items.append({
            'asset_id': p.asset_id,
            'asset': coin_obj,
            'asset_type': asset_type,
            'quantity': qty,
            'avg_buy_price': avg_buy,
            'current_price': current_price,
            'current_value': round(current_value, 2),
            'invested': invested,
            'unrealized_pnl': round(unrealized, 2),
            'realized_pnl': realized,
            'pnl_pct': round(pnl_pct, 2),
        })

        total_invested += invested
        total_current += current_value
        total_realized += realized

        # Accumulate subtotals
        st = subtotals.get(asset_type, subtotals['crypto'])
        st['invested'] += invested
        st['current'] += current_value
        st['realized'] += realized
        st['count'] += 1

    # Finalize subtotals
    for key in subtotals:
        st = subtotals[key]
        st['unrealized'] = round(st['current'] - st['invested'], 2)
        st['invested'] = round(st['invested'], 2)
        st['current'] = round(st['current'], 2)
        st['realized'] = round(st['realized'], 2)
        st['pnl_pct'] = round((st['unrealized'] / st['invested'] * 100), 2) if st['invested'] > 0 else 0

    summary = {
        'count': len(portfolio_items),
        'total_invested': round(total_invested, 2),
        'total_current': round(total_current, 2),
        'total_unrealized': round(total_current - total_invested, 2),
        'total_realized': round(total_realized, 2),
        'total_pnl_pct': round(
            (total_current - total_invested) / total_invested * 100, 2
        ) if total_invested > 0 else 0,
    }

    # --- 2. Active queues (ALL assets — no filter) ---
    active_queues_raw = PredictionQueue.query.join(
        Asset, PredictionQueue.asset_id == Asset.id
    ).filter(
        PredictionQueue.is_executed == False
    ).order_by(
        PredictionQueue.prediction_date.desc(),
        PredictionQueue.asset_id,
        PredictionQueue.sequence_num.asc(),
    ).limit(200).all()

    queues_by_coin: dict[str, list] = OrderedDict()
    for entry in active_queues_raw:
        if entry.asset_id not in queues_by_coin:
            queues_by_coin[entry.asset_id] = []
        queues_by_coin[entry.asset_id].append(entry)

    # --- 3. Recent trade history (ALL assets — no filter) ---
    recent_trades = TradeHistory.query.filter(
        TradeHistory.user_id == get_current_user_id()
    ).order_by(
        TradeHistory.executed_at.desc()
    ).limit(20).all()

    # Preload asset objects for trades
    trade_asset_ids = list({t.asset_id for t in recent_trades})
    trade_coins = {c.id: c for c in Asset.query.filter(
        Asset.id.in_(trade_asset_ids)
    ).all()} if trade_asset_ids else {}

    return render_template('portfolio/index.html',
                           portfolio_items=portfolio_items,
                           summary=summary,
                           subtotals=subtotals,
                           queues_by_coin=queues_by_coin,
                           recent_trades=recent_trades,
                           trade_coins=trade_coins)
