{% extends "equity/base.html" %}
{% load static %}

{% block title %}个股筛选 - AgomTradePro{% endblock %}

{% block content %}
<div class="equity-container">
    <style>
        .screen-workflow {
            display: grid;
            grid-template-columns: repeat(4, minmax(0, 1fr));
            gap: 12px;
            margin-bottom: 20px;
        }

        .screen-workflow-step {
            background: linear-gradient(135deg, #eff6ff 0%, #f8fafc 100%);
            border: 1px solid #dbeafe;
            border-radius: 14px;
            padding: 16px;
        }

        .screen-workflow-step strong {
            display: block;
            margin-bottom: 6px;
            color: #1e3a8a;
        }

        .screen-workflow-step p {
            margin: 0;
            color: #475569;
            font-size: 13px;
            line-height: 1.5;
        }

        .screen-unified-layout {
            display: grid;
            grid-template-columns: 1.15fr 1fr;
            gap: 20px;
            margin-bottom: 20px;
        }

        .screen-source-card {
            border: 1px solid #dbeafe;
            background: linear-gradient(180deg, #f8fbff 0%, #ffffff 100%);
        }

        .screen-source-status {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            padding: 6px 12px;
            border-radius: 999px;
            background: #eff6ff;
            color: #1d4ed8;
            font-size: 13px;
            font-weight: 600;
        }

        .screen-source-actions,
        .screen-toolbar-actions {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
        }

        .auto-recommendation-grid {
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 12px;
            margin-top: 16px;
        }

        .auto-recommendation-item {
            border: 1px solid #e5e7eb;
            border-radius: 14px;
            padding: 14px;
            background: #fff;
        }

        .auto-recommendation-head {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            gap: 12px;
            margin-bottom: 10px;
        }

        .auto-recommendation-code {
            color: #111827;
            text-decoration: none;
            font-weight: 700;
        }

        .auto-recommendation-name {
            color: #475569;
            font-size: 13px;
            margin-top: 3px;
        }

        .auto-recommendation-score {
            text-align: right;
            color: #2563eb;
            font-weight: 700;
            font-size: 14px;
        }

        .auto-recommendation-meta {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
            margin-bottom: 12px;
        }

        .auto-meta-chip {
            padding: 4px 8px;
            border-radius: 999px;
            background: #f1f5f9;
            color: #475569;
            font-size: 12px;
        }

        .auto-recommendation-actions {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }

        .screen-mode-banner {
            display: none;
            margin-bottom: 16px;
            padding: 14px 16px;
            border-radius: 12px;
            background: #ecfeff;
            border: 1px solid #a5f3fc;
            color: #155e75;
            font-size: 14px;
        }

        .screen-summary-strip {
            display: grid;
            grid-template-columns: repeat(4, minmax(0, 1fr));
            gap: 12px;
            margin-bottom: 16px;
        }

        .screen-summary-card {
            border-radius: 14px;
            background: #fff;
            border: 1px solid #e5e7eb;
            padding: 14px 16px;
        }

        .screen-summary-label {
            color: #64748b;
            font-size: 12px;
            margin-bottom: 6px;
        }

        .screen-summary-value {
            color: #0f172a;
            font-size: 20px;
            font-weight: 700;
        }

        @media (max-width: 1100px) {
            .screen-unified-layout,
            .screen-workflow,
            .screen-summary-strip,
            .auto-recommendation-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
    <div class="equity-header">
        <h1>个股筛选</h1>
        <p>把系统自动推荐、手动筛选和用户决策接到同一个页面里，而不是分成两套入口。</p>
    </div>

    <div class="screen-workflow">
        <div class="screen-workflow-step">
            <strong>1. 系统自动</strong>
            <p>系统 Alpha 推荐会同步到这里，导航栏、首页摘要和完整排名页使用同一批自动推荐。</p>
        </div>
        <div class="screen-workflow-step">
            <strong>2. 用户加条件</strong>
            <p>可以继续按 Regime、ROE、PE、PB、增长率和负债率二次筛选。</p>
        </div>
        <div class="screen-workflow-step">
            <strong>3. 看解释</strong>
            <p>同一张结果表里直接看标的、行业、指标，并跳详情页或首页来源。</p>
        </div>
        <div class="screen-workflow-step">
            <strong>4. 去决策</strong>
            <p>结果项直接支持加入观察、采纳，继续流向统一决策工作台。</p>
        </div>
    </div>

    <div class="page-tabs">
        <button class="page-tab active" onclick="switchTab('screen')">个股筛选</button>
        <button class="page-tab" onclick="window.location.href='/equity/pool/'">股票池</button>
    </div>

    <div class="screen-unified-layout">
        <div class="card screen-source-card" id="alphaSourceCard">
            <div style="display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; flex-wrap: wrap;">
                <div>
                    <span class="screen-source-status" id="autoRecommendationStatus">系统自动推荐</span>
                    <h2 class="card-title" style="margin: 10px 0 8px;">当前系统推荐流</h2>
                    <p id="alphaSourceSummary" style="margin: 0; color: #6b7280;">
                        正在加载系统自动推荐...
                    </p>
                </div>
                <div class="screen-source-actions">
                    <button class="btn btn-primary" type="button" onclick="refreshDashboardAlphaRecommendations(true)">刷新自动推荐</button>
                    <a id="alphaRankingLink" href="/dashboard/alpha/ranking/" class="btn btn-secondary" style="text-decoration: none;">查看完整排名</a>
                    <a href="/decision/workspace/" class="btn btn-secondary" style="text-decoration: none;">决策工作台</a>
                    <a href="/dashboard/" class="btn btn-secondary" style="text-decoration: none;">返回首页</a>
                </div>
            </div>
            <!-- 投资免责声明 -->
            <div class="investment-disclaimer compact" style="margin-top: 12px;">
                <div class="disclaimer-icon">⚠️</div>
                <div class="disclaimer-text">
                    <strong>免责声明：</strong>系统推荐仅供研究，<span class="highlight">不构成投资建议</span>。
                </div>
            </div>
            <div class="auto-recommendation-grid" id="autoRecommendationGrid"></div>
        </div>

        <!-- 筛选条件卡片 -->
        <div class="card">
            <h2 class="card-title">手动二次筛选</h2>
            <p style="margin: 8px 0 0; color: #6b7280; font-size: 14px;">
                不是另起一个工具页，而是在系统自动推荐之外，继续让用户表达自己的偏好。
            </p>

            <div class="filter-group">
            <div class="filter-item">
                <label>Regime</label>
                <select id="regimeSelect">
                    <option value="">自动获取最新</option>
                    <option value="Recovery">复苏 (Recovery)</option>
                    <option value="Overheat">过热 (Overheat)</option>
                    <option value="Stagflation">滞胀 (Stagflation)</option>
                    <option value="Deflation">通缩 (Deflation)</option>
                </select>
            </div>

            <div class="filter-item">
                <label>最低 ROE (%)</label>
                <input type="number" id="minRoe" value="15" min="0" max="100" step="1">
            </div>

            <div class="filter-item">
                <label>最高 PE</label>
                <input type="number" id="maxPe" value="30" min="0" max="200" step="1">
            </div>

            <div class="filter-item">
                <label>最高 PB</label>
                <input type="number" id="maxPb" value="5" min="0" max="50" step="0.5">
            </div>

            <div class="filter-item">
                <label>最低营收增长率 (%)</label>
                <input type="number" id="minRevenueGrowth" value="10" min="-100" max="500" step="1">
            </div>

            <div class="filter-item">
                <label>最低净利润增长率 (%)</label>
                <input type="number" id="minProfitGrowth" value="10" min="-100" max="500" step="1">
            </div>

            <div class="filter-item">
                <label>最高资产负债率 (%)</label>
                <input type="number" id="maxDebtRatio" value="70" min="0" max="100" step="1">
            </div>

            <div class="filter-item">
                <label>返回数量</label>
                <input type="number" id="maxCount" value="30" min="1" max="100" step="1">
            </div>
            </div>

            <div class="screen-toolbar-actions" style="margin-top: 20px;">
                <button class="btn btn-primary" onclick="runScreening()">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>
                </svg>
                开始筛选
                </button>
                <button class="btn btn-secondary" onclick="resetFilters()">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
                    <path d="M3 3v5h5"/>
                </svg>
                重置条件
                </button>
                <button class="btn btn-success" onclick="exportResults()">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                    <polyline points="7 10 12 15 17 10"/>
                    <line x1="12" y1="15" x2="12" y2="3"/>
                </svg>
                导出结果
                </button>
                <button class="btn btn-secondary" type="button" onclick="loadDashboardAlphaRecommendations(true)">切回系统推荐</button>
            </div>
        </div>
    </div>

    <div class="screen-mode-banner" id="screenModeBanner"></div>

    <!-- 当前 Regime 显示 -->
    <div class="card" id="regimeInfo" style="display: none;">
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; gap: 16px; flex-wrap: wrap;">
            <div>
                <h2 class="card-title" style="margin: 0;">当前结果上下文</h2>
                <div style="margin-top: 8px;">
                    <span style="font-size: 24px; font-weight: 600; color: #2563eb;" id="currentRegime">-</span>
                    <span style="color: #6b7280; margin-left: 12px;" id="regimeDesc">-</span>
                </div>
            </div>
        </div>
        <div class="screen-summary-strip">
            <div class="screen-summary-card">
                <div class="screen-summary-label">来源模式</div>
                <div class="screen-summary-value" id="screenModeValue">-</div>
            </div>
            <div class="screen-summary-card">
                <div class="screen-summary-label">结果数量</div>
                <div class="screen-summary-value" id="screenCount">-</div>
            </div>
            <div class="screen-summary-card">
                <div class="screen-summary-label">筛选时间</div>
                <div class="screen-summary-value" style="font-size: 16px;" id="screenTime">-</div>
            </div>
            <div class="screen-summary-card">
                <div class="screen-summary-label">响应耗时</div>
                <div class="screen-summary-value" style="font-size: 16px;" id="screenDuration">-</div>
            </div>
        </div>
    </div>

    <!-- 加载状态 -->
    <div class="card" id="loadingCard" style="display: none;">
        <div class="app-loading-state">
            <div class="app-spinner" aria-hidden="true"></div>
            <p class="app-loading-text">正在筛选个股...</p>
        </div>
    </div>

    <!-- 筛选结果 -->
    <div class="card" id="resultsCard" style="display: none;">
        <h2 class="card-title">筛选结果</h2>
        <div class="table-container">
            <table>
                <thead>
                    <tr>
                        <th>排名</th>
                        <th>股票代码</th>
                        <th>股票名称</th>
                        <th>所属行业</th>
                        <th>ROE (%)</th>
                        <th>PE</th>
                        <th>PB</th>
                        <th>营收增长率 (%)</th>
                        <th>净利润增长率 (%)</th>
                        <th>综合评分</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody id="resultsTableBody">
                </tbody>
            </table>
        </div>
    </div>

    <!-- 空状态 -->
    <div class="card" id="emptyCard" style="display: none;">
        <div class="empty-state">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                <circle cx="11" cy="11" r="8"/>
                <line x1="21" y1="21" x2="16.65" y2="16.65"/>
            </svg>
            <p>点击"开始筛选"按钮进行个股筛选</p>
        </div>
    </div>
</div>

<script>
const urlParams = new URLSearchParams(window.location.search);
let screeningResults = [];
let currentResults = [];
let currentSourceLabel = '手动筛选';
let autoRecommendationItems = [];

function buildDashboardAlphaApiUrl() {
    const query = new URLSearchParams();
    query.set('format', 'json');
    query.set('top_n', '10');
    query.set('_ts', String(Date.now()));

    const portfolioId = urlParams.get('portfolio_id');
    const poolMode = urlParams.get('pool_mode');
    if (portfolioId) {
        query.set('portfolio_id', portfolioId);
    }
    if (poolMode) {
        query.set('pool_mode', poolMode);
    }
    return `/api/dashboard/alpha/stocks/?${query.toString()}`;
}

function buildDashboardAlphaRankingUrl() {
    const query = new URLSearchParams();
    query.set('top_n', '200');

    const portfolioId = urlParams.get('portfolio_id');
    const poolMode = urlParams.get('pool_mode');
    const alphaScope = urlParams.get('alpha_scope');

    if (alphaScope) {
        query.set('alpha_scope', alphaScope);
    }
    if (portfolioId) {
        query.set('portfolio_id', portfolioId);
    }
    if (poolMode) {
        query.set('pool_mode', poolMode);
    }

    return `/dashboard/alpha/ranking/?${query.toString()}`;
}

function buildDashboardAlphaRefreshPayload(sync = true) {
    const payload = new URLSearchParams();
    payload.set('top_n', '10');

    if (sync) {
        payload.set('sync', 'true');
    }

    const portfolioId = urlParams.get('portfolio_id');
    const poolMode = urlParams.get('pool_mode');
    const alphaScope = urlParams.get('alpha_scope');

    if (portfolioId) {
        payload.set('portfolio_id', portfolioId);
    }
    if (poolMode) {
        payload.set('pool_mode', poolMode);
    }
    if (alphaScope) {
        payload.set('alpha_scope', alphaScope);
    }

    return payload;
}

function getDashboardAlphaMeta(payload) {
    return payload?.data?.meta || {};
}

function getDashboardAlphaAsOfDate(payload, items) {
    const meta = getDashboardAlphaMeta(payload);
    return (
        meta.effective_asof_date ||
        meta.verified_asof_date ||
        meta.cache_date ||
        items.find((item) => item?.asof_date)?.asof_date ||
        ''
    );
}

function sleep(ms) {
    return new Promise((resolve) => window.setTimeout(resolve, ms));
}

function getRecommendationCodes(items) {
    return Array.from(new Set(
        (Array.isArray(items) ? items : [])
            .map((item) => String(item?.code || '').trim().toUpperCase())
            .filter(Boolean)
    ));
}

async function syncRecommendationFundamentals(stockCodes) {
    if (!Array.isArray(stockCodes) || stockCodes.length === 0) {
        return { synced: false, message: '当前推荐列表没有可同步的股票代码。' };
    }

    const csrftoken = getCookie('csrftoken');
    const requestHeaders = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'X-CSRFToken': csrftoken,
    };

    const valuationResponse = await fetch('/api/equity/valuation-data/sync/', {
        method: 'POST',
        headers: requestHeaders,
        body: JSON.stringify({
            stock_codes: stockCodes,
            days_back: 7,
            primary_source: 'akshare',
        }),
    });
    const valuationPayload = await valuationResponse.json();
    if (!valuationResponse.ok || valuationPayload.success === false) {
        throw new Error(valuationPayload.error || '估值同步失败');
    }

    const financialResponse = await fetch('/api/equity/financial-data/sync/', {
        method: 'POST',
        headers: requestHeaders,
        body: JSON.stringify({
            stock_codes: stockCodes,
            periods: 8,
            source: 'akshare',
        }),
    });
    const financialPayload = await financialResponse.json();
    if (!financialResponse.ok || financialPayload.success === false) {
        throw new Error(financialPayload.error || '财务同步失败');
    }

    const valuationCount = Number(valuationPayload.synced_count || 0);
    const financialCount = Number(financialPayload.synced_count || 0);
    return {
        synced: true,
        valuationCount,
        financialCount,
        message: `已同步 ${stockCodes.length} 只推荐股票的估值/财务真源数据。`,
    };
}

function switchTab(tab) {
    // Tab 切换逻辑
}

function resetFilters() {
    document.getElementById('regimeSelect').value = '';
    document.getElementById('minRoe').value = 15;
    document.getElementById('maxPe').value = 30;
    document.getElementById('maxPb').value = 5;
    document.getElementById('minRevenueGrowth').value = 10;
    document.getElementById('minProfitGrowth').value = 10;
    document.getElementById('maxDebtRatio').value = 70;
    document.getElementById('maxCount').value = 30;
}

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function escapeHtml(value) {
    return String(value ?? '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

function formatMetric(value, digits = 2) {
    if (value === null || value === undefined || value === '') {
        return '-';
    }

    const numericValue = Number(value);
    return Number.isFinite(numericValue) ? numericValue.toFixed(digits) : escapeHtml(value);
}

function toResultItems(result) {
    if (Array.isArray(result.items) && result.items.length > 0) {
        return result.items;
    }

    return (result.stock_codes || []).map((code, index) => ({
        rank: index + 1,
        code,
        name: '待补充',
        sector: '-',
        roe: null,
        pe: null,
        pb: null,
        revenue_growth: null,
        profit_growth: null,
        score: null,
        source: result.source || 'screen',
    }));
}

function renderAutoRecommendationGrid(items) {
    const container = document.getElementById('autoRecommendationGrid');
    if (!container) {
        return;
    }

    if (!items || items.length === 0) {
        container.innerHTML = `
            <div class="auto-recommendation-item">
                <div class="auto-recommendation-name">当前没有可展示的系统自动推荐，请稍后重试或直接使用手动筛选。</div>
            </div>
        `;
        return;
    }

    container.innerHTML = items.slice(0, 6).map((item, index) => {
        const code = escapeHtml(item.code || '-');
        const name = escapeHtml(item.name || '未命名');
        const score = formatMetric(item.score, 3);
        const confidence = formatMetric(item.confidence, 2);
        const detailUrl = `/equity/detail/${encodeURIComponent(item.code || '')}/`;

        return `
            <div class="auto-recommendation-item">
                <div class="auto-recommendation-head">
                    <div>
                        <a href="${detailUrl}" class="auto-recommendation-code">${code}</a>
                        <div class="auto-recommendation-name">${name}</div>
                    </div>
                    <div class="auto-recommendation-score">#${index + 1}<br>${score}</div>
                </div>
                <div class="auto-recommendation-meta">
                    <span class="auto-meta-chip">置信度 ${confidence}</span>
                    <span class="auto-meta-chip">${escapeHtml(item.source || 'alpha')}</span>
                    <span class="auto-meta-chip">${escapeHtml(item.asof_date || '-')}</span>
                </div>
                <div class="auto-recommendation-actions">
                    <a class="btn btn-primary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="${detailUrl}">解释</a>
                    <a class="btn btn-secondary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="${buildDecisionWorkspaceUrl(item.code || '', { source: 'equity-screen', action: 'watch' })}">观察</a>
                    <a class="btn btn-secondary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="${buildDecisionWorkspaceUrl(item.code || '', { source: 'equity-screen', action: 'adopt' })}">采纳</a>
                </div>
            </div>
        `;
    }).join('');
}

function setModeBanner(message) {
    const banner = document.getElementById('screenModeBanner');
    banner.textContent = message;
    banner.style.display = 'block';
}

function buildDecisionWorkspaceUrl(securityCode, { source = '', action = '', step = '' } = {}) {
    const params = new URLSearchParams();
    if (source) {
        params.set('source', source);
    }
    if (securityCode) {
        params.set('security_code', String(securityCode).toUpperCase());
    }
    if (step) {
        params.set('step', String(step));
    }
    if (action) {
        params.set('action', String(action).toUpperCase());
    }
    return `/decision/workspace/?${params.toString()}`;
}

function renderResultsTable(items) {
    const tbody = document.getElementById('resultsTableBody');
    tbody.innerHTML = '';

    items.forEach((item, index) => {
        const code = escapeHtml(item.code || '-');
        const name = escapeHtml(item.name || '未命名');
        const sector = escapeHtml(item.sector || item.industry || '-');
        const detailUrl = `/equity/detail/${encodeURIComponent(item.code || '')}/`;
        const row = document.createElement('tr');
        row.innerHTML = `
            <td>${escapeHtml(item.rank || index + 1)}</td>
            <td><a href="${detailUrl}" class="stock-code">${code}</a></td>
            <td>${name}</td>
            <td>${sector}</td>
            <td>${formatMetric(item.roe)}</td>
            <td>${formatMetric(item.pe)}</td>
            <td>${formatMetric(item.pb)}</td>
            <td>${formatMetric(item.revenue_growth)}</td>
            <td>${formatMetric(item.profit_growth)}</td>
            <td>${formatMetric(item.score, 3)}</td>
            <td>
                <div style="display: flex; gap: 8px; flex-wrap: wrap;">
                    <a class="btn btn-primary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="${detailUrl}">个股详情</a>
                    <a class="btn btn-secondary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="${buildDecisionWorkspaceUrl(item.code || '', { source: 'equity-screen', action: 'watch' })}">加入观察</a>
                    <a class="btn btn-secondary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="${buildDecisionWorkspaceUrl(item.code || '', { source: 'equity-screen', action: 'adopt' })}">采纳</a>
                    <a class="btn btn-secondary" style="padding: 6px 12px; font-size: 13px; text-decoration: none;" href="/dashboard/">首页来源</a>
                </div>
            </td>
        `;
        tbody.appendChild(row);
    });
}

function updateSummary(result, duration, sourceLabel) {
    const regimeNames = {
        'Recovery': '复苏',
        'Overheat': '过热',
        'Stagflation': '滞胀',
        'Deflation': '通缩'
    };

    const regime = result.regime ? (regimeNames[result.regime] || result.regime) : 'Alpha 推荐';
    const criteria = result.screening_criteria || {};
    const sectors = Array.isArray(criteria.sectors) && criteria.sectors.length > 0
        ? `偏好行业: ${criteria.sectors.join(', ')}`
        : `${sourceLabel}结果`;

    document.getElementById('currentRegime').textContent = regime;
    document.getElementById('regimeDesc').textContent = sectors;
    document.getElementById('screenModeValue').textContent = sourceLabel;
    document.getElementById('screenTime').textContent = new Date().toLocaleString('zh-CN');
    document.getElementById('screenCount').textContent = `${currentResults.length} 只`;
    document.getElementById('screenDuration').textContent = `${duration} 秒`;
    document.getElementById('regimeInfo').style.display = 'block';
}

function showEmpty(message) {
    document.getElementById('loadingCard').style.display = 'none';
    document.getElementById('resultsCard').style.display = 'none';
    document.getElementById('regimeInfo').style.display = 'none';
    document.getElementById('emptyCard').style.display = 'block';
    document.querySelector('#emptyCard p').textContent = message;
}

function displayResults(result, duration, sourceLabel = '手动筛选') {
    currentSourceLabel = sourceLabel;
    currentResults = toResultItems(result);
    screeningResults = currentResults.map((item) => item.code).filter(Boolean);

    if (currentResults.length === 0) {
        showEmpty(`${sourceLabel}暂无结果`);
        return;
    }

    updateSummary(result, duration, sourceLabel);
    renderResultsTable(currentResults);
    document.getElementById('loadingCard').style.display = 'none';
    document.getElementById('emptyCard').style.display = 'none';
    document.getElementById('resultsCard').style.display = 'block';
    setModeBanner(`当前结果来自「${sourceLabel}」。你可以继续切回系统自动推荐，或修改条件做二次筛选。`);
}

async function runScreening() {
    const regime = document.getElementById('regimeSelect').value;
    const customRule = {
        min_roe: parseFloat(document.getElementById('minRoe').value),
        max_pe: parseFloat(document.getElementById('maxPe').value),
        max_pb: parseFloat(document.getElementById('maxPb').value),
        min_revenue_growth: parseFloat(document.getElementById('minRevenueGrowth').value),
        min_profit_growth: parseFloat(document.getElementById('minProfitGrowth').value),
        max_debt_ratio: parseFloat(document.getElementById('maxDebtRatio').value)
    };
    const maxCount = parseInt(document.getElementById('maxCount').value);

    // 显示加载状态
    document.getElementById('loadingCard').style.display = 'block';
    document.getElementById('resultsCard').style.display = 'none';
    document.getElementById('emptyCard').style.display = 'none';
    document.getElementById('regimeInfo').style.display = 'none';

    const startTime = Date.now();

    const csrftoken = getCookie('csrftoken');

    try {
        const response = await fetch('/api/equity/screen/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrftoken
            },
            body: JSON.stringify({
                regime: regime || null,
                custom_rule: customRule,
                max_count: maxCount
            })
        });

        const result = await response.json();
        const duration = ((Date.now() - startTime) / 1000).toFixed(2);

        document.getElementById('loadingCard').style.display = 'none';

        if (result.success) {
            displayResults(result, duration, '手动筛选');
        } else {
            alert('筛选失败: ' + result.error);
            showEmpty('筛选失败，未返回推荐结果');
        }
    } catch (error) {
        document.getElementById('loadingCard').style.display = 'none';
        alert('请求失败: ' + error.message);
        showEmpty('请求失败，请稍后重试');
    }
}

async function loadDashboardAlphaRecommendations(renderResults = true, options = {}) {
    const preserveLoading = Boolean(options.preserveLoading);
    document.getElementById('alphaSourceSummary').textContent = '正在同步系统自动推荐结果...';
    document.getElementById('autoRecommendationStatus').textContent = '系统自动推荐加载中';
    if (!preserveLoading) {
        document.getElementById('loadingCard').style.display = 'block';
        document.getElementById('emptyCard').style.display = 'none';
    }

    const startTime = Date.now();
    try {
        const payload = await window.fetchJsonOrThrow(buildDashboardAlphaApiUrl(), {
            cache: 'no-store',
            headers: {
                'Accept': 'application/json'
            }
        });
        const items = Array.isArray(payload?.data?.items)
            ? payload.data.items
            : (Array.isArray(payload?.data?.top_candidates) ? payload.data.top_candidates : []);
        const meta = getDashboardAlphaMeta(payload);
        const asofDate = getDashboardAlphaAsOfDate(payload, items) || '未知';
        const duration = ((Date.now() - startTime) / 1000).toFixed(2);
        autoRecommendationItems = items;
        renderAutoRecommendationGrid(items);

        const refreshMessage = options.refreshMessage ? `${options.refreshMessage} ` : '';
        if (urlParams.get('source') === 'dashboard-alpha') {
            document.getElementById('autoRecommendationStatus').textContent = meta.uses_cached_data ? '来自系统 Alpha 推荐（缓存）' : '来自系统 Alpha 推荐';
            document.getElementById('alphaSourceSummary').textContent = `${refreshMessage}已带入 ${items.length} 只系统 Alpha 推荐，当前页面与首页摘要、完整排名页使用同一批系统推荐。最新评分日 ${asofDate}。`;
        } else {
            document.getElementById('autoRecommendationStatus').textContent = meta.uses_cached_data ? '系统自动推荐（缓存）' : '系统自动推荐';
            document.getElementById('alphaSourceSummary').textContent = `${refreshMessage}当前系统推荐共 ${items.length} 只股票。最新评分日 ${asofDate}。导航栏、首页摘要和完整排名页看到的是同一批推荐。`;
        }

        if (meta.warning_message) {
            document.getElementById('alphaSourceSummary').textContent += ` ${meta.warning_message}`;
        }

        if (renderResults) {
            displayResults(
                {
                    success: true,
                    regime: null,
                    items,
                    stock_codes: items.map((item) => item.code),
                    screening_criteria: {},
                },
                duration,
                '系统自动推荐'
            );
        } else {
            document.getElementById('loadingCard').style.display = 'none';
        }
    } catch (error) {
        console.error('Failed to load dashboard alpha recommendations:', error);
        document.getElementById('autoRecommendationStatus').textContent = '系统自动推荐异常';
        document.getElementById('alphaSourceSummary').textContent = '系统推荐同步失败，请稍后重试，或直接使用下方手动筛选。';
        renderAutoRecommendationGrid([]);
        showEmpty('首页推荐暂时无法加载，请改用手动筛选');
    }
}

async function refreshDashboardAlphaRecommendations(renderResults = true) {
    const statusNode = document.getElementById('autoRecommendationStatus');
    const summaryNode = document.getElementById('alphaSourceSummary');
    statusNode.textContent = '系统自动推荐刷新中';
    summaryNode.textContent = '正在触发当日最新 Alpha 推荐刷新，请稍候...';
    document.getElementById('loadingCard').style.display = 'block';
    document.getElementById('emptyCard').style.display = 'none';

    const csrftoken = getCookie('csrftoken');

    try {
        const response = await fetch('/api/dashboard/alpha/refresh/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'X-CSRFToken': csrftoken,
                'Accept': 'application/json',
            },
            body: buildDashboardAlphaRefreshPayload(true).toString(),
        });
        const payload = await response.json();
        const message = String(payload.message || payload.error || '').trim();

        if (payload.success) {
            const waitMs = payload.sync ? 0 : Math.min(Number(payload.poll_after_ms) || 0, 5000);
            if (waitMs > 0) {
                await sleep(waitMs);
            }
            await loadDashboardAlphaRecommendations(renderResults, {
                preserveLoading: true,
                refreshMessage: message || '系统自动推荐已触发刷新。',
            });

            const stockCodes = getRecommendationCodes(autoRecommendationItems);
            if (stockCodes.length > 0) {
                statusNode.textContent = '同步推荐财务/估值中';
                summaryNode.textContent = '正在补齐当前推荐股票的财务与估值真源数据，请稍候...';
                let syncResult;
                try {
                    syncResult = await syncRecommendationFundamentals(stockCodes);
                } catch (syncError) {
                    await loadDashboardAlphaRecommendations(renderResults, {
                        preserveLoading: true,
                        refreshMessage: `${message || '系统自动推荐已触发刷新。'} 但推荐股票财务/估值真源同步失败：${syncError.message}。`,
                    });
                    return;
                }
                await loadDashboardAlphaRecommendations(renderResults, {
                    preserveLoading: true,
                    refreshMessage: `${message || '系统自动推荐已触发刷新。'} ${syncResult.message}`,
                });
            }
            return;
        }

        await loadDashboardAlphaRecommendations(renderResults, {
            preserveLoading: true,
            refreshMessage: message
                ? `${message} 当前先回显最近可用结果。`
                : '刷新未成功，当前先回显最近可用结果。',
        });
    } catch (error) {
        console.error('Failed to refresh dashboard alpha recommendations:', error);
        await loadDashboardAlphaRecommendations(renderResults, {
            preserveLoading: true,
            refreshMessage: `刷新触发失败：${error.message}。当前先回显最近可用结果。`,
        });
    }
}

function exportResults() {
    if (screeningResults.length === 0) {
        alert('没有可导出的数据');
        return;
    }

    const csv = '股票代码\n' + screeningResults.join('\n');
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `stock_screen_${new Date().toISOString().slice(0, 10)}.csv`;
    link.click();
}

document.addEventListener('DOMContentLoaded', () => {
    const rankingLink = document.getElementById('alphaRankingLink');
    if (rankingLink) {
        rankingLink.href = buildDashboardAlphaRankingUrl();
    }
    loadDashboardAlphaRecommendations(true);
});
</script>

<!-- Floating Widget Config -->
<script>
    // Load floating widget config from JSON file
    fetch('{% static "widgets/configs/equity_widget.json" %}')
        .then(response => response.json())
        .then(config => {
            window.floatingWidgetConfig = config;
            // Trigger initialization manually since DOM is already loaded
            if (window.initFloatingWidget) {
                window.initFloatingWidget(config);
            }
        })
        .catch(err => console.error('Failed to load widget config:', err));
</script>

{% endblock %}
