import pandas as pd
import numpy as np
from datetime import datetime

try:
    from .config import TS_TOKEN, START_DATE, END_DATE, PRECISION_CONFIG
    from .stock_utils import *
    from .smoothBrush import smooth_dataframe_brush
except (ImportError, SystemError):
    from config import TS_TOKEN, START_DATE, END_DATE, PRECISION_CONFIG
    from stock_utils import *
    from smoothBrush import smooth_dataframe_brush

from .data_source import get_tushare_pro

pro = get_tushare_pro()
'''
给定个股代码和起止日期：
1.  调用tushare接口查询个股分红数据，接口文档：https://tushare.pro/document/2?doc_id=103 查询日期范围内的所有分红记录
2.  返回调整后的分红记录，包含以下字段：
    - ts_code: 股票代码
    - end_date: 分红年度
    - ann_date: 公告日期
    - ex_date: 除权除息日
    - cash_div_tax: 每股现金分红（含税）
    - div_proc: 实施进度,仅筛选 div_proc='实施'的记录
3.  调用tushare 的trade_cal接口，查询起止日期内的所有交易日
4.  建一个新的df,在起止日期内填充，规则：
    - 下列运算过程中将起始时间往前推 gap_days,赋值360天。运算结束后，截取起止时间内的数据
    - trade_date: 以交易日历为准，填充所有交易日。
    - 填入当ex_date=trade_date的日期，填入：ex_date,cash_div_tax，其余日期ex_date留空，cash_div_tax 置 0
    - cash_div_year:逐行计算填入，以trade_date往前计算过去gap_days天内的cash_div_tax之和
5. 调用tushare的个股日线行情接口：https://tushare.pro/document/2?doc_id=27，查询起止日期内的个股日线行情数据，包含以下字段：
    - ts_code: 股票代码
    - trade_date: 交易日期
    - close: 收盘价
6. 将分红数据和日线行情数据按交易日期合并，得到最终结果，包含以下字段：
    - ts_code: 股票代码
    - trade_date: 交易日期
    - close: 收盘价
    - cach_div_tax: 每股现金分红（含税）
    - cach_div_year: 每股现金TTM年度分红（含税）
    - div_yield: 股息率，计算公式为 (cach_div_year / close) * 100，保留PRECISION_CONFIG位小数，如果cash_div_year为0则div_yield也为0
7. 返回最终结果的DataFrame
'''
def analyze_stock_dividend_and_price(ts_code, start_date=START_DATE, end_date=END_DATE):
    # 检查日期范围是否超过当前日期，若超过则调整为当前日期
    start_date=date_format_correction(start_date)
    end_date=date_format_correction(end_date)
    today = datetime.now().strftime("%Y%m%d")
    if end_date > today: end_date = today
    if start_date > today: start_date = today

    GAP_DAYS = 360  # 定义TTM计算窗口期为360天
    """
    分析个股分红与行情数据。

    参数:
    ts_code (str): 股票代码，例如 '000001.SZ'。
    start_date (str): 起始日期，格式 'YYYYMMDD'。
    end_date (str): 结束日期，格式 'YYYYMMDD'。

    返回:
    pd.DataFrame: 包含合并后数据的DataFrame。
    """
    
    # 1. 调用tushare接口查询个股分红数据
    try:
        df_div_raw = pro.dividend(ts_code=ts_code)
        # 2. 筛选并调整分红记录
        # 筛选实施进度为'实施'的记录，并在指定日期范围内
        df_div_filtered = df_div_raw[
            (df_div_raw['div_proc'] == '实施')
        ].copy()

        df_div_adjusted = df_div_filtered[[
            'ts_code', 'end_date', 'ann_date', 'ex_date', 'cash_div_tax'
        ]].reset_index(drop=True)
    
    except Exception as e:
        print(f"获取或处理分红数据时出错: {e}")
        return pd.DataFrame() # 返回空DataFrame

    # 3. 调用tushare 的trade_cal接口，查询交易日
    try:
        # 运算时起始时间往前推 GAP_DAYS
        calc_start_date = pd.to_datetime(start_date) - pd.Timedelta(days=GAP_DAYS)
        calc_start_date_str = calc_start_date.strftime('%Y%m%d')
        
        df_cal = pro.trade_cal(exchange='', start_date=calc_start_date_str, end_date=end_date)
        # 筛选交易日
        trade_dates_all = df_cal[df_cal['is_open'] == 1]['cal_date'].sort_values().tolist()
        
    except Exception as e:
        print(f"获取交易日历时出错: {e}")
        return pd.DataFrame()

    # 4. 建立新df并填充
    df_div_processed = pd.DataFrame({'trade_date': trade_dates_all})
    df_div_processed['trade_date'] = pd.to_datetime(df_div_processed['trade_date'], format='%Y%m%d')

    # 将原始分红数据的ex_date也转为datetime以便合并
    df_div_adjusted['ex_date'] = pd.to_datetime(df_div_adjusted['ex_date'], format='%Y%m%d')
    
    # 合并分红数据到交易日历
    df_merged_temp = df_div_processed.merge(df_div_adjusted[['ex_date', 'cash_div_tax']], 
                                            left_on='trade_date', right_on='ex_date', how='left')
    df_merged_temp.drop('ex_date', axis=1, inplace=True)
    # 填充空值
    df_merged_temp['cash_div_tax'] = df_merged_temp['cash_div_tax'].fillna(0.0)
    
    # 计算 cash_div_year (TTM) — 向量化 rolling 窗口
    df_merged_temp = df_merged_temp.sort_values('trade_date').reset_index(drop=True)
    df_temp = df_merged_temp.set_index('trade_date')
    df_temp['cash_div_year'] = df_temp['cash_div_tax'].rolling(f'{GAP_DAYS}D', min_periods=1).sum()
    df_merged_temp['cash_div_year'] = df_temp['cash_div_year'].values


    # 截取原始请求的起止时间内的数据
    start_date_dt = pd.to_datetime(start_date, format='%Y%m%d')
    end_date_dt = pd.to_datetime(end_date, format='%Y%m%d')
    df_div_final = df_merged_temp[
        (df_merged_temp['trade_date'] >= start_date_dt) & 
        (df_merged_temp['trade_date'] <= end_date_dt)
    ].copy()
    df_div_final['trade_date'] = df_div_final['trade_date'].dt.strftime('%Y%m%d')

    # 5. 调用tushare的个股日线行情接口
    try:
        df_daily = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date)
        df_daily = df_daily[['ts_code', 'trade_date', 'close']].sort_values('trade_date').reset_index(drop=True)
    except Exception as e:
        print(f"获取日线行情数据时出错: {e}")
        return pd.DataFrame()

    # 6. 合并分红数据和日线行情数据
    df_result = df_daily.merge(df_div_final[['trade_date', 'cash_div_tax', 'cash_div_year']], 
                               on='trade_date', how='left')
    
    # 填充因合并可能产生的NaN（例如，某日有行情但无分红记录）
    df_result['cash_div_tax'] = df_result['cash_div_tax'].fillna(0.0)
    df_result['cash_div_year'] = df_result['cash_div_year'].fillna(0.0)
    
    
    # 毛刺平滑处理 cash_div_year 列
    df_result=smooth_dataframe_brush(df_result, target_columns=['cash_div_year'], window_size=31,  threshold_factor=0.5, max_brush_length=15 )
    # 恢复原始日期顺序
    df_result = df_result.sort_values('trade_date').reset_index(drop=True)

    # 计算股息率
    df_result['div_yield'] = 0.0
    mask_non_zero_price = df_result['close'] > 0
    mask_non_zero_div_year = df_result['cash_div_year'] > 0
    # 只对收盘价大于0且TTM分红大于0的记录计算股息率
    valid_mask = mask_non_zero_price & mask_non_zero_div_year
    df_result.loc[valid_mask, 'div_yield'] = (
        (df_result.loc[valid_mask, 'cash_div_year'] / df_result.loc[valid_mask, 'close']) * 100
    ).round(PRECISION_CONFIG)

    # 7. 返回最终结果
    # 重命名字段以匹配要求 (注意: 题目中'cach_div_tax'应为'cash_div_tax')
    #df_result.rename(columns={'cash_div_tax': 'cach_div_tax', 'cash_div_year': 'cach_div_year'}, inplace=True)
    
    final_columns = ['ts_code', 'trade_date', 'close', 'cash_div_tax', 'cash_div_year', 'div_yield']
    df_final = df_result[final_columns]

    return df_final



# --- 示例用法 ---
if __name__ == "__main__":
    start_dt = '2020-01-01'
    end_dt = '2025-12-31'
    ts_code = '000001.SZ'
    result = analyze_stock_dividend_and_price(ts_code, start_dt, end_dt)
    print(f"股票 {ts_code} 的分红与行情数据分析结果:")
    print(result.head(10))
    print(f"\n数据总行数: {len(result)}")