# -*- coding: utf-8 -*-
import requests
import json
import os
import glob
import time
from typing import Tuple
import os
from openai import OpenAI
import re
import base64
from Speechgenerator import *
"""
总： 时间 概念 解释

1. 去重 & 删掉噪声单词
2. 概念标号，重新添加格式： ID,时间戳,概念,解释

======== 图像对齐（服务器）=====
* 对每一个文件进行遍历，因为每一个txt文件，对应几张照片
* 如果文件中的概念在最后的概念列表中，加入到对齐列表中
* 便利文件中的每一个图，以base64和prompt的形式传入gpt4o进行对齐
* 建立互索引，将图像和概念进行互索引，保存分别到以追加方式保存在json文件中
* 注意，每对齐一次写一次，图片的命名为images+数字，概念的命名为json中的index，为concept+数字


"""
concept = []

def imageAnalysis(image_path: str, subject: str, concepts: list ,model="gpt-4o-2024-11-20") -> str:
    prompt = f"""
        You are an AI  {subject} image analyst. Follow this strict protocol:
        1. Candidate Verification:
           Within the {subject} concepts {concept},
           identify and extract the concepts that appear in the image or are highly related to it. 
           Use these extracted concepts to form the C4 .
        2. Multilevel Analysis:
        a) OCR Extraction: Capture ALL {subject} pure concept  in  → C1
        b) Regional Analysis: Identify specific  {subject} components → C2
        c) Holistic Analysis: Derive tissue/system-level {subject} concepts → C3
        3. Deduplication Protocol:
        Priority: C4 > C3 > C2 > C1
        - Remove duplicates ONLY for identical terms
        - Preserve hierarchical terms (e.g., keep both "上皮组织" and "小肠上皮细胞")
        4. Output Decision:
        - If any valid terms remain: List ALL in bullet format
        - If completely empty: Output "none"
        Mandatory Format:
        - concept1
        - concept2
        ...

        OR
        "none"
        Absolute constraints:
        1. No term suppression except exact duplicates
        2. No explanations, categories, or formatting variations.
    """
    with open(image_path, "rb") as image_file:
        base64_image = base64.b64encode(image_file.read()).decode("utf-8")   
    url = "https://api.chatfire.cn/v1/chat/completions"
    payload = json.dumps({
    "model": model,
    "messages": [
        {
                "role": "user",
                "content": [
                    {"type": "text", "text": f"{prompt}"},
                    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_image}"}},
                ],
            }
    ]
    })
    headers = {
        'Accept': 'application/json',
        'Authorization': 'Bearer sk-ygAo2alTCCo1i0CHXe6fPd2xlyKouDKxlui2PGDGo7d150pA',
        'Content-Type': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload)
    response_json = response.json()
    return response_json["choices"][0]["message"]["content"]

def conceptVideo(file_path: str, subject: str, concepts: list) -> str:
    videoConcept = {}
    video_counter = 1  # 用于生成唯一视频ID：v1,v2,v3,...

    # 检查一级文件夹是否存在
    if not os.path.isdir(file_path):
        return json.dumps(videoConcept, ensure_ascii=False)

    # 遍历一级文件夹下所有二级文件夹
    for folder in os.listdir(file_path):
        folder_path = os.path.join(file_path, folder)
        if not os.path.isdir(folder_path):
            continue

        # 在当前二级文件夹中查找后缀为"_Intergrationner"的文件
        integration_file = None
        for item in os.listdir(folder_path):
            item_path = os.path.join(folder_path, item)
            if os.path.isfile(item_path) and item.endswith("_Intergrationner"):
                integration_file = item_path
                break  # 每个二级文件夹只处理一个匹配的整合文件
        if integration_file is None:
            continue  # 如果未找到整合文件，则跳过此文件夹
        
        # 解析整合文件，文件中过滤掉空行后奇数行为时间戳，偶数行为概念
        time_to_concepts = {}
        try:
            with open(integration_file, "r", encoding="utf-8") as f:
                # 过滤空行，并去除首尾空白字符
                all_lines = [line.strip() for line in f if line.strip() != ""]
        except Exception as e:
            print(f"读取文件 {integration_file} 时出错：{e}")
            continue
        
        # 若行数不是偶数，则按最后一行无法配对处理，可忽略最后一行
        for i in range(0, len(all_lines) - 1, 2):
            ts_line = all_lines[i]
            concepts_line = all_lines[i+1]
            # 使用正则提取时间戳行中第一个时间，如格式 "00:10-02:11"
            m = re.match(r"(\d{2}:\d{2})-\d{2}:\d{2}", ts_line)
            if m:
                ts = m.group(1)
                concept_list = concepts_line.split()
                time_to_concepts[ts] = concept_list
            else:
                # 若时间戳格式不符合要求，则跳过当前对
                continue

        # 查找二级文件夹内的三级文件夹（假设视频均存放在这些子文件夹中）
        third_level_dirs = [d for d in os.listdir(folder_path) 
                            if os.path.isdir(os.path.join(folder_path, d))]
        if not third_level_dirs:
            continue
        
        for subfolder in third_level_dirs:
            subfolder_path = os.path.join(folder_path, subfolder)
            for video_file in os.listdir(subfolder_path):
                video_file_path = os.path.join(subfolder_path, video_file)
                if not os.path.isfile(video_file_path):
                    continue
                # 视频文件命名以"clip_"开头
                if not video_file.startswith("clip_"):
                    continue
                # 通过正则提取视频文件中的时间戳部分，例如 "clip_00_10_..." -> "00_10"
                m_video = re.search(r"clip_(\d{2}_\d{2})", video_file)
                if not m_video:
                    continue
                video_ts_raw = m_video.group(1)
                video_ts = video_ts_raw.replace("_", ":")  # 转换为 "00:10"
                # 若该时间戳存在于整合文件中，则构建视频与概念的映射数据
                if video_ts in time_to_concepts:
                    extracted_concepts = time_to_concepts[video_ts]
                    # 如果传入的过滤概念列表不为空，则保留仅在concepts中出现的概念
                    if concepts:
                        filtered = [c for c in extracted_concepts if c in concepts]
                        final_concepts = filtered if filtered else extracted_concepts
                    else:
                        final_concepts = extracted_concepts
                    video_id = "v" + str(video_counter)
                    videoConcept[video_id] = final_concepts
                    video_counter += 1
                    
    return json.dumps(videoConcept, ensure_ascii=False, indent=2)
        
def conceptAudio(file_path:str):
    concept_dict = {}
    cnt = 1
    with open(file_path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:  # 跳过空行
                continue
            parts = line.split("\t", 1)  # 以第一个制表符为界分割
            if len(parts) == 2:
                concept, explanation = parts
                speechGenerator(concept, explanation, "./")
                print(cnt)
                cnt += 1
                               
def mainImages(file_path: str, jsonFile:str, subject: str) -> None:
    # 以追加和读取模式打开文件
    imageC = {}
    with open(f"imageConceptIndex_{subject}", "a+", encoding="utf-8") as files:
        files.seek(0)  # 移动到文件开头以读取内容
        content = files.read()
        cnt = 0
        
        # obtain all txt
        txt_files = glob.glob(os.path.join(file_path, '**', '*_Intergrationner'), recursive=True)
        for txt_file in txt_files:
            print("*"*10)
            print(txt_file)
            print("*"*10)
            concepts_list = []
            data = {}
            with open(txt_file, 'r', encoding='utf-8') as file:
                for line in file:
                    match = re.match(r'(\d{2}:\d{2}-\d{2}:\d{2})\s+(.+)', line.strip())
                    if match:
                        time_range, concepts = match.groups()
                        for con in concepts.split():
                            if con not in concepts_list:
                                concepts_list.append(con) 

            #==========================================================      
            folder_path = os.path.dirname(txt_file)
            png_files = glob.glob(os.path.join(folder_path, "*.png"))
            add_concepts = []
            for png in png_files:
                imageC[str(cnt)+".png"] = []
                result1  = imageAnalysis(png, subject, concepts_list, model="gpt-4o-2024-11-20")
                result2 = imageAnalysis(png, subject, concepts_list, model="gpt-4o-2024-11-20")
                result3 = imageAnalysis(png, subject, concepts_list, model="gpt-4o-2024-11-20")
                result1 = re.findall(r"-\s*(\w+)", result1)
                result2 = re.findall(r"-\s*(\w+)", result2)
                result3 = re.findall(r"-\s*(\w+)", result3)
                result = set(result1) | set(result2) | set(result3)
                #print("*"*10)
                #print(f"result1: {result1}\n result2: {result2}\n result3: {result3}\n")
                #print(f"png: {png}\n  result {result}\n concepts_list {concepts_list}\n concept {concept}\n")
                #print("*"*10)
                
                if result == "none":
                    continue   
                else:
                    #result =  re.findall(r"-\s*(\w+)", result)
                    for r in result:
                        try:
                            index = concept.index(r)
                            imageC[str(cnt)+".png"].append(index)
                        except:
                            concept.append(r)
                            add_concepts.append(r)
                            imageC[str(cnt)+".png"].append(len(concept)-1)
                directory = os.path.dirname(png)
                new_path = os.path.join(directory, str(cnt)+".png")
                os.rename(png, new_path)
                files.write(f"{str(cnt)}.png ")
                for i in imageC[str(cnt)+".png"]:
                    files.write(str(i)+" ")
                files.write("\n")

                cnt += 1
                if add_concepts != []:
                    with open(jsonFile, "r", encoding="utf-8") as fa:
                        res = json.load(fa)
                    fa.close()
                    for i in add_concepts:
                        dat = {}
                        dat["time"] = "none"
                        dat['concept'] = i
                        dat['explanation'] = "none"
                        res.append(dat)
                    with open(jsonFile, "w", encoding="utf-8") as fa:
                        json.dump(res, fa, ensure_ascii=False, indent=4)
                        fa.close()
                                                   
def readConcepts(conceptPath: str) -> None:
    """
    读取概念文件，返回概念列表
    """
    global concept
    with open(conceptPath, "r", encoding="utf-8") as f:
        # 读取已有的数据
        existing_data = json.load(f)
    for item in existing_data:
        concept.append(item['concept'])
    f.close()
    
if __name__ == "__main__":
    subject = "biology"
    fileList = r"F:\2.实验\3.Datasets\1.国家中小学智慧平台数据集\0.smartEdu\tools\test"
    jsonFile = r"F:\2.实验\3.Datasets\1.国家中小学智慧平台数据集\0.smartEdu\tools\test\concepts.json"
    # 读取概念文件
    readConcepts(jsonFile)
    # 图像对齐
    mainImages(fileList, jsonFile, subject)
    
    
    
