import os
import re
import pandas as pd
import jieba
from collections import defaultdict


# ----------------------------
# 1. 加载词典
# -----------  -----------------
def load_dictionary_txt(txt_path):
    dictionary = {}
    current_construct = None
    # 增加 '行动' 的映射
    construct_map = {'意图': 'intention', '认知': 'cognition', '想象': 'imagination', '学习': 'learning',
                     '行动': 'action'}

    with open(txt_path, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if line.startswith('#'):
                cn_name = line[1:].split(' - ')[0].strip()
                current_construct = construct_map.get(cn_name)
                if current_construct and current_construct not in dictionary:
                    dictionary[current_construct] = set()
            elif line and current_construct:
                words = [w.strip() for w in line.split(',') if w.strip()]
                dictionary[current_construct].update(words)
    return dictionary


# ----------------------------
# 2. 从文件名提取 stock_code 和 report_year
# ----------------------------
def parse_filename(filename):
    base = filename.replace('.txt', '')
    parts = base.split('_')
    stock_code = parts[0] if parts else None
    year_match = re.search(r'(\d{4})年', parts[-1]) if parts else None
    report_year = year_match.group(1) if year_match else None
    return stock_code, report_year


# ----------------------------
# 3. 切分句子（中文）
# ----------------------------
def split_into_sentences(text):
    sentences = re.split(r'[。！？；]', text)
    return [s.strip() for s in sentences if s.strip()]


# ----------------------------
# 4. 判断句子是否为“有效语境”
# ----------------------------
def is_valid_context(sentence):
    invalid_phrases = ['据', '报道称', '认为', '指出', '表示', '据悉', '有媒体', '分析师', '第三方', '外界']
    return not any(phrase in sentence for phrase in invalid_phrases)


# ----------------------------
# 5. 分词、计数并计算共现
# ----------------------------
def count_keywords_and_cooccurrence(text, keyword_sets):
    # 1. 将所有关键词（包括行动词）加入 jieba 自定义词典，防止被切碎
    all_words = set()
    for kw_set in keyword_sets.values():
        all_words.update(kw_set)
    for word in all_words:
        jieba.add_word(word)

    sentences = split_into_sentences(text)

    # 初始化基础计数器
    counts = {k: 0 for k in keyword_sets.keys()}

    # 【新增】初始化共现计数器
    # 关心“想象”和“行动”的共现，回应审稿人关于“空洞修辞”的质疑
    imagination_action_coupling = 0

    for sent in sentences:
        if not is_valid_context(sent):
            continue

        # 对当前句子进行分词
        tokens = list(jieba.cut(sent))

        # 标记当前句子是否包含“想象”类词汇
        has_imagination_word = False
        # 标记当前句子是否包含“行动”类词汇
        has_action_word = False

        # 遍历分词结果
        for t in tokens:
            for construct, kw_set in keyword_sets.items():
                if t in kw_set:
                    counts[construct] += 1
                    # 如果是“想象”词，标记为True
                    if construct == 'imagination':
                        has_imagination_word = True
                    # 如果是“行动”词，标记为True
                    if construct == 'action':
                        has_action_word = True

        # 【核心逻辑】如果当前句子同时包含“想象”和“行动”，说明这是一种“落地的叙事”
        if has_imagination_word and has_action_word:
            imagination_action_coupling += 1

    # 将共现次数加入返回的字典
    counts['imagination_action_coupling'] = imagination_action_coupling
    return counts


# ----------------------------
# 6. 主分析函数
# ----------------------------
def analyze_report(file_path, dictionary):
    filename = os.path.basename(file_path)
    stock_code, report_year = parse_filename(filename)
    if not stock_code or not report_year:
        return {'file': filename, 'error': 'parse_failed'}

    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            text = f.read()
    except Exception as e:
        return {'file': filename, 'error': str(e)}

    scores = count_keywords_and_cooccurrence(text, dictionary)
    return {
        'stock_code': stock_code,
        'report_year': report_year,
        'intention_score': scores['intention'],
        'cognition_score': scores['cognition'],
        'imagination_score': scores['imagination'],
        'learning_score': scores['learning'],
        'action_score': scores['action'],  # 输出行动词的总频次，作为控制变量
        'imagination_action_coupling': scores['imagination_action_coupling']  # 新增的耦合度指标
    }


# ----------------------------
# 7. 批量处理主程序
# ----------------------------
if __name__ == "__main__":
    # 设置实际路径
    BASE_DIR = r"D:\学术研究\066研究数据与论文撰写\01研究数据\新理论论文撰写\第十稿修订\data and log\Keyword Extraction Scripts and Text Data"
    txt_folder = BASE_DIR
    dict_path = os.path.join(BASE_DIR, "rci_cil_dictionary.txt")
    # 修改输出文件名，提示这是包含耦合度的版本
    output_path = os.path.join(BASE_DIR, "rci_cil_scores_with_coupling.csv")

    if not os.path.exists(dict_path):
        raise FileNotFoundError(f"词典文件未找到: {dict_path}")
    if not os.path.exists(txt_folder):
        raise FileNotFoundError(f"年报文件夹不存在: {txt_folder}")

    # 加载词典
    dictionary = load_dictionary_txt(dict_path)
    print("✅ 词典加载完成")

    files = [f for f in os.listdir(txt_folder) if f.endswith('.txt')]
    print(f"📁 共找到 {len(files)} 份年报文件，开始处理...")

    if not files:
        print("⚠️ 警告：未找到任何 .txt 文件！请检查路径是否正确。")
    else:
        results = []
        for i, file in enumerate(files):
            if i % 50 == 0:
                print(f"📊 已处理 {i}/{len(files)}")
            res = analyze_report(os.path.join(txt_folder, file), dictionary)
            results.append(res)

        df = pd.DataFrame(results)
        df.to_csv(output_path, index=False, encoding='utf_8_sig')
        print(f"\n🎉 处理完成！结果已保存至:\n{output_path}")