import sys
import os
# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

from .indicators import BALANCE_SHEET_MAPPING, PROFIT_STATEMENT_MAPPING, CASH_FLOW_STATEMENT_MAPPING
from .chinese_field_normalizer import normalize_chinese_field

from enum import Enum
import pdfplumber
import tempfile
import os

def extract_text_above_table(table_info, pdf_content):
    """
    根据表格坐标信息，提取表格上方的文本内容
    """
    if not table_info or 'bbox' not in table_info:
        return ""
    
    try:
        with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp_file:
            tmp_file.write(pdf_content)
            tmp_path = tmp_file.name
        
        text_above = ""
        with pdfplumber.open(tmp_path) as pdf:
            current_page = pdf.pages[table_info['page_number'] - 1]  # 当前页面
            total_pages = len(pdf.pages)
            
            # 获取页面边界
            page_bbox = current_page.bbox
            page_width = page_bbox[2] - page_bbox[0]
            page_height = page_bbox[3] - page_bbox[1]
            
            # 获取表格边界框
            table_bbox = table_info['bbox']
            table_y0 = table_bbox[1]  # 表格上边界
            
            # 定义搜索区域：表格上方200个单位的区域（约2-4行文本）
            search_height = 200
            
            # 确保搜索区域不超出页面边界
            search_x0 = max(page_bbox[0], table_bbox[0])  # 左边界不小于页面左边界
            search_x1 = min(page_bbox[2], table_bbox[2])  # 右边界不大于页面右边界
            search_y0 = max(page_bbox[1], table_y0 - search_height)  # 上边界不小于页面上边界
            search_y1 = min(page_bbox[3], table_y0)  # 下边界不大于页面下边界
            
            search_bbox = (search_x0, search_y0, search_x1, search_y1)
            
            # 提取当前页面搜索区域内的文本
            text_above = current_page.within_bbox(search_bbox).extract_text() or ""
            
            # 如果表格在页面顶部且搜索高度不够，尝试从上一页获取更多内容
            if table_y0 - search_height <= page_bbox[1] and table_info['page_number'] > 1:
                # 表格在页面顶部，需要检查上一页
                prev_page = pdf.pages[table_info['page_number'] - 2]  # 上一页
                
                # 从上一页底部开始搜索
                prev_page_bbox = prev_page.bbox
                prev_page_height = prev_page_bbox[3] - prev_page_bbox[1]
                prev_page_search_height = min(search_height - (table_y0 - page_bbox[1]), prev_page_height)  # 剩余搜索高度
                
                if prev_page_search_height > 0:
                    prev_page_bbox_search = (
                        search_x0,  # 左边界
                        prev_page_bbox[3] - prev_page_search_height,  # 上边界（上一页底部开始）
                        search_x1,  # 右边界
                        prev_page_bbox[3]  # 下边界（上一页底部）
                    )
                    
                    prev_page_text = prev_page.within_bbox(prev_page_bbox_search).extract_text() or ""
                    text_above = prev_page_text + "\n" + text_above
            
        # 删除临时文件
        try:
            os.unlink(tmp_path)
        except:
            pass
            
        return text_above if text_above else ""
        
    except Exception as e:
        return ""

class TableType(Enum):
    BALANCE_SHEET = "balance_sheet"
    PROFIT_STATEMENT = "profit_statement"
    CASH_FLOW_STATEMENT = "cash_flow_statement"
    UNKNOWN = "unknown"

#表格类型与映射的对应关系
TABLE_MAPPING ={
    TableType.BALANCE_SHEET: BALANCE_SHEET_MAPPING,
    TableType.PROFIT_STATEMENT: PROFIT_STATEMENT_MAPPING,
    TableType.CASH_FLOW_STATEMENT: CASH_FLOW_STATEMENT_MAPPING,
}

# 资产负债表关键词列表
BALANCE_SHEET_KEYWORDS = [
    {"name": "货币资金", "value": 0},
    {"name": "应收账款", "value": 0},
    {"name": "存货", "value": 0},
    {"name": "固定资产", "value": 0},
    {"name": "应付账款", "value": 0},
    {"name": "股本", "value": 0},
    {"name": "未分配利润", "value": 0},
    {"name": "盈余公积", "value": 0}
]

PROFIT_STATEMENT_KEYWORDS = [
    {"name": "营业收入", "value": 0},
    {"name": "营业成本", "value": 0},
    {"name": "税金及附加", "value": 0},
    {"name": "销售费用", "value": 0},
    {"name": "管理费用", "value": 0},
    {"name": "财务费用", "value": 0},
    {"name": "营业利润", "value": 0},
    {"name": "利润总额", "value": 0},
    {"name": "所得税费用", "value": 0},
    {"name": "净利润", "value": 0}
]

CASH_FLOW_STATEMENT_KEYWORDS = [
    {"name": "经营活动产生的现金流量净额", "value": 0},
    {"name": "投资活动产生的现金流量净额", "value": 0},
    {"name": "筹资活动产生的现金流量净额", "value": 0},
    {"name": "销售商品、提供劳务收到的现金", "value": 0},
    {"name": "购买商品、接受劳务支付的现金", "value": 0},
    {"name": "支付给职工以及为职工支付的现金", "value": 0},
    {"name": "支付的各项税费", "value": 0},
    {"name": "取得投资收益收到的现金", "value": 0},
    {"name": "购建固定资产、无形资产和其他长期资产支付的现金", "value": 0},
    {"name": "吸收投资收到的现金", "value": 0},
    {"name": "取得借款收到的现金", "value": 0},
    {"name": "偿还债务支付的现金", "value": 0},
    {"name": "分配股利、利润或偿付利息支付的现金", "value": 0},
    {"name": "现金及现金等价物净增加额", "value": 0},
    {"name": "期初现金及现金等价物余额", "value": 0},
    {"name": "期末现金及现金等价物余额", "value": 0}
]

CASH_FLOW_STATEMENT_NOT_KEYWORDS = [
    "销售费用",
    "研发费用",
    "管理费用",
    "营业收入",
    "营业成本"
]

# 母公司报表识别关键词（用于排除）
PARENT_COMPANY_KEYWORDS = [
    "母公司利润表",
    "母公司资产负债表",
    "母公司现金流量表"
]

def parse_number_string(number_str):
   
    # 将金额字符串转换为数字类型
    # 支持格式：-1231239890.98号、小数点）

    if not number_str or number_str == "":
        return 0
    
    # 去掉所有逗号，保留负号和小数点
    cleaned_str = str(number_str).replace(",", "")
    try:
        return float(cleaned_str)
    except ValueError:
        return 0

def identify_table_type(table, table_info=None):
    """
    识别表格类型
    """
    if not table:
        return TableType.UNKNOWN
    
    # 重置关键词匹配状态
    for keyword in BALANCE_SHEET_KEYWORDS:
        keyword["value"] = 0
    for keyword in PROFIT_STATEMENT_KEYWORDS:
        keyword["value"] = 0
    for keyword in CASH_FLOW_STATEMENT_KEYWORDS:
        keyword["value"] = 0
    
    # 检查表格内容
    for row in table:
        for cell in row:
            if cell:
                cell_str = str(cell).strip()
                normalized_name = normalize_chinese_field(cell_str)
                
                # 检查资产负债表关键词
                for keyword in BALANCE_SHEET_KEYWORDS:
                    if normalized_name and keyword["name"] in normalized_name:
                        keyword["value"] = 1
                
                # 检查利润表关键词
                for keyword in PROFIT_STATEMENT_KEYWORDS:
                    if normalized_name and keyword["name"] in normalized_name:
                        keyword["value"] = 1
                
                # 检查现金流量表关键词
                for keyword in CASH_FLOW_STATEMENT_KEYWORDS:
                    if normalized_name and keyword["name"] in normalized_name:
                        keyword["value"] = 1
    
    # 统计匹配数量
    balance_count = sum(1 for keyword in BALANCE_SHEET_KEYWORDS if keyword["value"] == 1)
    profit_count = sum(1 for keyword in PROFIT_STATEMENT_KEYWORDS if keyword["value"] == 1)
    cash_flow_count = sum(1 for keyword in CASH_FLOW_STATEMENT_KEYWORDS if keyword["value"] == 1)
    
    # 判断表格类型
    if balance_count >= 6:
        return TableType.BALANCE_SHEET
    elif profit_count >= 6:
        return TableType.PROFIT_STATEMENT
    elif cash_flow_count >= 3:  # 调整为至少匹配3个现金流量表关键词
        return TableType.CASH_FLOW_STATEMENT
    else:
        return TableType.UNKNOWN

def extract_value_from_row(row, table, row_index):
    """
    从行中提取数值
    """
    if not row or len(row) < 2:
        return None
    
    # 尝试从第2列或第3列提取数值
    for col_index in [1, 2]:
        if col_index < len(row) and row[col_index] is not None:
            value = parse_number_string(row[col_index])
            if value is not None:
                return value
    
    return None

def transfrom_table_to_json(table, table_info=None):
    """
    将表格转换为JSON格式
    """
    if table_info is None:
        table_info = {}
    
    # 检查是否为母公司报表
    if is_parent_company_table(table, table_info):
        return None
    
    # 识别表格类型
    table_type = identify_table_type(table, table_info)

    # 往前推断 - 检查表格上方文本是否包含对应的表类型关键词
    if table_info and 'pdf_content' in table_info:
        try:
            text_above = extract_text_above_table(table_info, table_info['pdf_content'])
            
            # 根据识别出的表格类型，检查上方文本是否包含对应的关键词
            if table_type == TableType.PROFIT_STATEMENT:
                # 检查是否包含"利润表"关键词
                profit_keywords = ["利润表", "损益表", "收益表"]
                if not any(keyword in text_above for keyword in profit_keywords):
                    # 如果没有找到利润表关键词，可能是误判，返回None
                    return None
                    
            elif table_type == TableType.BALANCE_SHEET:
                # 检查是否包含"资产负债表"关键词
                balance_keywords = ["资产负债表", "财务状况表"]
                if not any(keyword in text_above for keyword in balance_keywords):
                    # 如果没有找到资产负债表关键词，可能是误判，返回None
                    return None
                    
            elif table_type == TableType.CASH_FLOW_STATEMENT:
                # 检查是否包含"现金流量表"关键词
                cash_flow_keywords = ["现金流量表", "现金流动表"]
                if not any(keyword in text_above for keyword in cash_flow_keywords):
                    # 如果没有找到现金流量表关键词，可能是误判，返回None
                    return None
                    
        except Exception:
            # 如果提取文本失败，继续处理
            pass
    
    # 如果无法识别表格类型，返回None
    if table_type == TableType.UNKNOWN:
        return None
    
    # 获取对应的字段映射
    field_mapping = TABLE_MAPPING.get(table_type)
    if not field_mapping:
        return None
    
    # 识别表头结构，确定数值列位置
    header = table[0] if table else []
    note_idx = header.index('附注') if '附注' in header else None
    value_offset = 2 if note_idx == 1 else 1  # 附注在第2列则数值在第3列，否则在第2列
    
    # 去掉表头，只处理数据行
    data_rows = table[1:] if len(table) > 1 else []
    
    # 提取数据
    result = {}
    unmatched_fields = []
    
    for row in data_rows:
        if not row or len(row) == 0:
            continue
            
        # 中文名
        name = row[0] if row and len(row) > 0 and row[0] is not None else ""
        # 数值
        value = row[value_offset] if row and len(row) > value_offset else None
        
        if not name or name.strip() == "":
            continue
            
        # 标准化中文字段名
        normalized_name = normalize_chinese_field(name)
        
        # 使用精准匹配查找对应的英文字段名
        matched = False
        for chinese_name, english_name in field_mapping.items():
            if normalized_name and chinese_name == normalized_name:  # 精准匹配
                result[english_name] = parse_number_string(value)
                matched = True
                break
        
        # 如果没有匹配到，记录为未匹配字段
        if not matched:
            # if table_type == TableType.BALANCE_SHEET and value is not None:
            #     print(f"未匹配到: {name}")
            #     print('*'*100)
            unmatched_fields.append({
                "chinese_name": name,
                "value": parse_number_string(value),
                "row_data": row
            })
    
    # 验证数据完整性
    validation_result = validate_financial_data(result, table_type)
    
    # 构建最终结果
    final_result = {
        table_type.value: result,
        "unmatched_fields": unmatched_fields,
        "validation": validation_result
    }
    
    # 添加位置信息
    if table_info:
        final_result.update({
            "position": table_info.get("position", ""),
            "page_number": table_info.get("page_number", 0),
            "table_index": table_info.get("table_index", 0),
            "bbox": table_info.get("bbox", ()),
            "x0": table_info.get("x0", 0),
            "y0": table_info.get("y0", 0),
            "x1": table_info.get("x1", 0),
            "y1": table_info.get("y1", 0),
            "width": table_info.get("width", 0),
            "height": table_info.get("height", 0),
            "center_x": table_info.get("center_x", 0),
            "center_y": table_info.get("center_y", 0)
        })
    
    return final_result

def validate_financial_data(table_json, table_type):
    """
    校验财务数据的正确性
    
    Args:
        table_json: 提取的财务数据字典
        table_type: 表格类型
        
    Returns:
        dict: 包含校验结果和错误信息的字典
    """
    validation_result = {
        "is_valid": True,
        "errors": [],
        "warnings": [],
        "data_quality_score": 100
    }
    
    if not table_json or table_type == "unknown":
        validation_result["is_valid"] = False
        validation_result["errors"].append("无效的表格数据或未知表格类型")
        validation_result["data_quality_score"] = 0
        return validation_result
    
    # 数据完整性检查
    if table_type == "balance_sheet":
        validation_result = validate_balance_sheet(table_json, validation_result)
    elif table_type == "profit_statement":
        validation_result = validate_profit_statement(table_json, validation_result)
    elif table_type == "cash_flow_statement":
        validation_result = validate_cash_flow_statement(table_json, validation_result)
    
    return validation_result

def validate_balance_sheet(data, result):
    """校验资产负债表数据"""
    
    # 检查关键字段是否存在
    required_fields = ["monetary_funds", "accounts_receivable", "inventory", 
                      "fixed_assets", "accounts_payable", "paid_in_capital"]
    
    for field in required_fields:
        if field not in data or data[field] is None:
            result["warnings"].append(f"缺少关键字段: {field}")
            result["data_quality_score"] -= 5
    
    return result

def validate_profit_statement(data, result):
    """校验利润表数据"""
    
    # 检查关键字段
    required_fields = ["operating_revenue", "operating_cost", "operating_profit", 
                      "total_profit", "net_profit_final"]
    
    for field in required_fields:
        if field not in data or data[field] is None:
            result["warnings"].append(f"缺少关键字段: {field}")
            result["data_quality_score"] -= 5
    
    return result

def validate_cash_flow_statement(data, result):
    """校验现金流量表数据"""
    
    # 检查关键字段
    required_fields = ["net_cash_flows_from_operating_activities", 
                      "net_cash_flows_from_investing_activities",
                      "net_cash_flows_from_financing_activities"]
    
    for field in required_fields:
        if field not in data or data[field] is None:
            result["warnings"].append(f"缺少关键字段: {field}")
            result["data_quality_score"] -= 5
    
    return result

def check_data_consistency(table_json):
    """
    检查数据一致性
    
    Args:
        table_json: 包含多个表格数据的字典
        
    Returns:
        dict: 一致性检查结果
    """
    consistency_result = {
        "is_consistent": True,
        "inconsistencies": [],
        "warnings": [],
        "consistency_score": 100
    }
    
    return consistency_result

def is_parent_company_table(table, table_info=None):
    """
    判断是否为母公司报表
    """
    if not table:
        return False
    
    # 检查表格上方文本
    if table_info and 'pdf_content' in table_info:
        try:
            text_above = extract_text_above_table(table_info, table_info['pdf_content'])
            for keyword in PARENT_COMPANY_KEYWORDS:
                if keyword in text_above:
                    return True
        except Exception:
            pass
    
    return False