<template>
  <view class="page-rank">
    <scroll-view class="scroll-view" scroll-y>
      <view class="content-wrapper" :class="{ 'blur-content': !isLoggedIn }">
        <!-- 上证指数卡片 -->
        <view class="index-card">
          <view class="index-left">
            <view class="index-price-row">
              <text :class="['index-price', getIndexChangeClass(indexData.changePercent)]">
                {{ formatIndexPrice(indexData.currentPrice) }}
              </text>
              <text :class="['index-change', getIndexChangeClass(indexData.changePercent)]">
                {{ indexData.priceChange || '--' }}
              </text>
            </view>
            <view class="index-name-row">
              <text class="index-name">{{ indexData.stockName || '上证指数' }}</text>
              <text :class="['index-percent', getIndexChangeClass(indexData.changePercent)]">
                {{ indexData.changePercent || '--' }}
              </text>
            </view>
          </view>
        </view>

        <!-- 分段控制器 -->
        <view class="segment-control">
          <view class="segment-slider" :class="{ 'slider-right': viewMode === 'table' }"></view>
          <view 
            class="segment-item" 
            :class="{ 'segment-active': viewMode === 'list' }"
            @click="setViewMode('list')"
          >
            <text class="segment-text">热力图</text>
          </view>
          <view 
            class="segment-item" 
            :class="{ 'segment-active': viewMode === 'table' }"
            @click="setViewMode('table')"
          >
            <text class="segment-text">详情</text>
          </view>
        </view>

        <!-- 热力图视图 -->
        <view v-show="viewMode === 'list'" class="stock-list-card" :class="{ 'hidden-list': myStocks.length === 0 }">
          <view class="list-header">
            <view class="list-dot"></view>
            <text class="list-title">我的自选</text>
            <text class="list-count">{{ myStocks.length }}只</text>
          </view>
          <view class="stock-list">
            <view class="stock-item-wrapper" v-for="(stock, index) in myStocks" :key="stock.code">
              <movable-area class="movable-area">
                <movable-view 
                  class="movable-view"
                  direction="horizontal"
                  :x="slideStates[stock.code]?.x || 0"
                  :damping="40"
                  :friction="5"
                  :out-of-bounds="false"
                  @change="(e) => handleSlideChange(e, stock.code)"
                  @touchend="() => handleSlideEnd(stock.code)"
                >
                  <view class="stock-item">
                    <view class="stock-main">
                      <view class="stock-info">
                        <text class="stock-name">{{ stock.name }}</text>
                        <view class="stock-code-row">
                          <text :class="['stock-tag', getMarketClass(stock.code)]">{{ getMarketTag(stock.code) }}</text>
                          <text class="stock-code">{{ stock.code }}</text>
                        </view>
                      </view>
                      <!-- 趋势图 - 使用 canvas 2d 模式解决滚动分离问题 -->
                      <view class="stock-chart">
                        <canvas 
                          type="2d"
                          :id="'chart-' + stock.code"
                          class="trend-canvas"
                        ></canvas>
                      </view>
                      <view class="stock-quote">
                        <text class="stock-price">{{ stock.currentPrice || '-' }}</text>
                        <text :class="['stock-change', getProfitClass(stock.changePercent)]">{{ stock.changePercent || '-' }}</text>
                      </view>
                    </view>
                    <!-- 滑动删除按钮 -->
                    <view class="slide-delete-btn" @click.stop="removeStock(index)">
                      <view class="delete-icon-circle">
                        <text class="delete-icon-text">−</text>
                      </view>
                    </view>
                  </view>
                </movable-view>
              </movable-area>
            </view>
          </view>
        </view>

        <!-- 详情表格视图 -->
        <view v-show="viewMode === 'table'" class="stock-table-card" :class="{ 'hidden-list': myStocks.length === 0 }">
          <view class="list-header">
            <view class="list-dot list-dot-blue"></view>
            <text class="list-title">详情数据</text>
          </view>
          <!-- 表头 -->
          <view class="table-header">
            <text class="th-name">股票</text>
            <text class="th-date">自选日</text>
            <text class="th-price">自选价</text>
            <text class="th-profit">收益</text>
          </view>
          <!-- 表格内容 -->
          <view class="table-list">
            <view 
              v-for="(stock, index) in myStocks" 
              :key="stock.code"
              class="table-row"
            >
              <view class="td-name">
                <text class="stock-name">{{ stock.name }}</text>
                <view class="stock-code-row">
                  <text :class="['stock-tag', getMarketClass(stock.code)]">{{ getMarketTag(stock.code) }}</text>
                  <text class="stock-code">{{ stock.code }}</text>
                </view>
              </view>
              <text class="td-date">{{ stock.addDate || '--' }}</text>
              <text class="td-price">{{ formatPrice(stock.addPrice) }}</text>
              <view class="td-profit-wrap">
                <text :class="['td-profit', getProfitClass(stock.profitPercent)]">
                  {{ stock.profitPercent || '--' }}
                </text>
              </view>
            </view>
          </view>
        </view>

        <!-- 空状态 -->
        <view v-if="myStocks.length === 0" class="empty-content">
          <view class="empty-icon">📊</view>
          <text class="empty-text">暂无收藏股票</text>
          <text class="empty-desc">在强势池中点击"+"按钮添加股票</text>
        </view>

        <!-- 底部安全区域 -->
        <view class="bottom-safe-area"></view>
      </view>
    </scroll-view>

    <!-- 未登录遮罩层 -->
    <view v-if="!isLoggedIn" class="login-mask">
      <view class="login-prompt">
        <view class="lock-icon">🔒</view>
        <text class="prompt-title">登录后查看我的股票</text>
        <text class="prompt-desc">使用微信授权快速登录</text>
        <button class="login-button-native" @click="goToLogin">
          <text>登录</text>
        </button>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, nextTick, getCurrentInstance, reactive } from 'vue'
import { onLoad, onShow, onHide, onUnload } from '@dcloudio/uni-app'
import { isLoggedIn as checkLoginStatus } from '../../utils/auth.js'
import { getStockQuotes, getIndexQuote, getUserStocks, deleteUserStock } from '../../utils/api.js'

// 保存组件实例
let componentInstance = null

const isLoggedIn = ref(false)
const myStocks = ref([])
const viewMode = ref('list') // 'list' 或 'table'
const isLoading = ref(false) // 加载状态
const lastLoadTime = ref(0) // 上次加载时间
const CACHE_DURATION = 5000 // 缓存有效期5秒
const isPageVisible = ref(false) // 页面是否可见

// 获取随机刷新间隔 (2000-3000ms)
const getRandomInterval = () => 2000 + Math.random() * 1000

// 滑动删除相关
const SLIDE_WIDTH = 100 // 滑动距离（三分之一宽度约100rpx转换）
const slideStates = reactive({}) // 每个股票的滑动状态
let slideTimers = {} // 自动还原计时器
const AUTO_RESET_DELAY = 2000 // 2秒后自动还原

// 初始化滑动状态
const initSlideState = (code) => {
  if (!slideStates[code]) {
    slideStates[code] = { x: 0, currentX: 0 }
  }
}

// 处理滑动变化
const handleSlideChange = (e, code) => {
  initSlideState(code)
  slideStates[code].currentX = e.detail.x
}

// 处理滑动结束
const handleSlideEnd = (code) => {
  initSlideState(code)
  const state = slideStates[code]
  
  // 滑动超过20px就显示删除按钮（吸附到三分之一处）
  if (state.currentX < -20) {
    state.x = -SLIDE_WIDTH
    // 启动自动还原计时器（2秒）
    startAutoResetTimer(code)
  } else {
    // 滑回初始位置
    resetSlide(code)
  }
}

// 重置滑动位置
const resetSlide = (code) => {
  if (slideStates[code]) {
    slideStates[code].x = 0
    slideStates[code].currentX = 0
  }
  clearSlideTimer(code)
}

// 启动自动还原计时器
const startAutoResetTimer = (code) => {
  clearSlideTimer(code)
  slideTimers[code] = setTimeout(() => {
    resetSlide(code)
  }, AUTO_RESET_DELAY) // 2秒后自动还原
}

// 清除计时器
const clearSlideTimer = (code) => {
  if (slideTimers[code]) {
    clearTimeout(slideTimers[code])
    delete slideTimers[code]
  }
}

// 清除所有计时器
const clearAllSlideTimers = () => {
  Object.keys(slideTimers).forEach(code => {
    clearSlideTimer(code)
  })
}

// 设置视图模式
const setViewMode = (mode) => {
  viewMode.value = mode
  
  // 切换到热力图视图时，先清空再重绘趋势图
  if (mode === 'list' && myStocks.value.length > 0) {
    nextTick(() => {
      clearAllCanvases()
      drawAllTrendCharts()
    })
  }
}

const indexData = ref({
  stockCode: '000001',
  stockName: '上证指数',
  currentPrice: null,
  priceChange: null,
  changePercent: null
})
let priceRefreshTimer = null  // 价格刷新定时器 (2-3秒)
let trendRefreshTimer = null  // 趋势图刷新定时器 (10秒)

// 获取上证指数数据
const fetchIndexData = async () => {
  try {
    const res = await getIndexQuote('000001')
    if (res.code === 200 && res.data) {
      indexData.value = { ...indexData.value, ...res.data }
    }
  } catch (e) {
    console.error('[上证指数] 获取失败:', e.message)
  }
}

// 格式化指数价格
const formatIndexPrice = (price) => {
  if (!price) return '--'
  return parseFloat(price).toFixed(2)
}

// 格式化价格
const formatPrice = (price) => {
  if (!price) return '--'
  return parseFloat(price).toFixed(2)
}

// 获取指数涨跌样式类
const getIndexChangeClass = (changePercent) => {
  if (!changePercent) return ''
  const str = String(changePercent).replace('%', '').replace('+', '')
  const value = parseFloat(str)
  if (value > 0) return 'index-up'
  if (value < 0) return 'index-down'
  return ''
}

// 获取收益样式类
const getProfitClass = (profitPercent) => {
  if (!profitPercent) return ''
  const str = String(profitPercent).replace('%', '').replace('+', '')
  const value = parseFloat(str)
  if (value > 0) return 'profit-up'
  if (value < 0) return 'profit-down'
  return ''
}

// 获取市场标签
const getMarketTag = (code) => {
  if (code.startsWith('6')) return '沪'
  if (code.startsWith('0')) return '深'
  if (code.startsWith('3')) return '创'
  return '沪'
}

const getMarketClass = (code) => {
  if (code.startsWith('6')) return 'market-sh'
  if (code.startsWith('0')) return 'market-sz'
  if (code.startsWith('3')) return 'market-cy'
  return 'market-sh'
}

// 获取设备像素比（使用新API替代废弃的getSystemInfoSync）
const getDevicePixelRatio = () => {
  try {
    const windowInfo = wx.getWindowInfo()
    return windowInfo.pixelRatio || 2
  } catch (e) {
    return 2 // 默认值
  }
}

// 清空单个 canvas
const clearCanvas = (canvasId) => {
  const query = uni.createSelectorQuery()
  query.select('#' + canvasId)
    .fields({ node: true, size: true })
    .exec((res) => {
      if (!res || !res[0] || !res[0].node) return
      
      const canvas = res[0].node
      const ctx = canvas.getContext('2d')
      const dpr = getDevicePixelRatio()
      const width = res[0].width
      const height = res[0].height
      
      canvas.width = width * dpr
      canvas.height = height * dpr
      ctx.setTransform(1, 0, 0, 1, 0, 0)
      ctx.clearRect(0, 0, width * dpr, height * dpr)
    })
}

// 清空所有趋势图 canvas
const clearAllCanvases = () => {
  myStocks.value.forEach(stock => {
    clearCanvas('chart-' + stock.code)
  })
}

// 绘制单个股票的趋势图 (使用 Canvas 2D API)
const drawTrendChart = (stock) => {
  const canvasId = 'chart-' + stock.code
  let trendData = stock.trendData
  
  // 如果没有趋势数据，生成模拟数据
  if (!trendData || !Array.isArray(trendData) || trendData.length === 0) {
    trendData = generateMockTrendData(stock.changePercent)
  }
  
  // 使用 Canvas 2D 模式
  const query = uni.createSelectorQuery()
  query.select('#' + canvasId)
    .fields({ node: true, size: true })
    .exec((res) => {
      if (!res || !res[0] || !res[0].node) {
        console.warn('[趋势图] 获取canvas节点失败:', canvasId)
        return
      }
      
      const canvas = res[0].node
      const ctx = canvas.getContext('2d')
      const dpr = getDevicePixelRatio()
      
      // 设置 canvas 实际尺寸
      const width = res[0].width
      const height = res[0].height
      
      // 重置 canvas 尺寸（强制清除之前的绘制状态，解决页面切换后显示异常）
      canvas.width = width * dpr
      canvas.height = height * dpr
      
      // 重置变换矩阵后再设置缩放
      ctx.setTransform(1, 0, 0, 1, 0, 0)
      ctx.scale(dpr, dpr)
      
      const padding = 1
      
      const maxValue = Math.max(...trendData)
      const minValue = Math.min(...trendData)
      const dataRange = maxValue - minValue
      const avgValue = (maxValue + minValue) / 2
      const minRange = avgValue * 0.03 || 1
      const range = Math.max(dataRange, minRange)
      
      const baseValue = trendData[0]
      const baseY = height - padding - ((baseValue - minValue) / range) * (height - padding * 2)
      
      const changePercent = parseFloat(String(stock.changePercent || '0').replace('%', '').replace('+', ''))
      const isUp = changePercent >= 0
      const lineColor = isUp ? '#ef4444' : '#22c55e'
      const fillColor = isUp ? 'rgba(239, 68, 68, 0.15)' : 'rgba(34, 197, 94, 0.15)'
      
      // 清除画布
      ctx.clearRect(0, 0, width, height)
      
      // 绘制基准虚线
      ctx.beginPath()
      ctx.strokeStyle = '#e5e7eb'
      ctx.lineWidth = 0.5
      ctx.setLineDash([2, 2])
      ctx.moveTo(padding, baseY)
      ctx.lineTo(width - padding, baseY)
      ctx.stroke()
      ctx.setLineDash([])
      
      // 绘制填充区域
      ctx.beginPath()
      ctx.moveTo(padding, baseY)
      
      trendData.forEach((value, index) => {
        const x = padding + (index / (trendData.length - 1)) * (width - padding * 2)
        const y = height - padding - ((value - minValue) / range) * (height - padding * 2)
        ctx.lineTo(x, y)
      })
      
      ctx.lineTo(width - padding, baseY)
      ctx.closePath()
      ctx.fillStyle = fillColor
      ctx.fill()
      
      // 绘制折线
      ctx.beginPath()
      
      trendData.forEach((value, index) => {
        const x = padding + (index / (trendData.length - 1)) * (width - padding * 2)
        const y = height - padding - ((value - minValue) / range) * (height - padding * 2)
        
        if (index === 0) {
          ctx.moveTo(x, y)
        } else {
          ctx.lineTo(x, y)
        }
      })
      
      ctx.strokeStyle = lineColor
      ctx.lineWidth = 1.5
      ctx.stroke()
    })
}

// 生成模拟趋势数据
const generateMockTrendData = (changePercent) => {
  const change = parseFloat(String(changePercent || '0').replace('%', '').replace('+', ''))
  const points = 15
  const data = []
  
  let baseValue = 100
  const trend = change / 100
  
  for (let i = 0; i < points; i++) {
    const randomChange = (Math.random() - 0.5) * 6
    const trendChange = (i / points) * trend * 100
    baseValue = baseValue + randomChange + trendChange / points
    data.push(baseValue)
  }
  
  return data
}

// 绘制所有股票的趋势图
const drawAllTrendCharts = () => {
  if (myStocks.value.length === 0) return
  
  // 确保页面可见时才绘制
  if (!isPageVisible.value) return
  
  nextTick(() => {
    // 增加延迟确保 canvas 节点完全渲染（解决页面切换后 canvas 上下文丢失问题）
    setTimeout(() => {
      if (!isPageVisible.value) return
      
      myStocks.value.forEach((stock, index) => {
        setTimeout(() => {
          if (isPageVisible.value) {
            drawTrendChart(stock)
          }
        }, index * 30)
      })
    }, 350)
  })
}

// 加载我的股票列表（从服务器数据库查询）
const loadMyStocks = async (forceRefresh = false) => {
  console.log('[我的股票] loadMyStocks 开始执行, isLoggedIn=', isLoggedIn.value, 'forceRefresh=', forceRefresh)
  
  if (!isLoggedIn.value) {
    myStocks.value = []
    stopAutoRefresh()
    return
  }
  
  // 如果正在加载中，跳过
  if (isLoading.value) {
    console.log('[我的股票] 正在加载中，跳过')
    return
  }
  
  // 如果有缓存数据且未过期，只刷新行情不重新加载列表
  const now = Date.now()
  if (!forceRefresh && myStocks.value.length > 0 && (now - lastLoadTime.value) < CACHE_DURATION) {
    console.log('[我的股票] 使用缓存数据，只刷新行情')
    // 只刷新行情数据
    await fetchIndexData()
    await refreshAllQuotes()
    // 重新绘制趋势图（解决页面切换回来后canvas显示异常的问题）
    drawAllTrendCharts()
    startAutoRefresh()
    return
  }
  
  try {
    isLoading.value = true
    
    // 只有首次加载或强制刷新时显示loading
    let showedLoading = false
    if (myStocks.value.length === 0 || forceRefresh) {
      uni.showLoading({ title: '加载中...' })
      showedLoading = true
    }
    
    // 从服务器获取用户自选股票
    console.log('[我的股票] 调用 getUserStocks 接口')
    const res = await getUserStocks()
    console.log('[我的股票] 服务器返回:', JSON.stringify(res))
    
    if (showedLoading) {
      uni.hideLoading()
    }
    
    if (res.code === 200 && res.data) {
      // 转换数据格式
      myStocks.value = res.data.map(item => ({
        code: item.stockCode,
        name: item.stockName,
        addPrice: item.addPrice,
        addDate: item.addDate,
        currentPrice: item.currentPrice,
        profitPercent: item.profitPercent,
        priceChange: item.priceChange,
        changePercent: item.changePercent,
        trendData: item.trendData
      }))
      lastLoadTime.value = Date.now()
      console.log('[我的股票] 加载完成, 股票数量:', myStocks.value.length)
    } else {
      myStocks.value = []
      console.log('[我的股票] 返回数据为空')
    }
    
    // 获取上证指数
    await fetchIndexData()
    
    // 如果有股票数据，刷新行情
    if (myStocks.value.length > 0) {
      await refreshAllQuotes()
      // 绘制趋势图
      drawAllTrendCharts()
    }
    
    // 登录后启动定时刷新
    startAutoRefresh()
  } catch (e) {
    // 安全地隐藏loading
    try { uni.hideLoading() } catch (err) {}
    console.error('[我的股票] 加载失败:', e)
    // 加载失败时不清空已有数据
    if (myStocks.value.length === 0) {
      myStocks.value = []
    }
    startAutoRefresh()
  } finally {
    isLoading.value = false
  }
}

// 批量刷新所有股票行情（只更新价格，不更新趋势图）
const refreshPriceOnly = async () => {
  if (myStocks.value.length === 0) return
  
  try {
    const codes = myStocks.value.map(stock => stock.code).join(',')
    const quoteRes = await getStockQuotes(codes)
    
    if (quoteRes.code === 200 && quoteRes.data && quoteRes.data.length > 0) {
      quoteRes.data.forEach(quoteData => {
        const index = myStocks.value.findIndex(stock => stock.code === quoteData.stockCode)
        if (index !== -1) {
          const stock = myStocks.value[index]
          stock.priceChange = quoteData.priceChange
          stock.changePercent = quoteData.changePercent
          stock.currentPrice = quoteData.currentPrice
          stock.name = quoteData.stockName || stock.name
          // 不更新 trendData
          
          // 计算自选收益（当前价格相对于加入价格的涨跌幅）
          if (stock.addPrice && quoteData.currentPrice) {
            const addPrice = parseFloat(stock.addPrice)
            const currentPrice = parseFloat(quoteData.currentPrice)
            if (addPrice > 0) {
              const profit = ((currentPrice - addPrice) / addPrice * 100).toFixed(2)
              stock.profitPercent = profit >= 0 ? `+${profit}%` : `${profit}%`
            }
          }
        }
      })
    }
  } catch (e) {
    console.error('[我的股票] 价格刷新异常:', e.message)
  }
}

// 批量刷新所有股票行情（包含趋势图）
const refreshAllQuotes = async () => {
  if (myStocks.value.length === 0) return
  
  try {
    const codes = myStocks.value.map(stock => stock.code).join(',')
    const quoteRes = await getStockQuotes(codes)
    
    if (quoteRes.code === 200 && quoteRes.data && quoteRes.data.length > 0) {
      quoteRes.data.forEach(quoteData => {
        const index = myStocks.value.findIndex(stock => stock.code === quoteData.stockCode)
        if (index !== -1) {
          const stock = myStocks.value[index]
          stock.priceChange = quoteData.priceChange
          stock.changePercent = quoteData.changePercent
          stock.currentPrice = quoteData.currentPrice
          stock.name = quoteData.stockName || stock.name
          stock.trendData = quoteData.trendData || null
          
          // 计算自选收益（当前价格相对于加入价格的涨跌幅）
          if (stock.addPrice && quoteData.currentPrice) {
            const addPrice = parseFloat(stock.addPrice)
            const currentPrice = parseFloat(quoteData.currentPrice)
            if (addPrice > 0) {
              const profit = ((currentPrice - addPrice) / addPrice * 100).toFixed(2)
              stock.profitPercent = profit >= 0 ? `+${profit}%` : `${profit}%`
            }
          }
        }
      })
    }
  } catch (e) {
    console.error('[我的股票] 刷新异常:', e.message)
  }
}

// 启动定时刷新（价格2-3秒，趋势图10秒）
const startAutoRefresh = () => {
  if (!isLoggedIn.value || !isPageVisible.value) return
  stopAutoRefresh()
  
  // 价格刷新定时器 (2-3秒随机间隔)
  const schedulePriceRefresh = () => {
    if (!isPageVisible.value) {
      stopAutoRefresh()
      return
    }
    
    priceRefreshTimer = setTimeout(async () => {
      if (!isPageVisible.value) {
        stopAutoRefresh()
        return
      }
      
      await fetchIndexData()
      if (myStocks.value.length > 0) {
        await refreshPriceOnly()
      }
      schedulePriceRefresh()
    }, getRandomInterval())
  }
  
  // 趋势图刷新定时器 (10秒固定间隔)
  const scheduleTrendRefresh = () => {
    if (!isPageVisible.value) {
      stopAutoRefresh()
      return
    }
    
    trendRefreshTimer = setTimeout(async () => {
      if (!isPageVisible.value) {
        stopAutoRefresh()
        return
      }
      
      if (myStocks.value.length > 0) {
        await refreshAllQuotes()
        drawAllTrendCharts()
      }
      scheduleTrendRefresh()
    }, 10000)
  }
  
  schedulePriceRefresh()
  scheduleTrendRefresh()
}

// 停止定时刷新
const stopAutoRefresh = () => {
  if (priceRefreshTimer) {
    clearTimeout(priceRefreshTimer)
    priceRefreshTimer = null
  }
  if (trendRefreshTimer) {
    clearTimeout(trendRefreshTimer)
    trendRefreshTimer = null
  }
}

// 跳转到登录页
const goToLogin = () => {
  uni.navigateTo({ url: '/pages/login/login' })
}



// 删除股票
const removeStock = async (idx) => {
  const stock = myStocks.value[idx]
  // 先重置滑动状态
  resetSlide(stock.code)
  
  uni.showModal({
    title: '确认删除',
    content: `确定要删除 ${stock.name} 吗？`,
    confirmText: '删除',
    cancelText: '取消',
    success: async (res) => {
      if (res.confirm) {
        try {
          // 调用服务器删除接口
          await deleteUserStock(stock.code)
          // 清理滑动状态
          delete slideStates[stock.code]
          clearSlideTimer(stock.code)
          // 从本地列表删除
          myStocks.value.splice(idx, 1)
          uni.showToast({ title: '删除成功', icon: 'success' })
          
          if (myStocks.value.length === 0) {
            stopAutoRefresh()
          }
        } catch (e) {
          console.error('删除失败:', e)
          uni.showToast({ title: '删除失败', icon: 'none' })
        }
      }
    }
  })
}

onLoad(() => {
  console.log('[我的股票] onLoad 触发')
  componentInstance = getCurrentInstance()
  isLoggedIn.value = checkLoginStatus()
  isPageVisible.value = true
  loadMyStocks(true) // 首次加载强制刷新
})

onShow(() => {
  console.log('[我的股票] onShow 触发')
  isPageVisible.value = true
  
  // 立即清空所有 canvas，避免显示异常的长条
  if (myStocks.value.length > 0) {
    clearAllCanvases()
  }
  
  const wasLoggedIn = isLoggedIn.value
  isLoggedIn.value = checkLoginStatus()
  
  // 如果登录状态变化了，强制刷新
  if (wasLoggedIn !== isLoggedIn.value) {
    loadMyStocks(true)
  } else {
    // 否则使用缓存策略
    loadMyStocks(false)
  }
  
  uni.setNavigationBarTitle({ title: '量化交易大师' })
})

onHide(() => {
  console.log('[我的股票] onHide 触发')
  isPageVisible.value = false
  stopAutoRefresh()
})

onUnload(() => {
  console.log('[我的股票] onUnload 触发')
  isPageVisible.value = false
  stopAutoRefresh()
  clearAllSlideTimers()
})
</script>

<style>
.page-rank {
  display: flex;
  flex-direction: column;
  background: #f5f6fb;
  height: 100vh;
}

.scroll-view {
  flex: 1;
  height: 0;
}

.content-wrapper {
  padding: 32rpx;
  min-height: 100%;
}

/* 上证指数卡片 */
.index-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #ffffff;
  border-radius: 24rpx;
  padding: 32rpx;
  margin-bottom: 24rpx;
  box-shadow: 0 8rpx 24rpx rgba(37, 52, 94, 0.08);
}

.index-left {
  display: flex;
  flex-direction: column;
}

.index-price-row {
  display: flex;
  align-items: baseline;
  margin-bottom: 8rpx;
}

.index-price {
  font-size: 48rpx;
  font-weight: 700;
  margin-right: 16rpx;
}

.index-change {
  font-size: 28rpx;
  font-weight: 600;
}

.index-name-row {
  display: flex;
  align-items: center;
}

.index-name {
  font-size: 26rpx;
  color: #666666;
  margin-right: 12rpx;
}

.index-percent {
  font-size: 26rpx;
  font-weight: 600;
}

.index-up {
  color: #FF3B30;
}

.index-down {
  color: #34C759;
}

/* 分段控制器 */
.segment-control {
  display: flex;
  align-items: center;
  background: #F5F7FA;
  border-radius: 32rpx;
  padding: 6rpx;
  margin-bottom: 24rpx;
  position: relative;
  height: 64rpx;
  box-sizing: border-box;
}

.segment-slider {
  position: absolute;
  left: 6rpx;
  top: 6rpx;
  width: calc(50% - 6rpx);
  height: calc(100% - 12rpx);
  background: #ffffff;
  border-radius: 26rpx;
  box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.05);
  transition: transform 0.3s ease;
  z-index: 0;
}

.segment-slider.slider-right {
  transform: translateX(100%);
}

.segment-item {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  z-index: 1;
  transition: color 0.3s ease;
}

.segment-icon {
  font-size: 24rpx;
  margin-right: 8rpx;
  color: #999999;
  transition: color 0.3s ease;
}

.segment-text {
  font-size: 26rpx;
  color: #999999;
  font-weight: 500;
  transition: color 0.3s ease;
}

.segment-active .segment-icon,
.segment-active .segment-text {
  color: #E53935;
}

/* 隐藏空列表 */
.hidden-list {
  display: none !important;
}

/* 股票列表卡片 */
.stock-list-card,
.stock-table-card {
  background: #ffffff;
  border-radius: 32rpx;
  padding: 32rpx;
  box-shadow: 0 16rpx 48rpx rgba(37, 52, 94, 0.1);
}

.list-header {
  display: flex;
  align-items: center;
  margin-bottom: 28rpx;
}

.list-dot {
  width: 12rpx;
  height: 12rpx;
  border-radius: 50%;
  background: #3abf81;
  margin-right: 12rpx;
}

.list-dot-blue {
  background: #5B5AEA;
}

.list-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #1a1a2e;
  letter-spacing: 1rpx;
}

.list-count {
  font-size: 24rpx;
  color: #9ca3af;
  margin-left: 12rpx;
}

/* 股票列表 */
.stock-list {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
}

/* 滑动删除容器 */
.stock-item-wrapper {
  position: relative;
  height: 160rpx;
  overflow: hidden;
  border-radius: 20rpx;
  background: #fafbfc;
}

.movable-area {
  width: 100%;
  height: 100%;
}

.movable-view {
  width: calc(100% + 160rpx);
  height: 100%;
}

.stock-item {
  display: flex;
  align-items: center;
  padding: 20rpx 16rpx;
  background: #fafbfc;
  border-radius: 20rpx;
  height: 100%;
  box-sizing: border-box;
}

/* 滑动删除按钮 */
.slide-delete-btn {
  flex-shrink: 0;
  width: 160rpx;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fafbfc;
}

.delete-icon-circle {
  width: 72rpx;
  height: 72rpx;
  background: #ef4444;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6rpx 16rpx rgba(239, 68, 68, 0.4);
}

.delete-icon-text {
  font-size: 40rpx;
  color: #ffffff;
  font-weight: bold;
  line-height: 1;
}

.stock-main {
  display: flex;
  align-items: center;
  flex: 1;
  width: 100%;
}

.stock-info {
  display: flex;
  flex-direction: column;
  min-width: 130rpx;
  flex-shrink: 0;
}

.stock-name {
  font-size: 30rpx;
  font-weight: 700;
  color: #1a1a2e;
  margin-bottom: 8rpx;
  letter-spacing: 0.5rpx;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

.stock-code-row {
  display: flex;
  align-items: center;
}

.stock-tag {
  font-size: 18rpx;
  padding: 3rpx 8rpx;
  border-radius: 6rpx;
  color: #ffffff;
  font-weight: 600;
  margin-right: 6rpx;
  flex-shrink: 0;
}

.market-sh {
  background: #ef4444;
}

.market-sz {
  background: #22c55e;
}

.market-cy {
  background: #f59e0b;
}

.stock-code {
  font-size: 22rpx;
  color: #6b7280;
  font-weight: 500;
  text-rendering: optimizeLegibility;
}

.stock-quote {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
  min-width: 140rpx;
}

/* 趋势图 */
.stock-chart {
  flex: 1;
  height: 56rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 16rpx;
}

.trend-canvas {
  width: 100%;
  height: 56rpx;
}

.stock-price {
  font-size: 32rpx;
  font-weight: 700;
  color: #1a1a2e;
  margin-bottom: 6rpx;
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', sans-serif;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

.stock-change {
  font-size: 22rpx;
  font-weight: 600;
  padding: 4rpx 10rpx;
  border-radius: 8rpx;
  text-rendering: optimizeLegibility;
}

/* 表格视图 */
.table-header {
  display: flex;
  align-items: center;
  padding: 20rpx 16rpx;
  background: #f8f9fc;
  border-radius: 12rpx;
  margin-bottom: 16rpx;
}

.table-header text {
  font-size: 24rpx;
  color: #9ca3af;
  font-weight: 600;
}

.th-name {
  flex: 1;
}

.th-date {
  width: 140rpx;
  text-align: center;
}

.th-price {
  width: 120rpx;
  text-align: center;
}

.th-profit {
  width: 120rpx;
  text-align: right;
}

.table-list {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}

.table-row {
  display: flex;
  align-items: center;
  padding: 24rpx 16rpx;
  background: #fafbfc;
  border-radius: 16rpx;
}

.td-name {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.td-name .stock-name {
  font-size: 28rpx;
  font-weight: 700;
  color: #1a1a2e;
  margin-bottom: 4rpx;
}

.td-date {
  width: 140rpx;
  text-align: center;
  font-size: 24rpx;
  color: #6b7280;
}

.td-price {
  width: 120rpx;
  text-align: center;
  font-size: 26rpx;
  font-weight: 600;
  color: #1a1a2e;
}

.td-profit-wrap {
  width: 120rpx;
  display: flex;
  justify-content: flex-end;
}

.td-profit {
  font-size: 24rpx;
  font-weight: 600;
  padding: 6rpx 12rpx;
  border-radius: 8rpx;
}

.profit-up {
  color: #ef4444;
  background: rgba(239, 68, 68, 0.1);
}

.profit-down {
  color: #22c55e;
  background: rgba(34, 197, 94, 0.1);
}

/* 空状态 */
.empty-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 200rpx 60rpx;
}

.empty-icon {
  font-size: 120rpx;
  margin-bottom: 40rpx;
}

.empty-text {
  font-size: 32rpx;
  font-weight: 600;
  color: #333333;
  margin-bottom: 16rpx;
}

.empty-desc {
  font-size: 26rpx;
  color: #999999;
  text-align: center;
  line-height: 1.6;
}

.bottom-safe-area {
  height: 80rpx;
}

/* 模糊效果 */
.blur-content {
  filter: blur(8rpx);
  pointer-events: none;
}

/* 登录遮罩层 */
.login-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.login-prompt {
  width: 560rpx;
  max-width: 560rpx;
  background: #ffffff;
  border-radius: 24rpx;
  padding: 50rpx 40rpx;
  margin: 0 auto;
  text-align: center;
  box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
  box-sizing: border-box;
}

.lock-icon {
  font-size: 72rpx;
  margin-bottom: 20rpx;
}

.prompt-title {
  display: block;
  font-size: 32rpx;
  font-weight: 600;
  color: #222222;
  margin-bottom: 12rpx;
}

.prompt-desc {
  display: block;
  font-size: 24rpx;
  color: #999999;
  line-height: 1.5;
  margin-bottom: 32rpx;
}

.login-button-native {
  width: 100%;
  height: 80rpx;
  background: linear-gradient(135deg, #4CAF50, #66BB6A);
  color: #ffffff;
  border-radius: 40rpx;
  font-size: 30rpx;
  font-weight: 600;
  box-shadow: 0 8rpx 24rpx rgba(76, 175, 80, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  padding: 0;
  line-height: 80rpx;
}

.login-button-native::after {
  border: none;
}
</style>
