from .base import BaseDataProvider
from typing import Any, Dict, List, Optional
import pandas as pd
from datetime import datetime

# 假设 iFinDPy 库已安装在环境中
# 重要提示: 用户需要根据官方文档手动安装 iFinDPy
try:
    from iFinDPy import THS_iFinDLogin, THS_BD, THS_HQ
except ImportError:
    print("错误: iFinDPy 模块未找到。请确保已按照同花顺官方指引完成安装。")
    # 定义虚拟函数以避免在未安装时程序崩溃
    def THS_iFinDLogin(*args, **kwargs): return -1
    def THS_BD(*args, **kwargs): return pd.DataFrame()
    def THS_HQ(*args, **kwargs): return pd.DataFrame()


class TonghsProvider(BaseDataProvider):
    _is_logged_in = False

    def __init__(self, token: Optional[str] = None):
        # 使用从 iFinD 用户中心获取的 Refresh Token 进行登录
        if not TonghsProvider._is_logged_in:
            if not token:
                raise ValueError("同花顺 iFinDPy Refresh Token 未在配置中提供。")
            
            # 调用登录函数，直接传入 token
            # 注意: 具体的关键字参数名可能需要根据 iFinDPy 的实际文档确认，这里假设为 'token' 或直接作为第一个参数
            login_result = THS_iFinDLogin(token)
            
            if login_result == 0:
                print("同花顺 iFinDPy 登录成功。")
                TonghsProvider._is_logged_in = True
            else:
                print(f"同花顺 iFinDPy 登录失败，错误码: {login_result}")
                raise ConnectionError("无法登录到同花顺 iFinDPy 服务，请检查您的 Refresh Token 是否正确。")

    async def get_stock_basic(self, stock_code: str) -> Optional[Dict[str, Any]]:
        try:
            # TODO: 请用户确认用于获取公司基本信息的指标 (indicators)
            indicators = "ths_stock_short_name_stock;ths_listed_market_stock;ths_industry_stock;ths_ipo_date_stock"
            data = THS_BD(stock_code, indicators, "")
            
            if data.empty:
                return None
                
            # --- 数据归一化 ---
            # iFinDPy 返回的数据通常是 DataFrame，我们需要将其转换为字典
            info = data.iloc[0].to_dict()

            return {
                "ts_code": stock_code,
                "name": info.get("ths_stock_short_name_stock"),
                "area": info.get("ths_listed_market_stock"),
                "industry": info.get("ths_industry_stock"),
                "list_date": info.get("ths_ipo_date_stock"),
            }
        except Exception as e:
            print(f"同花顺 iFinDPy get_stock_basic 执行失败, 股票代码 {stock_code}: {e}")
            return None

    async def get_daily_price(self, stock_code: str, start_date: str, end_date: str) -> List[Dict[str, Any]]:
        try:
            # TODO: 请用户确认用于获取日线行情的指标
            indicators = "open;high;low;close;volume"
            # iFinDPy 的日期格式通常是 YYYY-MM-DD
            date_range = f"{start_date};{end_date}"
            
            data = THS_HQ(stock_code, indicators, date_range)
            
            if data.empty:
                return []
            
            # --- 数据归一化 ---
            data = data.reset_index()
            data.rename(columns={
                "time": "trade_date",
                "open": "open",
                "high": "high",
                "low": "low",
                "close": "close",
                "volume": "vol"
            }, inplace=True)
            
            return data.to_dict('records')
        except Exception as e:
            print(f"同花顺 iFinDPy get_daily_price 执行失败, 股票代码 {stock_code}: {e}")
            return []

    async def get_financial_statements(self, stock_code: str, report_dates: List[str]) -> List[Dict[str, Any]]:
        try:
            # TODO: 请用户确认获取财务报表的指标
            # 这可能需要多次调用 THS_BD 并合并结果
            
            # 示例：一次性获取多个报告期的数据
            # 将 report_dates 转换为 iFinDPy 接受的格式，例如 "2022-12-31;2021-12-31"
            dates_param = ";".join(report_dates)
            
            # 需要的指标
            income_indicators = "ths_np_stock" # 净利润
            bs_indicators = "ths_total_assets_stock;ths_total_liab_stock" # 总资产;总负债
            revenue_indicators = "ths_revenue_stock" # 营业收入

            # 获取数据
            income_data = THS_BD(stock_code, income_indicators, f"reportDate={dates_param}")
            bs_data = THS_BD(stock_code, bs_indicators, f"reportDate={dates_param}")
            revenue_data = THS_BD(stock_code, revenue_indicators, f"reportDate={dates_param}")

            # 合并数据
            financials_df = pd.concat([income_data, bs_data, revenue_data], axis=1)
            financials_df = financials_df.loc[:,~financials_df.columns.duplicated()]
            financials_df = financials_df.reset_index().rename(columns={"index": "end_date"})

            # --- 数据归一化 ---
            financials_df.rename(columns={
                "ths_revenue_stock": "revenue",
                "ths_np_stock": "net_income",
                "ths_total_assets_stock": "total_assets",
                "ths_total_liab_stock": "total_liabilities",
            }, inplace=True)
            
            financials_df["ts_code"] = stock_code
            
            return financials_df.to_dict('records')
        except Exception as e:
            print(f"同花顺 iFinDPy get_financial_statements 执行失败, 股票代码 {stock_code}: {e}")
            return []

    async def get_financial_statement(self, stock_code: str, report_date: str) -> Optional[Dict[str, Any]]:
        results = await self.get_financial_statements(stock_code, [report_date])
        return results[0] if results else None
