#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
低价擒牛UI模块
"""

import streamlit as st
import pandas as pd
from datetime import datetime
from low_price_bull_selector import LowPriceBullSelector
from low_price_bull_strategy import LowPriceBullStrategy
from notification_service import notification_service
from low_price_bull_monitor import low_price_bull_monitor
from low_price_bull_service import low_price_bull_service


def display_low_price_bull():
    """显示低价擒牛选股界面"""
    
    # 检查是否显示监控面板
    if st.session_state.get('show_low_price_monitor'):
        from low_price_bull_monitor_ui import display_monitor_panel
        display_monitor_panel()
        
        # 返回按钮
        if st.button("🔙 返回选股", type="secondary"):
            del st.session_state.show_low_price_monitor
            st.rerun()
        return
    
    st.markdown("顶部按钮区")
    col_select, col_monitor = st.columns([3, 1])
    
    with col_select:
        st.markdown("## 🐂 低价擒牛 - 低价高成长股票筛选")
    
    with col_monitor:
        st.write("")  # 占位
        if st.button("📊 策略监控", type="primary", width='content'):
            st.session_state.show_low_price_monitor = True
            st.rerun()
    
    st.markdown("---")
    
    st.markdown("""
    ### 📋 选股策略说明
    
    **筛选条件**：
    - ✅ 股价 < 10元
    - ✅ 净利润增长率 ≥ 100%（净利润同比增长率）
    - ✅ 非ST股票
    - ✅ 非科创板
    - ✅ 非创业板
    - ✅ 沪深A股
    - ✅ 按成交额由小至大排名
    
    **量化交易策略**：
    - 💰 资金量：100万元
    - 📅 持股周期：5天
    - 💼 仓位控制：满仓
    - 📊 个股最大持仓：4成（40%）
    - 🎯 账户最大持股数：4只
    - 🛒 单日最大买入数：2只
    - 📈 买入时机：开盘买入
    - 📉 卖出时机：MA5下穿MA20或持股满5天
    """)
    
    st.markdown("---")
    
    # 参数设置
    col1, col2 = st.columns([2, 1])
    
    with col1:
        top_n = st.slider(
            "筛选数量",
            min_value=3,
            max_value=10,
            value=5,
            step=1,
            help="选择展示的股票数量"
        )
    
    with col2:
        st.info(f"💡 将筛选成交额最小的前{top_n}只股票")
    
    st.markdown("---")
    
    # 开始选股按钮
    if st.button("🚀 开始低价擒牛选股", type="primary", width='content'):
        
        with st.spinner("正在获取数据，请稍候..."):
            # 创建选股器
            selector = LowPriceBullSelector()
            
            # 获取股票
            success, stocks_df, message = selector.get_low_price_stocks(top_n=top_n)
            
            if success and stocks_df is not None:
                # 保存结果
                st.session_state.low_price_bull_stocks = stocks_df
                st.session_state.low_price_bull_selector = selector
                
                st.success(f"✅ {message}")
                
                # 发送钉钉通知
                send_dingtalk_notification(stocks_df, top_n)
                
                st.rerun()
            else:
                st.error(f"❌ {message}")
    
    # 显示选股结果
    if 'low_price_bull_stocks' in st.session_state:
        display_stock_results(
            st.session_state.low_price_bull_stocks,
            st.session_state.get('low_price_bull_selector')
        )


def display_stock_results(stocks_df: pd.DataFrame, selector):
    """显示选股结果"""
    
    st.markdown("---")
    st.markdown("## 📊 选股结果")
    
    # 统计信息
    col1, col2, col3 = st.columns(3)
    
    with col1:
        st.metric("筛选数量", f"{len(stocks_df)} 只")
    
    with col2:
        # 智能计算平均净利增长率（过滤无效值）
        growth_col = stocks_df.get('净利润增长率', stocks_df.get('净利润同比增长率', pd.Series([])))
        valid_growth = growth_col[growth_col.notna() & (growth_col != '') & (growth_col != 'N/A')]
        if len(valid_growth) > 0:
            avg_growth = pd.to_numeric(valid_growth, errors='coerce').mean()
            if not pd.isna(avg_growth):
                st.metric("平均净利增长率", f"{avg_growth:.1f}%")
            else:
                st.metric("平均净利增长率", "-")
        else:
            st.metric("平均净利增长率", "-")
    
    with col3:
        # 智能计算平均股价（过滤无效值）
        price_col = stocks_df.get('股价', stocks_df.get('最新价', pd.Series([])))
        valid_price = price_col[price_col.notna() & (price_col != '') & (price_col != 'N/A')]
        if len(valid_price) > 0:
            avg_price = pd.to_numeric(valid_price, errors='coerce').mean()
            if not pd.isna(avg_price):
                st.metric("平均股价", f"{avg_price:.2f} 元")
            else:
                st.metric("平均股价", "-")
        else:
            st.metric("平均股价", "-")
    
    st.markdown("---")
    
    # 显示股票列表
    st.markdown("### 📋 精选股票列表")
    
    for idx, row in stocks_df.iterrows():
        # 获取股票代码和简称
        code = row.get('股票代码', 'N/A')
        name = row.get('股票简称', 'N/A')
        
        # 获取价格信息作为标题补充
        price = row.get('股价', row.get('最新价', None))
        price_str = ''
        if price is not None and not pd.isna(price):
            try:
                price_float = float(price)
                price_str = f" | 价格: {price_float:.2f}元"
            except:
                pass
        
        with st.expander(
            f"【第{idx+1}名】{code} - {name}{price_str}",
            expanded=(idx < 3)
        ):
            display_stock_detail(row)
    
    # 完整数据表格
    st.markdown("---")
    st.markdown("### 📊 完整数据表格")
    
    # 选择关键列显示
    display_cols = ['股票代码', '股票简称']
    
    # 智能匹配列名
    for pattern in ['股价', '最新价']:
        matching = [col for col in stocks_df.columns if pattern in col]
        if matching:
            display_cols.append(matching[0])
            break
    
    for pattern in ['净利润增长率', '净利润同比增长率']:
        matching = [col for col in stocks_df.columns if pattern in col]
        if matching:
            display_cols.append(matching[0])
            break
    
    for pattern in ['成交额']:
        matching = [col for col in stocks_df.columns if pattern in col]
        if matching:
            display_cols.append(matching[0])
            break
    
    for col_name in ['总市值', '市盈率', '市净率', '所属行业']:
        matching = [col for col in stocks_df.columns if col_name in col]
        if matching:
            display_cols.append(matching[0])
    
    # 选择存在的列
    final_cols = [col for col in display_cols if col in stocks_df.columns]
    
    if final_cols:
        st.dataframe(stocks_df[final_cols], width='content', height=400)
        
        # 下载按钮
        csv = stocks_df[final_cols].to_csv(index=False, encoding='utf-8-sig')
        st.download_button(
            label="📥 下载股票列表CSV",
            data=csv,
            file_name=f"low_price_bull_{datetime.now().strftime('%Y%m%d')}.csv",
            mime="text/csv"
        )
    
    # 量化交易模拟
    st.markdown("---")
    display_strategy_simulation(stocks_df, selector)


def display_stock_detail(row: pd.Series):
    """显示单个股票详情"""
    
    def is_valid_value(value):
        """判断值是否有效（非None、非NaN、非空字符串、非'N/A'）"""
        if value is None:
            return False
        if pd.isna(value):
            return False
        if str(value).strip() in ['', 'N/A', 'nan', 'None']:
            return False
        return True
    
    def format_value(value, suffix=''):
        """格式化显示值"""
        if isinstance(value, float):
            if abs(value) >= 100000000:  # 亿
                return f"{value/100000000:.2f}亿{suffix}"
            elif abs(value) >= 10000:  # 万
                return f"{value/10000:.2f}万{suffix}"
            else:
                return f"{value:.2f}{suffix}"
        return f"{value}{suffix}"
    
    # 先检查是否有任何财务数据
    has_any_data = False
    financial_fields = [
        ('所属行业', row.get('所属行业', row.get('所属同花顺行业', None))),
        ('总市值', row.get('总市值', row.get('总市值[20241211]', None))),
        ('市盈率', row.get('市盈率', row.get('市盈率pe', None))),
        ('市净率', row.get('市净率', row.get('市净率pb', None))),
        ('流通市值', row.get('流通市值', row.get('流通市值[20241211]', None))),
        ('换手率', row.get('换手率', row.get('换手率[%]', None)))
    ]
    
    for _, value in financial_fields:
        if is_valid_value(value):
            has_any_data = True
            break
    
    # 只有当存在有效数据时才显示两列布局
    if has_any_data:
        col1, col2 = st.columns(2)
    else:
        col1 = st.container()
        col2 = None
    
    with col1:
        st.markdown("#### 📊 基本信息")
        
        # 股票代码（必显示）
        code = row.get('股票代码', '')
        if is_valid_value(code):
            st.markdown(f"**股票代码**: {code}")
        
        # 股票简称（必显示）
        name = row.get('股票简称', '')
        if is_valid_value(name):
            st.markdown(f"**股票简称**: {name}")
        
        # 当前价格
        price = row.get('股价', row.get('最新价', None))
        if is_valid_value(price):
            st.markdown(f"**当前价格**: {format_value(price, '元')}")
        
        # 净利润增长率
        growth = row.get('净利润增长率', row.get('净利润同比增长率', None))
        if is_valid_value(growth):
            st.markdown(f"**净利润增长率**: {format_value(growth, '%')}")
        
        # 成交额
        turnover = row.get('成交额', None)
        if is_valid_value(turnover):
            st.markdown(f"**成交额**: {format_value(turnover, '元')}")
        
        # 涨跌幅
        change_pct = row.get('涨跌幅', row.get('涨跌幅:前复权[%]', None))
        if is_valid_value(change_pct):
            st.markdown(f"**涨跌幅**: {format_value(change_pct, '%')}")
    
    # 只有当有财务数据时才显示财务指标栏目
    if col2 is not None:
        with col2:
            st.markdown("#### 💼 财务指标")
            
            # 所属行业
            industry = row.get('所属行业', row.get('所属同花顺行业', None))
            if is_valid_value(industry):
                st.markdown(f"**所属行业**: {industry}")
            
            # 总市值
            market_cap = row.get('总市值', row.get('总市值[20241211]', None))
            if is_valid_value(market_cap):
                st.markdown(f"**总市值**: {format_value(market_cap, '元')}")
            
            # 市盈率
            pe = row.get('市盈率', row.get('市盈率pe', None))
            if is_valid_value(pe):
                st.markdown(f"**市盈率**: {format_value(pe, '')}")
            
            # 市净率
            pb = row.get('市净率', row.get('市净率pb', None))
            if is_valid_value(pb):
                st.markdown(f"**市净率**: {format_value(pb, '')}")
            
            # 流通市值
            float_cap = row.get('流通市值', row.get('流通市值[20241211]', None))
            if is_valid_value(float_cap):
                st.markdown(f"**流通市值**: {format_value(float_cap, '元')}")
            
            # 换手率
            turnover_rate = row.get('换手率', row.get('换手率[%]', None))
            if is_valid_value(turnover_rate):
                st.markdown(f"**换手率**: {format_value(turnover_rate, '%')}")
    
    # 添加监控按钮
    st.markdown("---")
    st.markdown("#### 📊 策略监控")
    
    from low_price_bull_monitor_ui import add_stock_to_monitor_button
    
    stock_code = row.get('股票代码', '')
    stock_name = row.get('股票简称', '')
    price = row.get('股价', row.get('最新价', None))
    
    # 去掉代码后缀
    if isinstance(stock_code, str) and '.' in stock_code:
        stock_code = stock_code.split('.')[0]
    
    # 转换价格
    try:
        price_float = float(price) if price and not pd.isna(price) else None
    except:
        price_float = None
    
    if stock_code and stock_name:
        add_stock_to_monitor_button(stock_code, stock_name, price_float)


def display_strategy_simulation(stocks_df: pd.DataFrame, selector):
    """显示量化交易策略模拟"""
    
    st.markdown("## 🎯 策略监控与模拟")
    
    st.info("""
    **监控说明**：
    - 在上方股票列表中点击"➕ 加入策略监控"按钮即可加入
    - 监控条件：① 持股满5天第6天开盘提醒卖出 ② MA5下穿MA20提醒卖出
    - 扫描频率：每分钟扫描1次（可在监控面板配置）
    - 提醒卖出后自动移出监控列表
    - 点击右上角"📊 策略监控"按钮查看监控面板
    """)
    
    col1, col2 = st.columns(2)
    
    with col1:
        if st.button("🎮 开始策略模拟", type="primary", width='content'):
            st.session_state.show_strategy_simulation = True
    
    with col2:
        if st.button("🔗 连接MiniQMT实盘", type="secondary", width='content'):
            st.warning("⚠️ MiniQMT实盘交易功能需要先配置环境变量，详见系统配置")
    
    # 显示模拟结果
    if st.session_state.get('show_strategy_simulation'):
        run_strategy_simulation(stocks_df)


def run_strategy_simulation(stocks_df: pd.DataFrame):
    """运行策略模拟"""
    
    st.markdown("---")
    st.markdown("### 📈 策略模拟执行")
    
    # 创建策略实例
    strategy = LowPriceBullStrategy(initial_capital=1000000.0)
    
    # 模拟买入（按成交额排序，优先买入成交额小的）
    st.markdown("#### 1️⃣ 模拟买入信号")
    
    buy_results = []
    current_date = datetime.now().strftime("%Y-%m-%d")
    
    for idx, row in stocks_df.head(strategy.max_daily_buy).iterrows():
        code = str(row.get('股票代码', '')).split('.')[0]
        name = row.get('股票简称', 'N/A')
        price = float(row.get('股价', row.get('最新价', 0)))
        
        if price > 0:
            success, message, trade = strategy.buy(code, name, price, current_date)
            buy_results.append({
                'success': success,
                'message': message,
                'trade': trade
            })
    
    # 显示买入结果
    for result in buy_results:
        if result['success']:
            st.success(result['message'])
        else:
            st.warning(f"⚠️ {result['message']}")
    
    # 显示持仓
    st.markdown("---")
    st.markdown("#### 2️⃣ 当前持仓")
    
    positions = strategy.get_positions()
    if positions:
        positions_df = pd.DataFrame(positions)
        st.dataframe(positions_df, width='content')
    else:
        st.info("暂无持仓")
    
    # 显示账户摘要
    st.markdown("---")
    st.markdown("#### 3️⃣ 账户摘要")
    
    summary = strategy.get_portfolio_summary()
    
    col1, col2, col3, col4 = st.columns(4)
    
    with col1:
        st.metric("初始资金", f"{summary['initial_capital']:,.0f} 元")
    
    with col2:
        st.metric("可用资金", f"{summary['available_cash']:,.0f} 元")
    
    with col3:
        st.metric("持仓市值", f"{summary['position_value']:,.0f} 元")
    
    with col4:
        st.metric("总资产", f"{summary['total_value']:,.0f} 元")
    
    st.markdown("---")
    
    # 策略说明
    st.markdown("#### 📝 策略执行说明")
    st.markdown("""
    **后续操作**：
    1. **持有期管理**：系统会自动跟踪每只股票的持有天数
    2. **卖出信号监测**：
       - 每日收盘后计算MA5和MA20
       - 如果MA5下穿MA20，触发卖出信号
       - 如果持股满5天，强制卖出
    3. **轮动买入**：卖出后释放资金，继续买入新的符合条件的股票
    
    **风险提示**：
    - ⚠️ 本策略为模拟演示，实际交易存在滑点、手续费等成本
    - ⚠️ 历史业绩不代表未来收益
    - ⚠️ 请谨慎评估风险，理性投资
    """)


def send_dingtalk_notification(stocks_df: pd.DataFrame, top_n: int):
    """发送钉钉通知"""
    
    try:
        # 检查webhook配置
        webhook_config = notification_service.get_webhook_config_status()
        
        if not webhook_config['enabled'] or not webhook_config['configured']:
            st.info("💡 未配置Webhook通知，如需接收钉钉消息请在环境配置中设置")
            return
        
        # 构建消息内容
        keyword = notification_service.config.get('webhook_keyword', 'aiagents通知')
        
        message_text = f"### {keyword} - 低价擒牛选股完成\n\n"
        message_text += f"**筛选策略**: 股价<10元 + 净利润增长率≥100% + 沪深A股\n\n"
        message_text += f"**筛选数量**: {len(stocks_df)} 只\n\n"
        message_text += f"**精选股票**:\n\n"
        
        for idx, row in stocks_df.head(top_n).iterrows():
            code = row.get('股票代码', '')
            name = row.get('股票简称', '')
            
            # 只显示有效的信息
            message_text += f"{idx+1}. **{code} {name}**\n"
            
            # 股价
            price = row.get('股价', row.get('最新价', None))
            if price is not None and not pd.isna(price) and str(price).strip() not in ['', 'N/A']:
                try:
                    price_float = float(price)
                    message_text += f"   - 股价: {price_float:.2f}元\n"
                except:
                    pass
            
            # 净利润增长率
            growth = row.get('净利润增长率', row.get('净利润同比增长率', None))
            if growth is not None and not pd.isna(growth) and str(growth).strip() not in ['', 'N/A']:
                try:
                    growth_float = float(growth)
                    message_text += f"   - 净利增长: {growth_float:.2f}%\n"
                except:
                    pass
            
            # 成交额
            turnover = row.get('成交额', None)
            if turnover is not None and not pd.isna(turnover) and str(turnover).strip() not in ['', 'N/A']:
                try:
                    turnover_float = float(turnover)
                    if turnover_float >= 100000000:  # 亿
                        message_text += f"   - 成交额: {turnover_float/100000000:.2f}亿元\n"
                    elif turnover_float >= 10000:  # 万
                        message_text += f"   - 成交额: {turnover_float/10000:.2f}万元\n"
                    else:
                        message_text += f"   - 成交额: {turnover_float:.2f}元\n"
                except:
                    pass
            
            # 所属行业
            industry = row.get('所属行业', row.get('所属同花顺行业', None))
            if industry is not None and not pd.isna(industry) and str(industry).strip() not in ['', 'N/A']:
                message_text += f"   - 所属行业: {industry}\n"
            
            message_text += "\n"
        
        message_text += f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
        message_text += "_此消息由AI股票分析系统自动发送_"
        
        # 直接发送钉钉Webhook（不使用notification_service的默认格式）
        if notification_service.config['webhook_type'] == 'dingtalk':
            import requests
            
            data = {
                "msgtype": "markdown",
                "markdown": {
                    "title": f"{keyword}",
                    "text": message_text
                }
            }
            
            try:
                response = requests.post(
                    notification_service.config['webhook_url'],
                    json=data,
                    headers={'Content-Type': 'application/json'},
                    timeout=10
                )
                
                if response.status_code == 200:
                    result = response.json()
                    if result.get('errcode') == 0:
                        st.success("✅ 已发送钉钉通知")
                    else:
                        st.warning(f"⚠️ 钉钉通知发送失败: {result.get('errmsg')}")
                else:
                    st.warning(f"⚠️ 钉钉通知请求失败: HTTP {response.status_code}")
            except Exception as e:
                st.warning(f"⚠️ 发送钉钉通知失败: {str(e)}")
        
    except Exception as e:
        st.warning(f"⚠️ 发送通知时出错: {str(e)}")
