# coding:utf-8

import requests
import pandas as pd
from sqlalchemy import create_engine, text
from datetime import datetime
import time
from config import XUEQIU_HEADERS

def ensure_stock_price_changes_table_exists(engine):
    """确保股价变化表存在"""
    try:
        create_table_query = text("""
            CREATE TABLE IF NOT EXISTS stock_price_changes (
                id INT AUTO_INCREMENT PRIMARY KEY,
                symbol VARCHAR(10),
                name VARCHAR(100),
                current FLOAT,
                percent FLOAT,
                time_mark VARCHAR(20),  -- '9:24:40' 或 '9:25:00'
                add_time DATETIME,
                UNIQUE KEY unique_stock_time (symbol, time_mark, add_time)
            )
        """)
        
        create_analysis_table_query = text("""
            CREATE TABLE IF NOT EXISTS rapid_price_changes (
                id INT AUTO_INCREMENT PRIMARY KEY,
                symbol VARCHAR(10),
                name VARCHAR(100),
                price_change_ratio FLOAT,  -- 两个时间点之间的涨幅
                sector_count INT,          -- 所属板块数量
                sectors TEXT,              -- 所属板块名称（逗号分隔）
                add_time DATETIME
            )
        """)
        
        with engine.connect() as conn:
            conn.execute(create_table_query)
            conn.execute(create_analysis_table_query)
            conn.commit()
        print("股价变化表检查/创建完成")
    except Exception as e:
        print("创建股价变化表时发生错误: {}".format(str(e)))

def fetch_stock_data(db_url, time_mark):
    """获取雪球数据并保存到数据库"""
    base_url = 'https://stock.xueqiu.com/v5/stock/screener/quote/list.json'
    types = ['sha', 'sza', 'kcb']
    headers = XUEQIU_HEADERS
    
    all_data = []
    
    for stock_type in types:
        # 先获取总数据量
        params = {
            'page': 1,
            'size': 100,
            'order': 'desc',
            'order_by': 'percent',
            'market': 'CN',
            'type': stock_type
        }
        
        # 初次请求以获取总页数
        response = requests.get(base_url, headers=headers, params=params)
        if response.status_code != 200:
            print(f"请求 {stock_type} 数据失败，状态码：{response.status_code}")
            continue

        data = response.json()
        total_count = data['data']['count']
        total_pages = (total_count // params['size']) + 1
        
        # 获取所有页面的数据
        for page in range(1, total_pages + 1):
            params['page'] = page
            response = requests.get(base_url, headers=headers, params=params)
            if response.status_code == 200:
                data = response.json()
                all_data.extend(data['data']['list'])
            else:
                print(f"请求 {stock_type} 数据第 {page} 页失败，状态码：{response.status_code}")
    
    if all_data:
        df = pd.DataFrame(all_data)
        selected_columns = ['symbol', 'name', 'current', 'percent']
        df = df[selected_columns]
        df['symbol'] = df['symbol'].str[2:]  # 去掉前缀
        df['time_mark'] = time_mark
        df['add_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        
        engine = create_engine(db_url)
        ensure_stock_price_changes_table_exists(engine)
        
        # 先删除同一时间标记的旧数据
        with engine.connect() as conn:
            delete_query = text("""
                DELETE FROM stock_price_changes 
                WHERE time_mark = :time_mark 
                AND DATE(add_time) = CURDATE()
            """)
            conn.execute(delete_query, {'time_mark': time_mark})
            conn.commit()
        
        # 保存新数据
        df.to_sql('stock_price_changes', con=engine, if_exists='append', index=False)
        print(f"成功保存{len(df)}条{time_mark}的股价数据")
        return True
    return False

def analyze_price_changes(db_url):
    """分析两个时间点之间的板块涨跌情况"""
    engine = create_engine(db_url)
    
    try:
        # 获取所有股票的涨跌幅数据
        query = text("""
            SELECT 
                t1.symbol,
                t1.name,
                ((t2.current - t1.current) / t1.current * 100) as price_change_ratio
            FROM
                stock_price_changes t1
                JOIN stock_price_changes t2 ON t1.symbol = t2.symbol
            WHERE 
                t1.time_mark = '9:24:00'
                AND t2.time_mark = '9:25:10'
                AND DATE(t1.add_time) = CURDATE()
                AND DATE(t2.add_time) = CURDATE()
        """)
        
        price_changes_df = pd.read_sql_query(query, engine)
        
        if not price_changes_df.empty:
            # 获取板块信息
            gp_gnbk_df = pd.read_sql_table('gp_gnbk', con=engine)
            
            # 合并获取板块信息
            merged_df = price_changes_df.merge(gp_gnbk_df, left_on='symbol', right_on='gp_code')
            
            # 按板块统计涨幅超过1%的股票数量和总数
            sector_stats = []
            for bk_name in merged_df['bk_name'].unique():
                sector_stocks = merged_df[merged_df['bk_name'] == bk_name]
                total_count = len(sector_stocks)
                up_count = len(sector_stocks[sector_stocks['price_change_ratio'] > 0.7])
                ratio = up_count / total_count if total_count > 0 else 0
                
                sector_stats.append({
                    'sector_name': bk_name,
                    'up_count': up_count,
                    'total_count': total_count,
                    'ratio': ratio,
                    'add_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                })
            
            # 转换为DataFrame并按比例排序
            result_df = pd.DataFrame(sector_stats)
            result_df = result_df.sort_values('ratio', ascending=False)
            
            # 打印分析结果
            print("\n=== 板块涨幅分析结果 ===")
            print(f"分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            print("\n{:<15} {:<8} {:<8} {:<10}".format(
                "板块名称", "上涨家数", "总家数", "占比"
            ))
            print("-" * 45)
            
            # 打印所有板块数据
            for _, row in result_df.iterrows():
                print("{:<15} {:<8d} {:<8d} {:<10.2f}%".format(
                    row['sector_name'],
                    row['up_count'],
                    row['total_count'],
                    row['ratio'] * 100
                ))
            
            print("\n总计分析板块数量:", len(result_df))
            
        else:
            print("未获取到股价变化数据")
            
    except Exception as e:
        print("分析数据时发生错误: {}".format(str(e)))

def main(db_url):
    """主函数"""
    engine = create_engine(db_url)

    target_time_1 = datetime.now().replace(hour=9, minute=24, second=0, microsecond=0)
    target_time_2 = datetime.now().replace(hour=9, minute=25, second=10, microsecond=0)
    current_time = datetime.now()

    # 如果当前时间已经超过了第二个时间点，直接进行分析
    if current_time > target_time_2:
        print("当前时间已超过9:24:00，直接进行数据分析...")
        analyze_price_changes(db_url)
        return

    # 如果还没到第一个时间点，等待
    if current_time < target_time_1:
        wait_seconds = (target_time_1 - current_time).total_seconds()
        print(f"等待{wait_seconds}9:24:00...")
        time.sleep(wait_seconds)
    
    # 获取第一次数据
    success_1 = fetch_stock_data(db_url, '9:24:00')
    
    if success_1:
        # 如果还没到第二个时间点，等待
        current_time = datetime.now()
        if current_time < target_time_2:
            wait_seconds = (target_time_2 - current_time).total_seconds()
            print(f"等待{wait_seconds}9:25:10...")
            time.sleep(wait_seconds)
        
        # 获取第二次数据
        success_2 = fetch_stock_data(db_url, '9:25:10')
        
        if success_2:
            # 分析数据
            analyze_price_changes(db_url)
        else:
            print("9:25:10数据失败")
    else:
        print("9:24:00数据失败")

if __name__ == "__main__":
    db_url = 'mysql+pymysql://root:Chlry#$.8@192.168.18.199:3306/db_gp_cj'
    main(db_url)