"""Settings routes."""
from __future__ import annotations

from flask import Blueprint, current_app, render_template, request, redirect, url_for, flash
from flask_login import login_required, current_user
from app.helpers.auth import admin_required, get_current_user_id
from app.models.settings import AppSettings

settings_bp = Blueprint('settings', __name__)


@settings_bp.route('/')
@login_required
def general():
    """Redirect to first settings sub-page (admin → data source, user → capital)."""
    from app.helpers.auth import is_admin as _is_admin
    if _is_admin():
        return redirect(url_for('settings.data_source'))
    return redirect(url_for('settings.capital'))


@settings_bp.route('/data-source')
@admin_required
def data_source():
    """Data source configuration page."""
    import os

    active_source = AppSettings.get('active_data_source', 'coingecko')
    sync_timeframes = AppSettings.get('sync_timeframes', ['1h', '4h', '1D'])

    def mask_key(key_str):
        """Mask API key: show first 4 + **** + last 4."""
        if not key_str or len(key_str) < 8:
            return ''
        return key_str[:4] + '****' + key_str[-4:]

    # API keys — env var takes priority, then AppSettings fallback
    cg_key = os.getenv('COINGECKO_API_KEY', '') or AppSettings.get('coingecko_api_key', '')
    idx_key = os.getenv('INDODAX_API_KEY', '') or AppSettings.get('indodax_api_key', '')
    idx_secret = os.getenv('INDODAX_API_SECRET', '') or AppSettings.get('indodax_api_secret', '')
    tc_key = os.getenv('TOKOCRYPTO_API_KEY', '') or AppSettings.get('tokocrypto_api_key', '')
    tc_secret = os.getenv('TOKOCRYPTO_API_SECRET', '') or AppSettings.get('tokocrypto_api_secret', '')

    # Sync config per source (saved → fallback to defaults)
    defaults_all = current_app.config.get('SYNC_CONFIG_DEFAULTS', {})
    sync_configs = {}
    for src in ('coingecko', 'indodax', 'tokocrypto'):
        defaults = defaults_all.get(src, {})
        saved = AppSettings.get(f'{src}_sync_config', {}) or {}
        sync_configs[src] = {**defaults, **saved}

    # Stock settings
    stock_icon_source = AppSettings.get('stock_icon_source', 'growin')
    stock_data_source = AppSettings.get('stock_data_source', 'yahoo')
    us_stock_icon_source = AppSettings.get('us_stock_icon_source', 'fmp')

    return render_template('settings/data_source.html',
                           active_source=active_source,
                           sync_timeframes=sync_timeframes,
                           stock_icon_source=stock_icon_source,
                           stock_data_source=stock_data_source,
                           us_stock_icon_source=us_stock_icon_source,
                           sync_configs=sync_configs,
                           coingecko_has_key=bool(cg_key),
                           coingecko_api_key_masked=mask_key(cg_key),
                           indodax_has_key=bool(idx_key),
                           indodax_api_key_masked=mask_key(idx_key),
                           indodax_api_secret_masked=mask_key(idx_secret),
                           tokocrypto_has_key=bool(tc_key),
                           tokocrypto_api_key_masked=mask_key(tc_key),
                           tokocrypto_api_secret_masked=mask_key(tc_secret))


@settings_bp.route('/capital')
@login_required
def capital():
    """Capital allocation settings page — reads from UserSettings (per-user)."""
    from app.models.settings import CapitalAllocation
    from app.models.user_settings import UserSettings
    uid = get_current_user_id()

    def _get(key, default):
        """Read from UserSettings first, fallback to AppSettings."""
        if uid:
            val = UserSettings.get(uid, key)
            if val is not None:
                return val
        return AppSettings.get(key, default)

    # Crypto capital
    default_capital = _get('default_capital', 1_000_000)
    active_pct = _get('active_capital_pct', 75.0)
    reserve_pct = _get('reserve_capital_pct', 25.0)

    # Stock-specific capital
    stock_capital = _get('stock_default_capital', 1_000_000)
    stock_active_pct = _get('stock_active_capital_pct', 75.0)
    stock_reserve_pct = _get('stock_reserve_capital_pct', 25.0)

    # US Stock capital
    us_capital = _get('stock_us_default_capital', 1_000_000)
    us_active_pct = _get('stock_us_active_capital_pct', 75.0)
    us_reserve_pct = _get('stock_us_reserve_capital_pct', 25.0)

    allocations = CapitalAllocation.query.filter_by(user_id=get_current_user_id()).all()

    # Enrich and split allocations by asset_type
    crypto_alloc_list = []
    stock_alloc_list = []
    us_alloc_list = []
    for a in allocations:
        d = a.to_dict()
        d['coin_name'] = a.asset.name if a.asset else a.asset_id
        d['coin_symbol'] = a.asset.symbol.upper() if a.asset else ''
        d['coin_icon'] = getattr(a.asset, 'icon_thumb_url', '') or '' if a.asset else ''
        d['asset_type'] = a.asset.asset_type if a.asset else 'crypto'
        d['editing'] = False
        if d['asset_type'] == 'stock':
            stock_alloc_list.append(d)
        elif d['asset_type'] == 'stock_us':
            us_alloc_list.append(d)
        else:
            crypto_alloc_list.append(d)

    return render_template('settings/capital.html',
                           default_capital=default_capital,
                           active_pct=active_pct,
                           reserve_pct=reserve_pct,
                           stock_capital=stock_capital,
                           stock_active_pct=stock_active_pct,
                           stock_reserve_pct=stock_reserve_pct,
                           us_capital=us_capital,
                           us_active_pct=us_active_pct,
                           us_reserve_pct=us_reserve_pct,
                           crypto_alloc_list=crypto_alloc_list,
                           stock_alloc_list=stock_alloc_list,
                           us_alloc_list=us_alloc_list)


@settings_bp.route('/fees')
@login_required
def fees():
    """Transaction fee configuration page — reads from UserSettings (per-user)."""
    from app.models.user_settings import UserSettings
    uid = get_current_user_id()

    def _get(key, default):
        """Read from UserSettings first, fallback to AppSettings."""
        if uid:
            val = UserSettings.get(uid, key)
            if val is not None:
                return val
        return AppSettings.get(key, default)

    buy_fee = _get('buy_fee_pct', 0.31)
    sell_fee = _get('sell_fee_pct', 0.31)
    # Stock IDX fees
    stock_buy_fee = _get('stock_buy_fee_pct', 0.15)
    stock_sell_fee = _get('stock_sell_fee_pct', 0.25)
    stock_sell_tax = _get('stock_sell_tax_pct', 0.10)
    stock_broker = _get('stock_broker', 'growin')
    # Stock US fees
    us_buy_fee = _get('stock_us_buy_fee_pct', 0.0)
    us_sell_fee = _get('stock_us_sell_fee_pct', 0.0)
    us_broker = _get('stock_us_broker', 'gotrade')
    return render_template('settings/fees.html',
                           buy_fee=buy_fee,
                           sell_fee=sell_fee,
                           stock_buy_fee=stock_buy_fee,
                           stock_sell_fee=stock_sell_fee,
                           stock_sell_tax=stock_sell_tax,
                           stock_broker=stock_broker,
                           us_buy_fee=us_buy_fee,
                           us_sell_fee=us_sell_fee,
                           us_broker=us_broker)


@settings_bp.route('/system')
@admin_required
def system():
    """System info page."""
    return render_template('settings/system.html')


@settings_bp.route('/export')
@admin_required
def export():
    """Export settings page."""
    from app.models.asset import Asset
    from app.models.ohlcv import OHLCVData
    from sqlalchemy import func
    from app.helpers.asset_filter import apply_asset_filter

    assets = apply_asset_filter(Asset.query.filter_by(is_active=True)).all()

    # Get available timeframes per asset
    coin_data = []
    for c in assets:
        tfs = OHLCVData.query.with_entities(
            OHLCVData.timeframe,
            func.count(OHLCVData.id).label('count'),
        ).filter_by(asset_id=c.id).group_by(OHLCVData.timeframe).all()

        if tfs:
            coin_data.append({
                'asset': c,
                'timeframes': {tf.timeframe: tf.count for tf in tfs},
            })

    return render_template('settings/export.html', coin_data=coin_data)
