<template>
  <div class="portfolio-container" :class="{ 'theme-dark': isDarkTheme }">
    <!-- 资产总览 - 第一行：核心数据 -->
    <div class="summary-section">
      <div class="summary-card total-value">
        <div class="card-icon">
          <a-icon type="wallet" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.totalValue') }}</div>
          <div class="card-value">
            <span class="currency">$</span>
            <span class="amount">{{ formatNumber(summary.total_market_value) }}</span>
          </div>
          <div class="card-sub" v-if="summary.today_change !== undefined">
            <span :class="summary.today_change >= 0 ? 'positive' : 'negative'">
              {{ $t('portfolio.summary.today') }}: {{ summary.today_change >= 0 ? '+' : '' }}${{ formatNumber(summary.today_change) }}
            </span>
          </div>
        </div>
      </div>

      <div class="summary-card">
        <div class="card-icon cost">
          <a-icon type="dollar" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.totalCost') }}</div>
          <div class="card-value">${{ formatNumber(summary.total_cost) }}</div>
        </div>
      </div>

      <div class="summary-card">
        <div class="card-icon" :class="summary.total_pnl >= 0 ? 'profit' : 'loss'">
          <a-icon :type="summary.total_pnl >= 0 ? 'rise' : 'fall'" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.totalPnl') }}</div>
          <div class="card-value" :class="summary.total_pnl >= 0 ? 'positive' : 'negative'">
            {{ summary.total_pnl >= 0 ? '+' : '' }}${{ formatNumber(summary.total_pnl) }}
            <span class="percent">({{ summary.total_pnl_percent >= 0 ? '+' : '' }}{{ summary.total_pnl_percent }}%)</span>
          </div>
        </div>
      </div>

      <div class="summary-card">
        <div class="card-icon positions">
          <a-icon type="fund" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.positionCount') }}</div>
          <div class="card-value">
            {{ summary.position_count }}
            <span class="position-detail" v-if="profitLossStats.profit > 0 || profitLossStats.loss > 0">
              (<span class="positive">{{ profitLossStats.profit }}</span>/<span class="negative">{{ profitLossStats.loss }}</span>)
            </span>
          </div>
          <div class="card-sub">
            {{ $t('portfolio.summary.profitLossRatio') }}
          </div>
        </div>
      </div>
    </div>

    <!-- 资产总览 - 第二行：详细统计 -->
    <div class="summary-section secondary">
      <div class="summary-card mini">
        <div class="card-icon today" :class="summary.today_pnl >= 0 ? 'profit' : 'loss'">
          <a-icon type="stock" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.todayPnl') }}</div>
          <div class="card-value" :class="summary.today_pnl >= 0 ? 'positive' : 'negative'">
            {{ summary.today_pnl >= 0 ? '+' : '' }}${{ formatNumber(summary.today_pnl || 0) }}
          </div>
        </div>
      </div>

      <div class="summary-card mini">
        <div class="card-icon best">
          <a-icon type="trophy" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.bestPerformer') }}</div>
          <div class="card-value small positive" v-if="bestPerformer">
            {{ bestPerformer.symbol }} +{{ bestPerformer.pnl_percent }}%
          </div>
          <div class="card-value small" v-else>-</div>
        </div>
      </div>

      <div class="summary-card mini">
        <div class="card-icon worst">
          <a-icon type="warning" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.worstPerformer') }}</div>
          <div class="card-value small negative" v-if="worstPerformer">
            {{ worstPerformer.symbol }} {{ worstPerformer.pnl_percent }}%
          </div>
          <div class="card-value small" v-else>-</div>
        </div>
      </div>

      <div class="summary-card mini sync-card">
        <div class="card-icon sync" :class="{ 'syncing': isSyncing }">
          <a-icon type="sync" :spin="isSyncing" />
        </div>
        <div class="card-content">
          <div class="card-label">{{ $t('portfolio.summary.priceSync') }}</div>
          <div class="card-value small">
            {{ lastSyncTime ? formatSyncTime(lastSyncTime) : '-' }}
          </div>
          <div class="card-sub">
            {{ $t('portfolio.summary.syncInterval') }}: 30s
            <a-button type="link" size="small" @click="refreshPrices" :loading="isSyncing" style="padding: 0; margin-left: 8px;">
              <a-icon type="reload" v-if="!isSyncing" />
            </a-button>
          </div>
        </div>
      </div>
    </div>

    <!-- 主内容区域 -->
    <div class="main-content">
      <!-- 持仓列表 -->
      <div class="positions-section">
        <div class="section-header">
          <h3>
            <a-icon type="stock" />
            <span>{{ $t('portfolio.positions.title') }}</span>
          </h3>
          <div class="header-actions">
            <!-- 视图切换 -->
            <a-radio-group v-model="viewMode" size="small" style="margin-right: 12px;">
              <a-radio-button value="grid">
                <a-icon type="appstore" />
              </a-radio-button>
              <a-radio-button value="group">
                <a-icon type="folder" />
              </a-radio-button>
            </a-radio-group>
            <!-- 分组筛选（仅网格视图时显示） -->
            <a-select
              v-if="viewMode === 'grid'"
              v-model="selectedGroup"
              :placeholder="$t('portfolio.groups.all')"
              style="width: 150px; margin-right: 12px;"
              allow-clear
              @change="filterByGroup"
            >
              <a-select-option value="">{{ $t('portfolio.groups.all') }}</a-select-option>
              <a-select-option value="__ungrouped__">{{ $t('portfolio.groups.ungrouped') }}</a-select-option>
              <a-select-option v-for="g in groups" :key="g.name" :value="g.name">
                {{ g.name }} ({{ g.count }})
              </a-select-option>
            </a-select>
            <a-button type="primary" @click="showAddPositionModal = true">
              <a-icon type="plus" />
              {{ $t('portfolio.positions.add') }}
            </a-button>
          </div>
        </div>

        <a-spin :spinning="loadingPositions">
          <div class="positions-list">
            <div v-if="positions.length === 0" class="empty-state">
              <a-empty :description="$t('portfolio.positions.empty')">
                <a-button type="primary" @click="showAddPositionModal = true">
                  <a-icon type="plus" />
                  {{ $t('portfolio.positions.addFirst') }}
                </a-button>
              </a-empty>
            </div>

            <!-- 网格视图 -->
            <div v-else-if="viewMode === 'grid'" class="position-grid">
              <div
                v-for="pos in filteredPositions"
                :key="pos.id"
                class="position-card"
                :class="{ 'profit': pos.pnl >= 0, 'loss': pos.pnl < 0 }"
              >
                <div class="position-header">
                  <div class="symbol-info">
                    <a-tag :color="getMarketColor(pos.market)" size="small">{{ getMarketName(pos.market) }}</a-tag>
                    <span class="symbol">{{ pos.symbol }}</span>
                    <span class="name">{{ pos.name }}</span>
                    <a-tag v-if="pos.group_name" size="small" color="blue" style="margin-left: 4px;">
                      <a-icon type="folder" /> {{ pos.group_name }}
                    </a-tag>
                  </div>
                  <div class="position-actions">
                    <a-tooltip :title="hasAlertForPosition(pos.id) ? $t('portfolio.alerts.editAlert') : $t('portfolio.alerts.addAlert')">
                      <a-button
                        type="link"
                        size="small"
                        @click="showAddAlertForPosition(pos)"
                        :class="{ 'has-alert': hasAlertForPosition(pos.id) }"
                      >
                        <a-icon type="bell" :theme="hasAlertForPosition(pos.id) ? 'filled' : 'outlined'" />
                      </a-button>
                    </a-tooltip>
                    <a-button type="link" size="small" @click="editPosition(pos)">
                      <a-icon type="edit" />
                    </a-button>
                    <a-popconfirm
                      :title="$t('portfolio.positions.deleteConfirm')"
                      @confirm="deletePosition(pos.id)"
                    >
                      <a-button type="link" size="small" class="delete-btn">
                        <a-icon type="delete" />
                      </a-button>
                    </a-popconfirm>
                  </div>
                </div>

                <div class="position-body">
                  <div class="price-row">
                    <div class="current-price">
                      <span class="label">{{ $t('portfolio.positions.currentPrice') }}</span>
                      <span class="value">{{ getCurrencySymbol(pos.market) }}{{ formatPrice(pos.current_price) }}</span>
                      <span class="change" :class="pos.price_change >= 0 ? 'up' : 'down'">
                        {{ pos.price_change >= 0 ? '▲' : '▼' }}{{ Math.abs(pos.price_change_percent).toFixed(2) }}%
                      </span>
                    </div>
                    <div class="entry-price">
                      <span class="label">{{ $t('portfolio.positions.entryPrice') }}</span>
                      <span class="value">{{ getCurrencySymbol(pos.market) }}{{ formatPrice(pos.entry_price) }}</span>
                    </div>
                  </div>

                  <div class="quantity-row">
                    <div class="item">
                      <span class="label">{{ $t('portfolio.positions.quantity') }}</span>
                      <span class="value">{{ formatNumber(pos.quantity, 4) }}</span>
                    </div>
                    <div class="item">
                      <span class="label">{{ $t('portfolio.positions.side') }}</span>
                      <a-tag :color="pos.side === 'long' ? 'green' : 'red'" size="small">
                        {{ pos.side === 'long' ? $t('portfolio.positions.long') : $t('portfolio.positions.short') }}
                      </a-tag>
                    </div>
                    <div class="item">
                      <span class="label">{{ $t('portfolio.positions.marketValue') }}</span>
                      <span class="value">{{ getCurrencySymbol(pos.market) }}{{ formatNumber(pos.market_value) }}</span>
                    </div>
                  </div>
                </div>

                <div class="position-footer">
                  <div class="pnl">
                    <span class="label">{{ $t('portfolio.positions.pnl') }}</span>
                    <span class="value" :class="pos.pnl >= 0 ? 'positive' : 'negative'">
                      {{ pos.pnl >= 0 ? '+' : '' }}{{ getCurrencySymbol(pos.market) }}{{ formatNumber(pos.pnl) }}
                      <span class="percent">({{ pos.pnl_percent >= 0 ? '+' : '' }}{{ pos.pnl_percent }}%)</span>
                    </span>
                  </div>
                </div>
              </div>
            </div>

            <!-- 分组折叠视图 -->
            <div v-else class="position-collapse-view">
              <a-collapse v-model="activeGroups" :bordered="false">
                <!-- 未分组 -->
                <a-collapse-panel v-if="ungroupedPositions.length > 0" key="__ungrouped__" class="group-panel">
                  <template slot="header">
                    <div class="group-header">
                      <span class="group-name">
                        <a-icon type="inbox" style="margin-right: 8px;" />
                        {{ $t('portfolio.groups.ungrouped') }}
                      </span>
                      <span class="group-stats">
                        <span class="count">{{ ungroupedPositions.length }} {{ $t('portfolio.positions.items') }}</span>
                        <span class="group-pnl" :class="getGroupPnl(ungroupedPositions) >= 0 ? 'positive' : 'negative'">
                          {{ getGroupPnl(ungroupedPositions) >= 0 ? '+' : '' }}${{ formatNumber(getGroupPnl(ungroupedPositions)) }}
                        </span>
                      </span>
                    </div>
                  </template>
                  <div class="position-grid compact">
                    <div
                      v-for="pos in ungroupedPositions"
                      :key="pos.id"
                      class="position-card compact"
                      :class="{ 'profit': pos.pnl >= 0, 'loss': pos.pnl < 0 }"
                    >
                      <div class="position-header">
                        <div class="symbol-info">
                          <a-tag :color="getMarketColor(pos.market)" size="small">{{ getMarketName(pos.market) }}</a-tag>
                          <span class="symbol">{{ pos.symbol }}</span>
                          <span class="name">{{ pos.name }}</span>
                        </div>
                        <div class="position-actions">
                          <a-button type="link" size="small" @click="editPosition(pos)">
                            <a-icon type="edit" />
                          </a-button>
                          <a-popconfirm :title="$t('portfolio.positions.deleteConfirm')" @confirm="deletePosition(pos.id)">
                            <a-button type="link" size="small" class="delete-btn"><a-icon type="delete" /></a-button>
                          </a-popconfirm>
                        </div>
                      </div>
                      <div class="position-compact-body">
                        <div class="compact-item">
                          <span class="value">{{ getCurrencySymbol(pos.market) }}{{ formatPrice(pos.current_price) }}</span>
                          <span class="change" :class="pos.price_change >= 0 ? 'up' : 'down'">
                            {{ pos.price_change >= 0 ? '▲' : '▼' }}{{ Math.abs(pos.price_change_percent).toFixed(2) }}%
                          </span>
                        </div>
                        <div class="compact-item">
                          <span class="label">{{ $t('portfolio.positions.quantity') }}:</span>
                          <span class="value">{{ formatNumber(pos.quantity, 4) }}</span>
                        </div>
                        <div class="compact-item pnl" :class="pos.pnl >= 0 ? 'positive' : 'negative'">
                          {{ pos.pnl >= 0 ? '+' : '' }}{{ getCurrencySymbol(pos.market) }}{{ formatNumber(pos.pnl) }}
                          <span class="percent">({{ pos.pnl_percent >= 0 ? '+' : '' }}{{ pos.pnl_percent }}%)</span>
                        </div>
                      </div>
                    </div>
                  </div>
                </a-collapse-panel>

                <!-- 各分组 -->
                <a-collapse-panel v-for="group in groupsWithPositions" :key="group.name" class="group-panel">
                  <template slot="header">
                    <div class="group-header">
                      <span class="group-name">
                        <a-icon type="folder" style="margin-right: 8px; color: #1890ff;" />
                        {{ group.name }}
                      </span>
                      <span class="group-stats">
                        <span class="count">{{ group.positions.length }} {{ $t('portfolio.positions.items') }}</span>
                        <span class="group-pnl" :class="getGroupPnl(group.positions) >= 0 ? 'positive' : 'negative'">
                          {{ getGroupPnl(group.positions) >= 0 ? '+' : '' }}${{ formatNumber(getGroupPnl(group.positions)) }}
                        </span>
                      </span>
                    </div>
                  </template>
                  <div class="position-grid compact">
                    <div
                      v-for="pos in group.positions"
                      :key="pos.id"
                      class="position-card compact"
                      :class="{ 'profit': pos.pnl >= 0, 'loss': pos.pnl < 0 }"
                    >
                      <div class="position-header">
                        <div class="symbol-info">
                          <a-tag :color="getMarketColor(pos.market)" size="small">{{ getMarketName(pos.market) }}</a-tag>
                          <span class="symbol">{{ pos.symbol }}</span>
                          <span class="name">{{ pos.name }}</span>
                        </div>
                        <div class="position-actions">
                          <a-button type="link" size="small" @click="editPosition(pos)">
                            <a-icon type="edit" />
                          </a-button>
                          <a-popconfirm :title="$t('portfolio.positions.deleteConfirm')" @confirm="deletePosition(pos.id)">
                            <a-button type="link" size="small" class="delete-btn"><a-icon type="delete" /></a-button>
                          </a-popconfirm>
                        </div>
                      </div>
                      <div class="position-compact-body">
                        <div class="compact-item">
                          <span class="value">{{ getCurrencySymbol(pos.market) }}{{ formatPrice(pos.current_price) }}</span>
                          <span class="change" :class="pos.price_change >= 0 ? 'up' : 'down'">
                            {{ pos.price_change >= 0 ? '▲' : '▼' }}{{ Math.abs(pos.price_change_percent).toFixed(2) }}%
                          </span>
                        </div>
                        <div class="compact-item">
                          <span class="label">{{ $t('portfolio.positions.quantity') }}:</span>
                          <span class="value">{{ formatNumber(pos.quantity, 4) }}</span>
                        </div>
                        <div class="compact-item pnl" :class="pos.pnl >= 0 ? 'positive' : 'negative'">
                          {{ pos.pnl >= 0 ? '+' : '' }}{{ getCurrencySymbol(pos.market) }}{{ formatNumber(pos.pnl) }}
                          <span class="percent">({{ pos.pnl_percent >= 0 ? '+' : '' }}{{ pos.pnl_percent }}%)</span>
                        </div>
                      </div>
                    </div>
                  </div>
                </a-collapse-panel>
              </a-collapse>
            </div>
          </div>
        </a-spin>
      </div>

      <!-- 监控任务 -->
      <div class="monitors-section">
        <div class="section-header">
          <h3>
            <a-icon type="eye" />
            <span>{{ $t('portfolio.monitors.title') }}</span>
          </h3>
          <a-button type="primary" @click="showAddMonitorModal = true">
            <a-icon type="plus" />
            {{ $t('portfolio.monitors.add') }}
          </a-button>
        </div>

        <a-spin :spinning="loadingMonitors">
          <div class="monitors-list">
            <div v-if="monitors.length === 0" class="empty-state small">
              <a-empty :description="$t('portfolio.monitors.empty')" :image="simpleImage">
                <a-button type="primary" size="small" @click="showAddMonitorModal = true">
                  <a-icon type="plus" />
                  {{ $t('portfolio.monitors.addFirst') }}
                </a-button>
              </a-empty>
            </div>

            <div v-else>
              <div v-for="monitor in monitors" :key="monitor.id" class="monitor-card">
                <div class="monitor-header">
                  <div class="monitor-name">
                    <a-icon type="robot" />
                    <span>{{ monitor.name }}</span>
                  </div>
                  <a-switch
                    :checked="monitor.is_active"
                    @change="toggleMonitor(monitor.id, $event)"
                    size="small"
                  />
                </div>
                <div class="monitor-body">
                  <div class="monitor-info">
                    <span class="label">{{ $t('portfolio.monitors.interval') }}:</span>
                    <span class="value">{{ getIntervalText(monitor.config.interval_minutes) }}</span>
                  </div>
                  <div class="monitor-info">
                    <span class="label">{{ $t('portfolio.form.monitorScope') }}:</span>
                    <span class="value">
                      <template v-if="getMonitorPositionIds(monitor).length > 0">
                        <a-tooltip>
                          <template slot="title">
                            <div v-for="posId in getMonitorPositionIds(monitor)" :key="posId">
                              {{ getPositionNameById(posId) }}
                            </div>
                          </template>
                          <span class="scope-selected">
                            {{ $t('portfolio.form.selectedCount', { count: getMonitorPositionIds(monitor).length, total: positions.length }) }}
                          </span>
                        </a-tooltip>
                      </template>
                      <span v-else class="scope-all">{{ $t('portfolio.form.allPositions') }}</span>
                    </span>
                  </div>
                  <div class="monitor-info" v-if="monitor.last_run_at">
                    <span class="label">{{ $t('portfolio.monitors.lastRun') }}:</span>
                    <span class="value">{{ formatTime(monitor.last_run_at) }}</span>
                  </div>
                  <div class="monitor-info" v-if="monitor.next_run_at && monitor.is_active">
                    <span class="label">{{ $t('portfolio.monitors.nextRun') }}:</span>
                    <span class="value">{{ formatTime(monitor.next_run_at) }}</span>
                  </div>
                  <div class="monitor-channels" v-if="monitor.notification_config.channels">
                    <span class="label">{{ $t('portfolio.monitors.channels') }}:</span>
                    <a-tag v-for="ch in monitor.notification_config.channels" :key="ch" size="small">
                      {{ ch }}
                    </a-tag>
                  </div>
                </div>
                <div class="monitor-actions">
                  <a-button type="link" size="small" @click="runMonitorNow(monitor.id)" :loading="runningMonitor === monitor.id">
                    <a-icon type="play-circle" />
                    {{ $t('portfolio.monitors.runNow') }}
                  </a-button>
                  <a-button type="link" size="small" @click="editMonitor(monitor)">
                    <a-icon type="edit" />
                  </a-button>
                  <a-popconfirm
                    :title="$t('portfolio.monitors.deleteConfirm')"
                    @confirm="deleteMonitor(monitor.id)"
                  >
                    <a-button type="link" size="small" class="delete-btn">
                      <a-icon type="delete" />
                    </a-button>
                  </a-popconfirm>
                </div>
              </div>
            </div>
          </div>
        </a-spin>
      </div>
    </div>

    <!-- 添加/编辑持仓弹窗 -->
    <a-modal
      :title="editingPosition ? $t('portfolio.modal.editPosition') : $t('portfolio.modal.addPosition')"
      :visible="showAddPositionModal"
      @ok="handleSavePosition"
      @cancel="closePositionModal"
      :confirmLoading="savingPosition"
      width="600px"
    >
      <a-form :form="positionForm" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
        <!-- 市场类型 -->
        <a-form-item :label="$t('portfolio.form.market')">
          <a-select
            v-decorator="['market', { rules: [{ required: true, message: $t('portfolio.form.marketRequired') }] }]"
            :placeholder="$t('portfolio.form.selectMarket')"
            @change="handleMarketChange"
            :disabled="!!editingPosition"
          >
            <a-select-option v-for="mt in marketTypes" :key="mt.value" :value="mt.value">
              {{ $t(mt.i18nKey) }}
            </a-select-option>
          </a-select>
        </a-form-item>

        <!-- 标的搜索/选择 -->
        <a-form-item :label="$t('portfolio.form.symbol')">
          <a-select
            v-decorator="['symbol', { rules: [{ required: true, message: $t('portfolio.form.symbolRequired') }] }]"
            show-search
            :placeholder="$t('portfolio.form.searchSymbol')"
            :default-active-first-option="false"
            :show-arrow="false"
            :filter-option="false"
            :not-found-content="null"
            @search="handleSymbolSearch"
            @change="handleSymbolSelect"
            :disabled="!!editingPosition"
            style="width: 100%"
          >
            <!-- 搜索结果选项 -->
            <a-select-option v-for="item in symbolSearchResults" :key="item.symbol" :value="item.symbol">
              <div class="symbol-option">
                <strong>{{ item.symbol }}</strong>
                <span class="symbol-name">{{ item.name }}</span>
              </div>
            </a-select-option>
            <!-- 手动输入选项：当搜索无结果且有输入时显示 -->
            <a-select-option
              v-if="symbolSearchKeyword && symbolSearchResults.length === 0"
              :key="'__manual__' + symbolSearchKeyword.toUpperCase()"
              :value="symbolSearchKeyword.toUpperCase()"
            >
              <div class="symbol-option manual-input">
                <a-icon type="edit" style="margin-right: 6px; color: #1890ff;" />
                <span>{{ $t('portfolio.form.useAsSymbol') }} </span>
                <strong style="color: #1890ff;">{{ symbolSearchKeyword.toUpperCase() }}</strong>
                <span> {{ $t('portfolio.form.asSymbolCode') }}</span>
              </div>
            </a-select-option>
          </a-select>
          <div class="symbol-hint" style="font-size: 12px; color: #999; margin-top: 4px;">
            {{ $t('portfolio.form.symbolHint') }}
          </div>
        </a-form-item>

        <!-- 方向 -->
        <a-form-item :label="$t('portfolio.form.side')">
          <a-radio-group v-decorator="['side', { initialValue: 'long' }]" :disabled="!!editingPosition">
            <a-radio-button value="long">{{ $t('portfolio.positions.long') }}</a-radio-button>
            <a-radio-button value="short">{{ $t('portfolio.positions.short') }}</a-radio-button>
          </a-radio-group>
        </a-form-item>

        <!-- 数量 -->
        <a-form-item :label="$t('portfolio.form.quantity')">
          <a-input-number
            v-decorator="['quantity', { rules: [{ required: true, message: $t('portfolio.form.quantityRequired') }] }]"
            :min="0.00000001"
            :step="1"
            style="width: 100%"
            :placeholder="$t('portfolio.form.enterQuantity')"
          />
        </a-form-item>

        <!-- 买入价 -->
        <a-form-item :label="$t('portfolio.form.entryPrice')">
          <a-input-number
            v-decorator="['entry_price', { rules: [{ required: true, message: $t('portfolio.form.entryPriceRequired') }] }]"
            :min="0.00000001"
            :step="0.01"
            style="width: 100%"
            :placeholder="$t('portfolio.form.enterEntryPrice')"
          />
        </a-form-item>

        <!-- 备注 -->
        <a-form-item :label="$t('portfolio.form.notes')">
          <a-textarea
            v-decorator="['notes']"
            :rows="2"
            :placeholder="$t('portfolio.form.enterNotes')"
          />
        </a-form-item>

        <!-- 分组 -->
        <a-form-item :label="$t('portfolio.form.group')">
          <a-auto-complete
            v-decorator="['group_name']"
            :placeholder="$t('portfolio.form.enterGroup')"
            :dataSource="groupNames"
          />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 添加/编辑预警弹窗 -->
    <a-modal
      :title="editingAlert ? $t('portfolio.modal.editAlert') : $t('portfolio.modal.addAlert')"
      :visible="showAddAlertModal"
      @cancel="closeAlertModal"
      width="560px"
    >
      <!-- 自定义 Footer -->
      <template slot="footer">
        <div class="alert-modal-footer">
          <a-button
            v-if="editingAlert"
            type="danger"
            ghost
            :loading="deletingAlert"
            @click="confirmDeleteAlert"
          >
            <a-icon type="delete" />
            {{ $t('portfolio.alerts.delete') }}
          </a-button>
          <span v-else></span>
          <div class="footer-right">
            <a-button @click="closeAlertModal">{{ $t('common.cancel') }}</a-button>
            <a-button type="primary" :loading="savingAlert" @click="handleSaveAlert">
              {{ $t('common.save') }}
            </a-button>
          </div>
        </div>
      </template>
      <a-form :form="alertForm" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
        <!-- 标的信息 -->
        <a-form-item :label="$t('portfolio.form.symbol')">
          <div class="alert-symbol-info">
            <a-input
              v-decorator="['symbol']"
              disabled
              class="symbol-input"
            />
            <div class="current-price-info" v-if="alertPosition">
              <span class="label">{{ $t('portfolio.alerts.currentPrice') }}:</span>
              <span class="price">${{ formatNumber(alertPosition.current_price || alertPosition.entry_price) }}</span>
            </div>
          </div>
        </a-form-item>

        <!-- 预警类型 -->
        <a-form-item :label="$t('portfolio.alerts.alertType')">
          <a-select
            v-decorator="['alert_type', { initialValue: 'price_above', rules: [{ required: true }] }]"
          >
            <a-select-option value="price_above">
              <a-icon type="rise" style="color: #52c41a; margin-right: 6px;" />
              {{ $t('portfolio.alerts.priceAbove') }}
            </a-select-option>
            <a-select-option value="price_below">
              <a-icon type="fall" style="color: #f5222d; margin-right: 6px;" />
              {{ $t('portfolio.alerts.priceBelow') }}
            </a-select-option>
            <a-select-option value="pnl_above">
              <a-icon type="dollar" style="color: #52c41a; margin-right: 6px;" />
              {{ $t('portfolio.alerts.pnlAbove') }}
            </a-select-option>
            <a-select-option value="pnl_below">
              <a-icon type="dollar" style="color: #f5222d; margin-right: 6px;" />
              {{ $t('portfolio.alerts.pnlBelow') }}
            </a-select-option>
          </a-select>
        </a-form-item>

        <!-- 阈值 -->
        <a-form-item :label="$t('portfolio.alerts.threshold')">
          <div class="threshold-input-wrapper">
            <a-input-number
              v-decorator="['threshold', { rules: [{ required: true, message: $t('portfolio.alerts.thresholdRequired') }] }]"
              :step="alertTypeIsPrice ? 0.01 : 1"
              style="width: 100%"
              :placeholder="alertTypeIsPrice ? $t('portfolio.alerts.enterPrice') : $t('portfolio.alerts.enterPercent')"
              :precision="alertTypeIsPrice ? 4 : 2"
            />
            <span class="alert-unit" v-if="!alertTypeIsPrice">%</span>
            <span class="alert-unit" v-else>$</span>
          </div>
          <div class="threshold-hint" v-if="alertPosition && alertTypeIsPrice">
            {{ $t('portfolio.alerts.currentPriceHint') }}: ${{ formatNumber(alertPosition.current_price || alertPosition.entry_price) }}
          </div>
        </a-form-item>

        <!-- 重复提醒 -->
        <a-form-item :label="$t('portfolio.alerts.repeatInterval')">
          <a-select
            v-decorator="['repeat_interval', { initialValue: 0 }]"
          >
            <a-select-option :value="0">{{ $t('portfolio.alerts.noRepeat') }}</a-select-option>
            <a-select-option :value="5">{{ $t('portfolio.alerts.every5min') }}</a-select-option>
            <a-select-option :value="15">{{ $t('portfolio.alerts.every15min') }}</a-select-option>
            <a-select-option :value="30">{{ $t('portfolio.alerts.every30min') }}</a-select-option>
            <a-select-option :value="60">{{ $t('portfolio.alerts.every1hour') }}</a-select-option>
            <a-select-option :value="240">{{ $t('portfolio.alerts.every4hours') }}</a-select-option>
            <a-select-option :value="1440">{{ $t('portfolio.alerts.onceDaily') }}</a-select-option>
          </a-select>
        </a-form-item>

        <!-- 通知渠道 - 使用 v-model 直接绑定 -->
        <a-form-item :label="$t('portfolio.form.notifyChannels')">
          <a-checkbox-group v-model="alertChannels">
            <a-checkbox value="browser">
              <a-icon type="bell" />
              {{ $t('portfolio.form.browser') }}
            </a-checkbox>
            <a-checkbox value="telegram">
              <a-icon type="message" />
              Telegram
            </a-checkbox>
            <a-checkbox value="email">
              <a-icon type="mail" />
              {{ $t('portfolio.form.email') }}
            </a-checkbox>
          </a-checkbox-group>
        </a-form-item>

        <!-- Telegram Chat ID -->
        <a-form-item
          v-show="alertChannels.includes('telegram')"
          :label="$t('portfolio.form.telegramChatId')"
        >
          <a-input
            v-model="alertTelegramChatId"
            :placeholder="$t('portfolio.form.enterTelegramChatId')"
          >
            <a-icon slot="prefix" type="message" />
          </a-input>
        </a-form-item>

        <!-- Email -->
        <a-form-item
          v-show="alertChannels.includes('email')"
          :label="$t('portfolio.form.emailAddress')"
        >
          <a-input
            v-model="alertEmail"
            :placeholder="$t('portfolio.form.enterEmail')"
          >
            <a-icon slot="prefix" type="mail" />
          </a-input>
        </a-form-item>

        <!-- 启用状态 -->
        <a-form-item :label="$t('portfolio.alerts.enabled')">
          <a-switch
            v-decorator="['is_active', { initialValue: true, valuePropName: 'checked' }]"
          />
          <span class="switch-label">{{ $t('portfolio.alerts.enabledDesc') }}</span>
        </a-form-item>

        <!-- 备注 -->
        <a-form-item :label="$t('portfolio.form.notes')">
          <a-textarea
            v-decorator="['notes']"
            :placeholder="$t('portfolio.form.enterNotes')"
            :autoSize="{ minRows: 2, maxRows: 4 }"
          />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 添加/编辑监控弹窗 -->
    <a-modal
      :title="editingMonitor ? $t('portfolio.modal.editMonitor') : $t('portfolio.modal.addMonitor')"
      :visible="showAddMonitorModal"
      @ok="handleSaveMonitor"
      @cancel="closeMonitorModal"
      :confirmLoading="savingMonitor"
      width="600px"
    >
      <a-form :form="monitorForm" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
        <!-- 监控名称 -->
        <a-form-item :label="$t('portfolio.form.monitorName')">
          <a-input
            v-decorator="['name', { rules: [{ required: true, message: $t('portfolio.form.monitorNameRequired') }] }]"
            :placeholder="$t('portfolio.form.enterMonitorName')"
          />
        </a-form-item>

        <!-- 执行间隔 -->
        <a-form-item :label="$t('portfolio.form.interval')">
          <a-select
            v-decorator="['interval_minutes', { initialValue: 60, rules: [{ required: true }] }]"
          >
            <a-select-option :value="5">5 {{ $t('portfolio.form.minutes') }}</a-select-option>
            <a-select-option :value="10">10 {{ $t('portfolio.form.minutes') }}</a-select-option>
            <a-select-option :value="30">30 {{ $t('portfolio.form.minutes') }}</a-select-option>
            <a-select-option :value="60">1 {{ $t('portfolio.form.hour') }}</a-select-option>
            <a-select-option :value="120">2 {{ $t('portfolio.form.hours') }}</a-select-option>
            <a-select-option :value="240">4 {{ $t('portfolio.form.hours') }}</a-select-option>
            <a-select-option :value="480">8 {{ $t('portfolio.form.hours') }}</a-select-option>
            <a-select-option :value="1440">24 {{ $t('portfolio.form.hours') }}</a-select-option>
          </a-select>
        </a-form-item>

        <!-- 通知渠道 - 使用 v-model 直接绑定 -->
        <a-form-item :label="$t('portfolio.form.notifyChannels')">
          <a-checkbox-group v-model="monitorChannels">
            <a-checkbox value="browser">{{ $t('portfolio.form.browser') }}</a-checkbox>
            <a-checkbox value="telegram">Telegram</a-checkbox>
            <a-checkbox value="email">{{ $t('portfolio.form.email') }}</a-checkbox>
          </a-checkbox-group>
        </a-form-item>

        <!-- Telegram Chat ID -->
        <a-form-item :label="$t('portfolio.form.telegramChatId')" v-show="monitorChannels.includes('telegram')">
          <a-input
            v-model="monitorTelegramChatId"
            :placeholder="$t('portfolio.form.enterTelegramChatId')"
          />
        </a-form-item>

        <!-- Email -->
        <a-form-item :label="$t('portfolio.form.emailAddress')" v-show="monitorChannels.includes('email')">
          <a-input
            v-model="monitorEmail"
            :placeholder="$t('portfolio.form.enterEmail')"
          />
        </a-form-item>

        <!-- 监控范围 -->
        <a-form-item :label="$t('portfolio.form.monitorScope')">
          <a-radio-group v-model="monitorScope" @change="handleMonitorScopeChange">
            <a-radio value="all">{{ $t('portfolio.form.allPositions') }}</a-radio>
            <a-radio value="selected">{{ $t('portfolio.form.selectedPositions') }}</a-radio>
          </a-radio-group>
        </a-form-item>

        <!-- 选择持仓 -->
        <a-form-item
          :label="$t('portfolio.form.selectPositions')"
          v-if="monitorScope === 'selected'"
        >
          <a-checkbox-group
            v-model="selectedMonitorPositions"
            class="position-checkbox-group"
          >
            <div
              v-for="pos in positions"
              :key="pos.id"
              class="position-checkbox-item"
            >
              <a-checkbox :value="pos.id">
                <span class="position-checkbox-label">
                  <a-tag :color="getMarketColor(pos.market)" size="small">{{ pos.market }}</a-tag>
                  <span class="symbol">{{ pos.symbol }}</span>
                  <span class="name">{{ pos.name }}</span>
                  <span :class="['pnl', pos.pnl >= 0 ? 'positive' : 'negative']">
                    {{ pos.pnl >= 0 ? '+' : '' }}{{ formatNumber(pos.pnl_percent) }}%
                  </span>
                </span>
              </a-checkbox>
            </div>
          </a-checkbox-group>
          <div class="position-select-actions">
            <a-button type="link" size="small" @click="selectAllPositions">
              {{ $t('portfolio.form.selectAll') }}
            </a-button>
            <a-divider type="vertical" />
            <a-button type="link" size="small" @click="deselectAllPositions">
              {{ $t('portfolio.form.deselectAll') }}
            </a-button>
            <span class="selected-count">
              {{ $t('portfolio.form.selectedCount', { count: selectedMonitorPositions.length, total: positions.length }) }}
            </span>
          </div>
        </a-form-item>

        <!-- 自定义提示 -->
        <a-form-item :label="$t('portfolio.form.customPrompt')">
          <a-textarea
            v-decorator="['prompt']"
            :rows="3"
            :placeholder="$t('portfolio.form.customPromptPlaceholder')"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import { Empty } from 'ant-design-vue'
import {
  getPositions, addPosition, updatePosition, deletePosition as deletePositionApi,
  getPortfolioSummary,
  getMonitors, addMonitor, updateMonitor, deleteMonitor as deleteMonitorApi, runMonitor,
  getAlerts, addAlert, updateAlert, deleteAlert as deleteAlertApi,
  getGroups,
  searchSymbols, getMarketTypes
} from '@/api/portfolio'

export default {
  name: 'Portfolio',
  data () {
    return {
      simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
      // Summary
      summary: {
        total_cost: 0,
        total_market_value: 0,
        total_pnl: 0,
        total_pnl_percent: 0,
        position_count: 0,
        market_distribution: [],
        today_pnl: 0,
        today_change: 0
      },
      // Positions
      positions: [],
      loadingPositions: false,
      showAddPositionModal: false,
      savingPosition: false,
      editingPosition: null,
      positionForm: null,
      // Monitors
      monitors: [],
      loadingMonitors: false,
      showAddMonitorModal: false,
      savingMonitor: false,
      editingMonitor: null,
      monitorForm: null,
      runningMonitor: null,
      // Market types
      marketTypes: [],
      // Symbol search
      symbolSearchResults: [],
      searchTimer: null,
      selectedSymbolName: '',
      symbolSearchKeyword: '', // 当前搜索关键词，用于手动输入
      // Price refresh
      priceRefreshTimer: null,
      lastSyncTime: null, // 最后同步时间
      isSyncing: false, // 是否正在同步
      // Groups
      groups: [],
      selectedGroup: '',
      // View mode
      viewMode: 'grid', // 'grid' or 'group'
      activeGroups: [], // 折叠面板展开的分组
      // Alerts
      alerts: [],
      loadingAlerts: false,
      showAddAlertModal: false,
      savingAlert: false,
      deletingAlert: false,
      editingAlert: null,
      alertForm: null,
      alertPosition: null,
      // Alert channels (for reactive display)
      alertChannels: ['browser'],
      // Alert notification targets
      alertTelegramChatId: '',
      alertEmail: '',
      // Monitor channels (for reactive display)
      monitorChannels: ['browser'],
      // Monitor notification targets
      monitorTelegramChatId: '',
      monitorEmail: '',
      // Monitor scope (all or selected positions)
      monitorScope: 'all',
      // Selected positions for monitoring
      selectedMonitorPositions: []
    }
  },
  computed: {
    ...mapState({
      navTheme: state => state.app.theme
    }),
    isDarkTheme () {
      return this.navTheme === 'dark' || this.navTheme === 'realdark'
    },
    selectedChannels () {
      return this.monitorChannels || []
    },
    selectedAlertChannels () {
      return this.alertChannels || []
    },
    filteredPositions () {
      if (!this.selectedGroup) {
        return this.positions
      }
      if (this.selectedGroup === '__ungrouped__') {
        return this.positions.filter(p => !p.group_name)
      }
      return this.positions.filter(p => p.group_name === this.selectedGroup)
    },
    groupNames () {
      return this.groups.map(g => g.name)
    },
    alertTypeIsPrice () {
      if (!this.alertForm) return true
      const alertType = this.alertForm.getFieldValue('alert_type')
      return alertType && alertType.startsWith('price_')
    },
    // 盈利/亏损持仓统计
    profitLossStats () {
      const profit = this.positions.filter(p => p.pnl >= 0).length
      const loss = this.positions.filter(p => p.pnl < 0).length
      return { profit, loss }
    },
    // 最佳表现持仓
    bestPerformer () {
      if (this.positions.length === 0) return null
      return this.positions.reduce((best, pos) => {
        if (!best || (pos.pnl_percent || 0) > (best.pnl_percent || 0)) return pos
        return best
      }, null)
    },
    // 最差表现持仓
    worstPerformer () {
      if (this.positions.length === 0) return null
      return this.positions.reduce((worst, pos) => {
        if (!worst || (pos.pnl_percent || 0) < (worst.pnl_percent || 0)) return pos
        return worst
      }, null)
    },
    // 未分组持仓
    ungroupedPositions () {
      return this.positions.filter(p => !p.group_name)
    },
    // 按分组整理的持仓
    groupsWithPositions () {
      const groupMap = {}
      this.positions.forEach(pos => {
        if (pos.group_name) {
          if (!groupMap[pos.group_name]) {
            groupMap[pos.group_name] = {
              name: pos.group_name,
              positions: []
            }
          }
          groupMap[pos.group_name].positions.push(pos)
        }
      })
      return Object.values(groupMap).sort((a, b) => a.name.localeCompare(b.name))
    }
  },
  created () {
    this.positionForm = this.$form.createForm(this, { name: 'position_form' })
    this.monitorForm = this.$form.createForm(this, { name: 'monitor_form' })
    this.alertForm = this.$form.createForm(this, { name: 'alert_form' })
    this.loadMarketTypes()
    this.loadData()
  },
  mounted () {
    // Refresh prices every 30 seconds
    this.priceRefreshTimer = setInterval(() => {
      this.refreshPrices()
    }, 30000)
  },
  beforeDestroy () {
    if (this.priceRefreshTimer) {
      clearInterval(this.priceRefreshTimer)
    }
    if (this.searchTimer) {
      clearTimeout(this.searchTimer)
    }
  },
  methods: {
    async loadData () {
      await Promise.all([
        this.loadPositions(),
        this.loadSummary(),
        this.loadMonitors(),
        this.loadGroups(),
        this.loadAlerts()
      ])
      this.lastSyncTime = new Date()
    },
    filterByGroup () {
      // Filter is handled by computed property
    },
    // 刷新价格
    async refreshPrices () {
      if (this.isSyncing) return
      this.isSyncing = true
      try {
        await Promise.all([
          this.loadPositions(),
          this.loadSummary()
        ])
        this.lastSyncTime = new Date()
      } finally {
        this.isSyncing = false
      }
    },
    // 格式化同步时间
    formatSyncTime (time) {
      if (!time) return '-'
      const now = new Date()
      const diff = Math.floor((now - time) / 1000)
      if (diff < 60) return this.$t('portfolio.summary.justNow')
      if (diff < 3600) return `${Math.floor(diff / 60)} ${this.$t('portfolio.form.minutes')}${this.$t('portfolio.summary.ago')}`
      return time.toLocaleTimeString()
    },
    // 计算分组总盈亏
    getGroupPnl (positions) {
      return positions.reduce((sum, pos) => sum + (pos.pnl || 0), 0)
    },
    async loadGroups () {
      try {
        const res = await getGroups()
        if (res && res.code === 1 && res.data) {
          this.groups = res.data.groups || []
        }
      } catch (e) {
        console.error('Failed to load groups:', e)
      }
    },
    async loadAlerts () {
      this.loadingAlerts = true
      try {
        const res = await getAlerts()
        if (res && res.code === 1) {
          this.alerts = res.data || []
        }
      } catch (e) {
        console.error('Failed to load alerts:', e)
      } finally {
        this.loadingAlerts = false
      }
    },
    async loadMarketTypes () {
      try {
        const res = await getMarketTypes()
        if (res && res.code === 1 && res.data) {
          this.marketTypes = res.data.map(item => ({
            value: item.value,
            i18nKey: item.i18nKey || `dashboard.analysis.market.${item.value}`
          }))
        }
      } catch (e) {
        this.marketTypes = [
          { value: 'USStock', i18nKey: 'dashboard.analysis.market.USStock' },
          { value: 'Crypto', i18nKey: 'dashboard.analysis.market.Crypto' },
          { value: 'AShare', i18nKey: 'dashboard.analysis.market.AShare' },
          { value: 'HShare', i18nKey: 'dashboard.analysis.market.HShare' },
          { value: 'Forex', i18nKey: 'dashboard.analysis.market.Forex' },
          { value: 'Futures', i18nKey: 'dashboard.analysis.market.Futures' }
        ]
      }
    },
    async loadPositions () {
      this.loadingPositions = true
      try {
        const res = await getPositions()
        if (res && res.code === 1) {
          this.positions = res.data || []
        }
      } catch (e) {
        this.$message.error(this.$t('portfolio.message.loadFailed'))
      } finally {
        this.loadingPositions = false
      }
    },
    async loadSummary () {
      try {
        const res = await getPortfolioSummary()
        if (res && res.code === 1) {
          this.summary = res.data || this.summary
        }
      } catch (e) {
        console.error('Failed to load summary:', e)
      }
    },
    async loadMonitors () {
      this.loadingMonitors = true
      try {
        const res = await getMonitors()
        if (res && res.code === 1) {
          this.monitors = res.data || []
        }
      } catch (e) {
        console.error('Failed to load monitors:', e)
      } finally {
        this.loadingMonitors = false
      }
    },
    // Position methods
    handleMarketChange (value) {
      this.symbolSearchResults = []
      this.symbolSearchKeyword = ''
      this.positionForm.setFieldsValue({ symbol: '' })
    },
    handleSymbolSearch (value) {
      // 保存搜索关键词，用于手动输入功能
      this.symbolSearchKeyword = value || ''

      if (this.searchTimer) {
        clearTimeout(this.searchTimer)
      }
      if (!value || value.length < 1) {
        this.symbolSearchResults = []
        return
      }
      this.searchTimer = setTimeout(async () => {
        const market = this.positionForm.getFieldValue('market')
        if (!market) return
        try {
          const res = await searchSymbols({ market, keyword: value, limit: 10 })
          if (res && res.code === 1) {
            this.symbolSearchResults = res.data || []
          } else {
            // 搜索无结果，清空列表但保留关键词供手动输入
            this.symbolSearchResults = []
          }
        } catch (e) {
          // 搜索失败，也允许手动输入
          this.symbolSearchResults = []
        }
      }, 300)
    },
    handleSymbolSelect (value, option) {
      // 先从搜索结果中查找
      const item = this.symbolSearchResults.find(s => s.symbol === value)
      if (item) {
        this.selectedSymbolName = item.name
      } else {
        // 手动输入的情况，名称留空，后端会尝试获取
        this.selectedSymbolName = ''
      }
      // 清空搜索关键词
      this.symbolSearchKeyword = ''
    },
    editPosition (pos) {
      this.editingPosition = pos
      this.showAddPositionModal = true
      this.$nextTick(() => {
        this.positionForm.setFieldsValue({
          market: pos.market,
          symbol: pos.symbol,
          side: pos.side,
          quantity: pos.quantity,
          entry_price: pos.entry_price,
          notes: pos.notes,
          group_name: pos.group_name || ''
        })
      })
    },
    async handleSavePosition () {
      this.positionForm.validateFields(async (err, values) => {
        if (err) return
        this.savingPosition = true
        try {
          const data = {
            market: values.market,
            symbol: values.symbol.toUpperCase(),
            side: values.side,
            quantity: values.quantity,
            entry_price: values.entry_price,
            notes: values.notes || '',
            name: this.selectedSymbolName || '',
            group_name: values.group_name || ''
          }

          let res
          if (this.editingPosition) {
            res = await updatePosition(this.editingPosition.id, data)
          } else {
            res = await addPosition(data)
          }

          if (res && res.code === 1) {
            this.$message.success(this.$t('portfolio.message.saveSuccess'))
            this.closePositionModal()
            this.loadData()
          } else {
            this.$message.error(res?.msg || this.$t('portfolio.message.saveFailed'))
          }
        } catch (e) {
          this.$message.error(this.$t('portfolio.message.saveFailed'))
        } finally {
          this.savingPosition = false
        }
      })
    },
    async deletePosition (id) {
      try {
        const res = await deletePositionApi(id)
        if (res && res.code === 1) {
          this.$message.success(this.$t('portfolio.message.deleteSuccess'))
          this.loadData()
        } else {
          this.$message.error(res?.msg || this.$t('portfolio.message.deleteFailed'))
        }
      } catch (e) {
        this.$message.error(this.$t('portfolio.message.deleteFailed'))
      }
    },
    closePositionModal () {
      this.showAddPositionModal = false
      this.editingPosition = null
      this.positionForm.resetFields()
      this.symbolSearchResults = []
      this.selectedSymbolName = ''
      this.symbolSearchKeyword = ''
    },
    // Alert methods
    handleAlertChannelsChange (channels) {
      this.alertChannels = channels || []
    },
    showAddAlertForPosition (pos) {
      // 检查是否已存在该持仓的 Alert，如果存在则编辑
      const existingAlert = this.alerts.find(a => a.position_id === pos.id)
      if (existingAlert) {
        // 编辑已存在的 Alert
        this.editAlert(existingAlert)
        return
      }
      // 创建新的 Alert
      this.editingAlert = null
      this.alertPosition = pos
      this.alertChannels = ['browser']
      this.alertTelegramChatId = ''
      this.alertEmail = ''
      this.showAddAlertModal = true
      this.$nextTick(() => {
        this.alertForm.setFieldsValue({
          symbol: `${pos.market}/${pos.symbol}`,
          alert_type: 'price_above',
          threshold: pos.current_price || pos.entry_price,
          repeat_interval: 0,
          is_active: true,
          notes: ''
        })
      })
    },
    editAlert (alert) {
      this.editingAlert = alert
      // 找到对应的持仓
      this.alertPosition = this.positions.find(p => p.id === alert.position_id) || {
        market: alert.market,
        symbol: alert.symbol,
        current_price: 0,
        entry_price: 0
      }
      // Set channels and targets directly with v-model binding
      this.alertChannels = [...(alert.notification_config?.channels || ['browser'])]
      this.alertTelegramChatId = alert.notification_config?.targets?.telegram || ''
      this.alertEmail = alert.notification_config?.targets?.email || ''
      // Show modal
      this.showAddAlertModal = true
      // Set form values for fields still using v-decorator
      this.$nextTick(() => {
        if (this.alertForm) {
          this.alertForm.setFieldsValue({
            symbol: `${alert.market}/${alert.symbol}`,
            alert_type: alert.alert_type || 'price_above',
            threshold: alert.threshold || 0,
            repeat_interval: alert.repeat_interval || 0,
            is_active: alert.is_active !== false,
            notes: alert.notes || ''
          })
        }
      })
    },
    async handleSaveAlert () {
      this.alertForm.validateFields(async (err, values) => {
        if (err) return
        this.savingAlert = true
        try {
          // 构建通知目标 - 使用 v-model 绑定的值
          const targets = {}
          if (this.alertChannels.includes('telegram') && this.alertTelegramChatId) {
            targets.telegram = this.alertTelegramChatId.trim()
          }
          if (this.alertChannels.includes('email') && this.alertEmail) {
            targets.email = this.alertEmail.trim()
          }

          const data = {
            position_id: this.alertPosition?.id,
            market: this.alertPosition?.market,
            symbol: this.alertPosition?.symbol,
            alert_type: values.alert_type,
            threshold: values.threshold,
            notification_config: {
              // 使用 v-model 绑定的值
              channels: this.alertChannels.length > 0 ? this.alertChannels : ['browser'],
              targets: targets,
              language: this.$store.getters.lang || 'en-US' // 保存当前语言
            },
            is_active: values.is_active !== false,
            repeat_interval: values.repeat_interval || 0,
            notes: values.notes || ''
          }

          let res
          if (this.editingAlert) {
            res = await updateAlert(this.editingAlert.id, data)
          } else {
            res = await addAlert(data)
          }

          if (res && res.code === 1) {
            this.$message.success(this.$t('portfolio.message.saveSuccess'))
            this.closeAlertModal()
            this.loadAlerts()
          } else {
            this.$message.error(res?.msg || this.$t('portfolio.message.saveFailed'))
          }
        } catch (e) {
          this.$message.error(this.$t('portfolio.message.saveFailed'))
        } finally {
          this.savingAlert = false
        }
      })
    },
    async deleteAlert (id) {
      try {
        const res = await deleteAlertApi(id)
        if (res && res.code === 1) {
          this.$message.success(this.$t('portfolio.message.deleteSuccess'))
          this.loadAlerts()
        } else {
          this.$message.error(res?.msg || this.$t('portfolio.message.deleteFailed'))
        }
      } catch (e) {
        this.$message.error(this.$t('portfolio.message.deleteFailed'))
      }
    },
    closeAlertModal () {
      this.showAddAlertModal = false
      this.editingAlert = null
      this.alertPosition = null
      this.alertChannels = ['browser']
      this.alertTelegramChatId = ''
      this.alertEmail = ''
      this.alertForm.resetFields()
    },
    confirmDeleteAlert () {
      if (!this.editingAlert) return
      const self = this
      this.$confirm({
        title: this.$t('portfolio.alerts.deleteConfirm'),
        okText: this.$t('common.confirm'),
        okType: 'danger',
        cancelText: this.$t('common.cancel'),
        async onOk () {
          await self.handleDeleteAlert()
        }
      })
    },
    async handleDeleteAlert () {
      if (!this.editingAlert) return
      this.deletingAlert = true
      try {
        const res = await deleteAlertApi(this.editingAlert.id)
        if (res && res.code === 1) {
          this.$message.success(this.$t('portfolio.message.deleteSuccess'))
          this.closeAlertModal()
          await this.loadAlerts()
        } else {
          this.$message.error(res?.msg || this.$t('portfolio.message.deleteFailed'))
        }
      } catch (e) {
        console.error('Delete alert error:', e)
        this.$message.error(this.$t('portfolio.message.deleteFailed'))
      } finally {
        this.deletingAlert = false
      }
    },
    // Monitor methods
    handleMonitorChannelsChange (channels) {
      this.monitorChannels = channels || []
    },
    editMonitor (monitor) {
      this.editingMonitor = monitor
      // Set channels directly with v-model binding
      this.monitorChannels = [...(monitor.notification_config?.channels || ['browser'])]
      this.monitorTelegramChatId = monitor.notification_config?.targets?.telegram || ''
      this.monitorEmail = monitor.notification_config?.targets?.email || ''
      // Update monitor scope and selected positions
      let positionIds = []
      if (monitor.position_ids) {
        if (typeof monitor.position_ids === 'string') {
          try {
            positionIds = JSON.parse(monitor.position_ids) || []
          } catch (e) {
            positionIds = []
          }
        } else if (Array.isArray(monitor.position_ids)) {
          positionIds = monitor.position_ids
        }
      }
      this.monitorScope = positionIds.length > 0 ? 'selected' : 'all'
      this.selectedMonitorPositions = positionIds
      // Show modal
      this.showAddMonitorModal = true
      // Set form values for fields still using v-decorator
      this.$nextTick(() => {
        if (this.monitorForm) {
          this.monitorForm.setFieldsValue({
            name: monitor.name,
            interval_minutes: monitor.config?.interval_minutes || 60,
            prompt: monitor.config?.prompt || ''
          })
        }
      })
    },
    handleMonitorScopeChange (e) {
      this.monitorScope = e.target.value
      if (e.target.value === 'all') {
        this.selectedMonitorPositions = []
      }
    },
    selectAllPositions () {
      this.selectedMonitorPositions = this.positions.map(p => p.id)
    },
    deselectAllPositions () {
      this.selectedMonitorPositions = []
    },
    async handleSaveMonitor () {
      this.monitorForm.validateFields(async (err, values) => {
        if (err) return

        // Validate: if selected scope but no positions selected
        if (this.monitorScope === 'selected' && this.selectedMonitorPositions.length === 0) {
          this.$message.warning(this.$t('portfolio.form.pleaseSelectPositions'))
          return
        }

        this.savingMonitor = true
        try {
          const data = {
            name: values.name,
            monitor_type: 'ai',
            // position_ids as a separate field for backend
            position_ids: this.monitorScope === 'selected' ? this.selectedMonitorPositions : [],
            config: {
              interval_minutes: values.interval_minutes,
              prompt: values.prompt || '',
              language: this.$store.getters.lang || 'en-US'
            },
            notification_config: {
              // Use v-model bound values instead of form values
              channels: this.monitorChannels.length > 0 ? this.monitorChannels : ['browser'],
              targets: {
                telegram: this.monitorTelegramChatId || '',
                email: this.monitorEmail || ''
              }
            },
            is_active: true
          }

          let res
          if (this.editingMonitor) {
            res = await updateMonitor(this.editingMonitor.id, data)
          } else {
            res = await addMonitor(data)
          }

          if (res && res.code === 1) {
            this.$message.success(this.$t('portfolio.message.saveSuccess'))
            this.closeMonitorModal()
            this.loadMonitors()
          } else {
            this.$message.error(res?.msg || this.$t('portfolio.message.saveFailed'))
          }
        } catch (e) {
          this.$message.error(this.$t('portfolio.message.saveFailed'))
        } finally {
          this.savingMonitor = false
        }
      })
    },
    async toggleMonitor (id, active) {
      try {
        const res = await updateMonitor(id, { is_active: active })
        if (res && res.code === 1) {
          this.$message.success(active ? this.$t('portfolio.message.monitorEnabled') : this.$t('portfolio.message.monitorDisabled'))
          this.loadMonitors()
        }
      } catch (e) {
        this.$message.error(this.$t('portfolio.message.updateFailed'))
      }
    },
    async runMonitorNow (id) {
      this.runningMonitor = id
      try {
        // 传递当前语言给后端
        const currentLang = this.$store.getters.lang || 'en-US'
        const res = await runMonitor(id, { language: currentLang })
        if (res && res.code === 1) {
          if (res.data?.success) {
            this.$message.success(this.$t('portfolio.message.monitorRunSuccess'))
            // Show analysis result in a modal or notification
            if (res.data.analysis) {
              this.$notification.open({
                message: this.$t('portfolio.monitors.analysisResult'),
                description: res.data.analysis.substring(0, 500) + (res.data.analysis.length > 500 ? '...' : ''),
                duration: 0
              })
            }
          } else {
            this.$message.error(res.data?.error || this.$t('portfolio.message.monitorRunFailed'))
          }
          this.loadMonitors()
        }
      } catch (e) {
        this.$message.error(this.$t('portfolio.message.monitorRunFailed'))
      } finally {
        this.runningMonitor = null
      }
    },
    async deleteMonitor (id) {
      try {
        const res = await deleteMonitorApi(id)
        if (res && res.code === 1) {
          this.$message.success(this.$t('portfolio.message.deleteSuccess'))
          this.loadMonitors()
        } else {
          this.$message.error(res?.msg || this.$t('portfolio.message.deleteFailed'))
        }
      } catch (e) {
        this.$message.error(this.$t('portfolio.message.deleteFailed'))
      }
    },
    closeMonitorModal () {
      this.showAddMonitorModal = false
      this.editingMonitor = null
      this.monitorForm.resetFields()
      this.monitorChannels = ['browser'] // Reset to default
      this.monitorTelegramChatId = '' // Reset telegram
      this.monitorEmail = '' // Reset email
      this.monitorScope = 'all' // Reset monitor scope
      this.selectedMonitorPositions = [] // Reset selected positions
    },
    // Helper to get position IDs from monitor
    getMonitorPositionIds (monitor) {
      if (!monitor.position_ids) return []
      if (typeof monitor.position_ids === 'string') {
        try {
          return JSON.parse(monitor.position_ids) || []
        } catch (e) {
          return []
        }
      }
      return Array.isArray(monitor.position_ids) ? monitor.position_ids : []
    },
    // Helper to get position name by ID
    getPositionNameById (posId) {
      const pos = this.positions.find(p => p.id === posId)
      return pos ? `${pos.symbol} (${pos.name || pos.market})` : `#${posId}`
    },
    // Helpers
    hasAlertForPosition (positionId) {
      return this.alerts.some(a => a.position_id === positionId)
    },
    getAlertForPosition (positionId) {
      return this.alerts.find(a => a.position_id === positionId)
    },
    getMarketColor (market) {
      const colors = {
        'USStock': 'green',
        'Crypto': 'purple',
        'Forex': 'gold',
        'Futures': 'cyan',
        'AShare': 'blue',
        'HShare': 'orange'
      }
      return colors[market] || 'default'
    },
    getMarketName (market) {
      return this.$t(`dashboard.analysis.market.${market}`) || market
    },
    getCurrencySymbol (market) {
      const dollarMarkets = ['USStock', 'Crypto', 'Forex', 'Futures']
      return dollarMarkets.includes(market) ? '$' : '¥'
    },
    formatNumber (num, digits = 2) {
      if (num === undefined || num === null) return '0.00'
      return Number(num).toLocaleString('en-US', { minimumFractionDigits: digits, maximumFractionDigits: digits })
    },
    formatPrice (price) {
      if (!price) return '0'
      if (price >= 1000) return this.formatNumber(price, 2)
      if (price >= 1) return this.formatNumber(price, 4)
      return this.formatNumber(price, 6)
    },
    formatTime (timestamp) {
      if (!timestamp) return '-'
      const d = new Date(timestamp * 1000)
      return d.toLocaleString()
    },
    getIntervalText (minutes) {
      if (!minutes) return '-'
      if (minutes < 60) return `${minutes} ${this.$t('portfolio.form.minutes')}`
      const hours = minutes / 60
      return `${hours} ${this.$t('portfolio.form.hours')}`
    }
  }
}
</script>

<style lang="less" scoped>
@import '~ant-design-vue/es/style/themes/default.less';

@green: #10b981;
@red: #ef4444;
@blue: #3b82f6;
@purple: #8b5cf6;

.portfolio-container {
  padding: 20px;
  background: #f5f5f5;
  min-height: calc(100vh - 120px);

  &.theme-dark {
    background: #131722;

    .summary-card {
      background: #1e222d;
      border-color: #363c4e;

      .card-label { color: #868993; }
      .card-value { color: #d1d4dc; }
      .card-sub { color: #868993; }

      // 暗色模式总市值卡片
      &.total-value {
        background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
        border: 1px solid rgba(59, 130, 246, 0.3);

        .card-icon { background: rgba(59, 130, 246, 0.2); color: #60a5fa; }
        .card-label { color: rgba(255, 255, 255, 0.7); }
        .card-value { color: #fff; }
        .card-sub {
          color: rgba(255, 255, 255, 0.6);
          .positive { color: #34d399; }
          .negative { color: #f87171; }
        }
      }

      &.mini {
        .card-label { color: #868993; }
        .card-value { color: #d1d4dc; }
      }
    }

    .positions-section, .monitors-section {
      background: #1e222d;
      border-color: #363c4e;

      .section-header {
        border-color: #363c4e;
        h3 { color: #d1d4dc; }
      }
    }

    .position-card {
      background: #2a2e39;
      border-color: #363c4e;

      .position-header {
        border-color: #363c4e;

        .symbol { color: #d1d4dc; }
        .name { color: #868993; }
      }

      .position-body {
        .label { color: #868993; }
        .value { color: #d1d4dc; }

        .price-row {
          .current-price, .entry-price {
            .label { color: #868993; }
            .value { color: #d1d4dc; }
          }
        }

        .quantity-row {
          .item {
            .label { color: #868993; }
            .value { color: #d1d4dc; }
          }
        }
      }

      .position-footer {
        background: #252930;

        .pnl {
          .label { color: #868993; }
        }
      }

      // 紧凑卡片暗色模式
      &.compact {
        .position-compact-body {
          .compact-item {
            .label { color: #868993; }
            .value { color: #d1d4dc; }
          }
        }
      }
    }

    .monitor-card {
      background: #2a2e39;
      border-color: #363c4e;

      .monitor-header {
        .monitor-name { color: #d1d4dc; }
      }

      .monitor-body {
        .label { color: #868993; }
        .value { color: #d1d4dc; }
      }

      .monitor-actions {
        border-color: #363c4e;
      }
    }

    // 折叠视图暗色模式
    .position-collapse-view {
      ::v-deep .ant-collapse {
        .ant-collapse-item {
          background: #2a2e39;
        }

        .ant-collapse-header {
          background: #1e222d;
          border-color: #363c4e;
          color: #d1d4dc;
        }

        .ant-collapse-content-box {
          background: #2a2e39;
        }
      }

      .group-header {
        .group-name { color: #d1d4dc; }
        .group-stats .count { color: #868993; }
      }
    }
  }
}

.summary-section {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 16px;

  &.secondary {
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    margin-bottom: 20px;
  }
}

.summary-card {
  background: #fff;
  border-radius: 12px;
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  border: 1px solid #e8e8e8;
  transition: all 0.3s;

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  }

  // 总市值卡片 - 鲜艳渐变风格
  &.total-value {
    background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
    border: none;
    position: relative;
    overflow: hidden;
    box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);

    &::before {
      content: '';
      position: absolute;
      top: -30%;
      right: -20%;
      width: 200px;
      height: 200px;
      background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, transparent 60%);
    }

    &::after {
      content: '';
      position: absolute;
      bottom: -30%;
      left: -10%;
      width: 150px;
      height: 150px;
      background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 50%);
    }

    &:hover {
      box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);
      transform: translateY(-2px);
    }

    .card-icon {
      background: rgba(255, 255, 255, 0.25);
      color: #fff;
    }

    .card-content {
      position: relative;
      z-index: 1;

      .card-label {
        color: rgba(255, 255, 255, 0.9) !important;
        font-weight: 500;
      }
      .card-value {
        color: #fff !important;
        font-size: 24px;
        text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

        .currency {
          color: rgba(255, 255, 255, 0.9);
          font-size: 18px;
        }
        .amount {
          color: #fff;
        }
      }
      .card-sub {
        color: rgba(255, 255, 255, 0.85) !important;
        font-size: 12px;
        margin-top: 4px;
        .positive { color: #bbf7d0 !important; }
        .negative { color: #fecaca !important; }
      }
    }
  }

  // 迷你卡片
  &.mini {
    padding: 14px 16px;

    .card-icon {
      width: 36px;
      height: 36px;
      font-size: 18px;
    }

    .card-value {
      font-size: 16px;

      &.small {
        font-size: 14px;
      }
    }
  }

  // 同步状态卡片
  &.sync-card {
    .card-sub {
      display: flex;
      align-items: center;
    }
  }

  .card-icon {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    background: rgba(59, 130, 246, 0.1);
    color: @blue;

    &.cost { background: rgba(139, 92, 246, 0.1); color: @purple; }
    &.profit { background: rgba(16, 185, 129, 0.1); color: @green; }
    &.loss { background: rgba(239, 68, 68, 0.1); color: @red; }
    &.positions { background: rgba(6, 182, 212, 0.1); color: #06b6d4; }
    &.today { background: rgba(251, 191, 36, 0.1); color: #f59e0b; }
    &.best { background: rgba(16, 185, 129, 0.1); color: @green; }
    &.worst { background: rgba(239, 68, 68, 0.1); color: @red; }
    &.sync {
      background: rgba(59, 130, 246, 0.1);
      color: @blue;
      &.syncing { color: #1890ff; }
    }
  }

  .card-content {
    flex: 1;
    min-width: 0;

    .card-label {
      font-size: 12px;
      color: #8c8c8c;
      margin-bottom: 4px;
    }

    .card-sub {
      font-size: 11px;
      color: #999;
      margin-top: 2px;
    }

    .card-value {
      font-size: 20px;
      font-weight: 700;
      color: #262626;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;

      .currency { font-size: 16px; margin-right: 2px; }
      .percent { font-size: 14px; margin-left: 8px; }

      .position-detail {
        font-size: 14px;
        font-weight: 500;
        margin-left: 4px;
      }
    }
  }
}

.main-content {
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: 20px;

  @media (max-width: 1200px) {
    grid-template-columns: 1fr;
  }
}

.positions-section, .monitors-section {
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e8e8e8;
  overflow: hidden;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #f0f0f0;

  h3 {
    font-size: 16px;
    font-weight: 600;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    color: #262626;

    .anticon { color: @blue; }
  }
}

.positions-list {
  padding: 16px;
}

.empty-state {
  padding: 40px 20px;
  text-align: center;

  &.small {
    padding: 20px;
  }
}

.position-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 16px;
}

.position-card {
  background: #fafafa;
  border-radius: 12px;
  border: 1px solid #e8e8e8;
  overflow: hidden;
  transition: all 0.3s;

  &:hover {
    border-color: @blue;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  }

  &.profit {
    border-left: 3px solid @green;
  }

  &.loss {
    border-left: 3px solid @red;
  }

  .position-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid #f0f0f0;

    .symbol-info {
      display: flex;
      align-items: center;
      gap: 8px;

      .symbol {
        font-size: 16px;
        font-weight: 600;
        color: #262626;
      }

      .name {
        font-size: 12px;
        color: #8c8c8c;
      }
    }

    .position-actions {
      .delete-btn { color: @red; }
      .has-alert {
        color: #faad14 !important;
        .anticon {
          color: #faad14;
        }
      }
    }
  }

  .position-body {
    padding: 12px 16px;

    .price-row {
      display: flex;
      justify-content: space-between;
      margin-bottom: 12px;

      .current-price, .entry-price {
        .label {
          display: block;
          font-size: 11px;
          color: #8c8c8c;
          margin-bottom: 2px;
        }

        .value {
          font-size: 16px;
          font-weight: 600;
          color: #262626;
        }

        .change {
          font-size: 12px;
          margin-left: 8px;

          &.up { color: @green; }
          &.down { color: @red; }
        }
      }
    }

    .quantity-row {
      display: flex;
      gap: 16px;

      .item {
        .label {
          display: block;
          font-size: 11px;
          color: #8c8c8c;
          margin-bottom: 2px;
        }

        .value {
          font-size: 14px;
          color: #262626;
        }
      }
    }
  }

  .position-footer {
    padding: 12px 16px;
    background: #f5f5f5;

    .pnl {
      display: flex;
      align-items: center;
      justify-content: space-between;

      .label {
        font-size: 12px;
        color: #8c8c8c;
      }

      .value {
        font-size: 18px;
        font-weight: 700;

        .percent {
          font-size: 14px;
          margin-left: 8px;
        }
      }
    }
  }
}

.monitors-list {
  padding: 16px;
}

.monitor-card {
  background: #fafafa;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
  padding: 12px 16px;
  margin-bottom: 12px;

  &:last-child {
    margin-bottom: 0;
  }

  .monitor-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;

    .monitor-name {
      font-size: 14px;
      font-weight: 600;
      color: #262626;
      display: flex;
      align-items: center;
      gap: 8px;

      .anticon { color: @blue; }
    }
  }

  .monitor-body {
    .monitor-info {
      font-size: 12px;
      margin-bottom: 4px;

      .label { color: #8c8c8c; }
      .value { color: #262626; margin-left: 4px; }
    }

    .monitor-channels {
      margin-top: 8px;
      font-size: 12px;

      .label { color: #8c8c8c; margin-right: 8px; }
    }

    .scope-selected {
      color: #1890ff;
      cursor: help;
      border-bottom: 1px dashed #1890ff;
    }

    .scope-all {
      color: #52c41a;
    }
  }

  .monitor-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #f0f0f0;

    .delete-btn { color: @red; }
  }
}

.positive { color: @green !important; }
.negative { color: @red !important; }

.symbol-option {
  display: flex;
  align-items: center;
  gap: 8px;

  .symbol-name {
    color: #8c8c8c;
    font-size: 12px;
  }
}

// 折叠视图样式
.position-collapse-view {
  ::v-deep .ant-collapse {
    background: transparent;
    border: none;

    .ant-collapse-item {
      border: none;
      margin-bottom: 12px;
      background: #fafafa;
      border-radius: 8px;
      overflow: hidden;

      &:last-child {
        margin-bottom: 0;
      }
    }

    .ant-collapse-header {
      padding: 12px 16px;
      background: #fff;
      border-bottom: 1px solid #f0f0f0;

      .ant-collapse-arrow {
        left: auto;
        right: 16px;
      }
    }

    .ant-collapse-content {
      border: none;

      .ant-collapse-content-box {
        padding: 12px;
        background: #fafafa;
      }
    }
  }

  .group-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: calc(100% - 30px);

    .group-name {
      font-weight: 600;
      font-size: 14px;
      color: #262626;
      display: flex;
      align-items: center;
    }

    .group-stats {
      display: flex;
      align-items: center;
      gap: 16px;

      .count {
        font-size: 12px;
        color: #8c8c8c;
      }

      .group-pnl {
        font-size: 14px;
        font-weight: 600;
      }
    }
  }
}

// 紧凑型持仓卡片
.position-grid.compact {
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

.position-card.compact {
  padding: 12px;

  .position-header {
    padding: 0 0 8px 0;
    border-bottom: none;

    .symbol-info {
      .symbol {
        font-size: 14px;
      }
      .name {
        font-size: 11px;
      }
    }
  }

  .position-compact-body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;

    .compact-item {
      .label {
        font-size: 11px;
        color: #8c8c8c;
        margin-right: 4px;
      }

      .value {
        font-size: 14px;
        font-weight: 600;
        color: #262626;
      }

      .change {
        font-size: 12px;
        margin-left: 6px;

        &.up { color: @green; }
        &.down { color: @red; }
      }

      &.pnl {
        font-size: 14px;
        font-weight: 700;

        .percent {
          font-size: 12px;
          margin-left: 4px;
        }
      }
    }
  }
}

// 预警弹窗样式
.alert-symbol-info {
  .symbol-input {
    margin-bottom: 8px;
  }

  .current-price-info {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: linear-gradient(135deg, #e6f7ff 0%, #f0f5ff 100%);
    border-radius: 6px;
    font-size: 13px;

    .label {
      color: #595959;
    }

    .price {
      font-weight: 600;
      color: #1890ff;
      font-size: 14px;
    }
  }
}

.threshold-input-wrapper {
  position: relative;
  display: flex;
  align-items: center;

  .alert-unit {
    position: absolute;
    right: 12px;
    color: #8c8c8c;
    font-size: 14px;
    pointer-events: none;
  }
}

.threshold-hint {
  margin-top: 4px;
  font-size: 12px;
  color: #8c8c8c;
}

.switch-label {
  margin-left: 12px;
  color: #8c8c8c;
  font-size: 13px;
}

// 预警弹窗底部按钮
.alert-modal-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .footer-right {
    display: flex;
    gap: 8px;
  }
}

// 持仓选择器样式
.position-checkbox-group {
  display: flex;
  flex-direction: column;
  max-height: 250px;
  overflow-y: auto;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  padding: 8px;
  background: #fafafa;

  .position-checkbox-item {
    padding: 6px 8px;
    border-radius: 4px;
    margin-bottom: 4px;
    transition: background 0.2s;

    &:hover {
      background: rgba(24, 144, 255, 0.05);
    }

    &:last-child {
      margin-bottom: 0;
    }

    .ant-checkbox-wrapper {
      width: 100%;
    }
  }
}

.position-checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;

  .symbol {
    font-weight: 600;
    color: #262626;
    min-width: 60px;
  }

  .name {
    color: #8c8c8c;
    font-size: 12px;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 120px;
  }

  .pnl {
    font-weight: 500;
    font-size: 12px;

    &.positive { color: @green; }
    &.negative { color: @red; }
  }
}

.position-select-actions {
  margin-top: 8px;
  display: flex;
  align-items: center;

  .ant-btn-link {
    padding: 0 4px;
    height: auto;
    font-size: 12px;
  }

  .selected-count {
    margin-left: auto;
    font-size: 12px;
    color: #8c8c8c;
  }
}

// 暗黑主题下的预警弹窗
&.theme-dark {
  .position-checkbox-group {
    background: #2a2e39;
    border-color: #363c4e;
  }

  .position-checkbox-item:hover {
    background: rgba(24, 144, 255, 0.1);
  }

  .position-checkbox-label {
    .symbol { color: #d1d4dc; }
    .name { color: #868993; }
  }

  .position-select-actions {
    .selected-count { color: #868993; }
  }

  .alert-symbol-info {
    .current-price-info {
      background: linear-gradient(135deg, rgba(24, 144, 255, 0.15) 0%, rgba(114, 46, 209, 0.1) 100%);

      .label {
        color: rgba(255, 255, 255, 0.65);
      }

      .price {
        color: #40a9ff;
      }
    }
  }

  .threshold-hint {
    color: rgba(255, 255, 255, 0.45);
  }

  .switch-label {
    color: rgba(255, 255, 255, 0.45);
  }
}

// ==================== 移动端响应式适配 ====================

// 平板端 (768px - 1024px)
@media screen and (max-width: 1024px) {
  .portfolio-container {
    padding: 16px;
  }

  .summary-section {
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;

    &.secondary {
      grid-template-columns: repeat(2, 1fr);
    }
  }

  .main-content {
    grid-template-columns: 1fr;
    gap: 16px;

    .monitors-section {
      order: 2;
    }
  }

  .position-grid {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 12px;
  }
}

// 手机端 (< 768px)
@media screen and (max-width: 768px) {
  .portfolio-container {
    padding: 12px;
  }

  // 概览卡片 - 手机端
  .summary-section {
    grid-template-columns: 1fr 1fr;
    gap: 10px;

    &.secondary {
      grid-template-columns: 1fr 1fr;
      gap: 8px;
    }
  }

  .summary-card {
    padding: 14px;
    border-radius: 10px;
    gap: 10px;

    // 总市值卡片手机端占满两列
    &.total-value {
      grid-column: span 2;
      padding: 16px;

      .card-content {
        .card-value {
          font-size: 22px;

          .currency {
            font-size: 16px;
          }
        }
      }
    }

    &.mini {
      padding: 10px 12px;

      .card-icon {
        width: 32px;
        height: 32px;
        font-size: 16px;
      }

      .card-value {
        font-size: 14px;

        &.small {
          font-size: 12px;
        }
      }

      .card-label {
        font-size: 11px;
      }
    }

    .card-icon {
      width: 40px;
      height: 40px;
      font-size: 20px;
      border-radius: 10px;
    }

    .card-content {
      .card-label {
        font-size: 11px;
      }

      .card-value {
        font-size: 16px;

        .percent {
          font-size: 11px;
        }

        .position-detail {
          font-size: 11px;
        }
      }

      .card-sub {
        font-size: 10px;
      }
    }
  }

  // 主内容区域
  .main-content {
    grid-template-columns: 1fr;
    gap: 12px;
  }

  // 持仓区域
  .positions-section {
    padding: 12px;
    border-radius: 10px;

    .section-header {
      padding-bottom: 10px;
      flex-wrap: wrap;
      gap: 8px;

      h3 {
        font-size: 15px;
        width: 100%;
      }

      .header-actions {
        width: 100%;
        justify-content: space-between;

        .view-toggle {
          .ant-btn {
            padding: 4px 8px;
            font-size: 12px;
          }
        }

        .group-filter {
          .ant-select {
            width: 120px !important;
            font-size: 12px;
          }
        }
      }
    }
  }

  // 持仓网格 - 手机端单列
  .position-grid {
    grid-template-columns: 1fr;
    gap: 10px;

    &.compact {
      grid-template-columns: 1fr;
    }
  }

  // 持仓卡片 - 手机端优化
  .position-card {
    border-radius: 10px;

    .position-header {
      padding: 12px;

      .symbol-info {
        .symbol {
          font-size: 15px;
        }
        .name {
          font-size: 12px;
        }
      }

      .position-actions {
        .ant-btn {
          padding: 2px 6px;
          font-size: 12px;
        }
      }
    }

    .position-body {
      padding: 10px 12px;

      .price-row {
        flex-direction: column;
        gap: 8px;

        .current-price, .entry-price {
          .value {
            font-size: 14px;
          }
        }
      }

      .quantity-row {
        .item {
          .value {
            font-size: 13px;
          }
        }
      }
    }

    .position-footer {
      padding: 10px 12px;

      .pnl {
        .value {
          font-size: 16px;
        }
        .percent {
          font-size: 12px;
        }
      }
    }

    // 紧凑卡片手机端
    &.compact {
      .position-compact-body {
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;

        .compact-item {
          width: 100%;
          display: flex;
          justify-content: space-between;

          .value {
            font-size: 13px;
          }
        }
      }
    }
  }

  // 监控区域 - 手机端
  .monitors-section {
    padding: 12px;
    border-radius: 10px;

    .section-header {
      padding-bottom: 10px;

      h3 {
        font-size: 15px;
      }
    }
  }

  .monitor-card {
    padding: 12px;
    border-radius: 8px;

    .monitor-header {
      .monitor-name {
        font-size: 14px;

        .anticon {
          font-size: 16px;
        }
      }
    }

    .monitor-body {
      .monitor-info {
        font-size: 12px;
      }
    }

    .monitor-actions {
      padding-top: 10px;
      flex-wrap: wrap;
      gap: 4px;

      .ant-btn {
        padding: 2px 8px;
        font-size: 12px;
      }
    }
  }

  // 折叠视图手机端
  .position-collapse-view {
    ::v-deep .ant-collapse {
      .ant-collapse-item {
        margin-bottom: 8px;
        border-radius: 8px;
      }

      .ant-collapse-header {
        padding: 10px 12px;
        font-size: 14px;
      }

      .ant-collapse-content-box {
        padding: 8px;
      }
    }

    .group-header {
      .group-name {
        font-size: 14px;
      }

      .group-stats {
        font-size: 11px;
        gap: 6px;
        flex-wrap: wrap;
      }
    }
  }

  // 空状态
  .empty-state {
    padding: 30px 16px;

    &.small {
      padding: 20px 12px;
    }
  }
}

// 超小屏幕 (< 480px)
@media screen and (max-width: 480px) {
  .portfolio-container {
    padding: 8px;
  }

  .summary-section {
    gap: 8px;

    &.secondary {
      // 超小屏幕下第二行改为滚动
      display: flex;
      overflow-x: auto;
      padding-bottom: 8px;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
      &::-webkit-scrollbar { display: none; }

      .summary-card.mini {
        flex-shrink: 0;
        min-width: 140px;
      }
    }
  }

  .summary-card {
    padding: 12px;
    gap: 8px;

    &.total-value {
      padding: 14px;

      .card-content {
        .card-value {
          font-size: 20px;
        }
      }
    }

    .card-icon {
      width: 36px;
      height: 36px;
      font-size: 18px;
    }

    .card-content {
      .card-value {
        font-size: 15px;
      }
    }
  }

  .positions-section, .monitors-section {
    padding: 10px;

    .section-header {
      h3 {
        font-size: 14px;
      }
    }
  }

  .position-card {
    .position-header {
      padding: 10px;

      .symbol-info {
        .symbol { font-size: 14px; }
        .name { font-size: 11px; }
      }
    }

    .position-body {
      padding: 8px 10px;
    }

    .position-footer {
      padding: 8px 10px;

      .pnl {
        .value { font-size: 15px; }
        .percent { font-size: 11px; }
      }
    }
  }

  .monitor-card {
    padding: 10px;

    .monitor-header {
      .monitor-name {
        font-size: 13px;
      }
    }
  }
}

</style>
