from fastapi import UploadFile
import os
from typing import Optional
import tempfile
import requests
import time
from tqdm import tqdm
from pathlib import Path

class ProgressFileReader:
    def __init__(self, file_path, progress_bar):
        self.file = open(file_path, 'rb')
        self.progress_bar = progress_bar
    
    def read(self, size=-1):
        data = self.file.read(size)
        if data:
            self.progress_bar.update(len(data))
        return data
    
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()
async def convert_doc_to_pdf(api_url: str, file: UploadFile, timeout: int = 300) -> Optional[str]:
    """
    将DOC文件转换为pdf
    
    参数:
        api_url: 转换服务的URL (如 "http://172.18.127.124:8000")
        file: 要转换的UploadFile对象
        timeout: 请求超时时间(秒)
    """
    try:
        with tempfile.NamedTemporaryFile(delete=False, suffix=".doc") as tmp_doc:
            content = await file.read()
            tmp_doc.write(content)
            tmp_path = tmp_doc.name
        
        file_name = file.filename
        file_size = os.path.getsize(tmp_path)
        output_name = Path(file_name).stem + ".pdf"
        
        with tqdm(total=file_size, unit='B', unit_scale=True, desc="上传进度") as pbar:
            with ProgressFileReader(tmp_path, pbar) as file_reader:
                files = {'file': (file_name, file_reader)}
                params = {'src': 'doc', 'to': 'pdf'}
                
                response = requests.post(
                    f"{api_url}/transfer",
                    files=files,
                    params=params,
                    timeout=timeout
                )

        if response.status_code == 200:
            with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_docx:
                tmp_docx.write(response.content)
                output_path = tmp_docx.name
            
            os.unlink(tmp_path)
            
            return output_path
        else:
            raise Exception(f"转换失败: {response.text}")

    except requests.exceptions.Timeout:
        raise Exception(f"请求超时(超过{timeout}秒)")
    except requests.exceptions.RequestException as e:
        raise Exception(f"请求错误: {str(e)}")
    except Exception as e:
        # 确保临时文件被清理
        if 'tmp_path' in locals() and os.path.exists(tmp_path):
            os.unlink(tmp_path)
        if 'output_path' in locals() and os.path.exists(output_path):
            os.unlink(output_path)
        raise Exception(f"转换过程中出错: {str(e)}")

async def convert_docx_to_pdf(api_url: str, file: UploadFile, timeout: int = 300) -> Optional[str]:
    """
    将DOCX文件转换为PDF（解决中文缺失问题）
    
    参数:
        api_url: 转换服务的URL (如 "http://172.18.127.124:8000")
        file: 要转换的UploadFile对象
        timeout: 请求超时时间(秒)
    """
    try:
        # 创建临时文件保存上传的DOCX
        with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp_docx:
            content = await file.read()
            tmp_docx.write(content)
            tmp_path = tmp_docx.name
        
        # 获取文件信息
        file_name = file.filename
        file_size = os.path.getsize(tmp_path)
        output_name = Path(file_name).stem + ".pdf"

        print(f"正在转换: {file_name} ({file_size/1024:.1f} KB) -> PDF")
        start_time = time.time()

        # 使用带进度条的文件读取器
        with tqdm(total=file_size, unit='B', unit_scale=True, desc="上传进度") as pbar:
            with ProgressFileReader(tmp_path, pbar) as file_reader:
                files = {'file': (file_name, file_reader)}
                params = {
                    'src': 'docx',
                    'to': 'pdf',
                    'font': 'SimSun',  
                    'encoding': 'utf-8'  
                }
                
                response = requests.post(
                    f"{api_url}/transfer",
                    files=files,
                    params=params,
                    timeout=timeout
                )

        # 处理响应
        if response.status_code == 200:

            with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_pdf:
                tmp_pdf.write(response.content)
                output_path = tmp_pdf.name
            

            if os.path.getsize(output_path) < 1024:  # 如果PDF文件过小
                raise Exception("生成的PDF可能不包含有效内容")
            
            elapsed = time.time() - start_time
            print(f"\n转换成功! 保存为: {output_path}")
            print(f"总耗时: {elapsed:.2f}秒")
            
            os.unlink(tmp_path)
            
            return output_path
        else:
            raise Exception(f"转换失败: {response.text}")

    except requests.exceptions.Timeout:
        raise Exception(f"请求超时(超过{timeout}秒)")
    except requests.exceptions.RequestException as e:
        raise Exception(f"请求错误: {str(e)}")
    except Exception as e:
        # 确保临时文件被清理
        if 'tmp_path' in locals() and os.path.exists(tmp_path):
            os.unlink(tmp_path)
        if 'output_path' in locals() and os.path.exists(output_path):
            os.unlink(output_path)
        raise Exception(f"转换过程中出错: {str(e)}")
    


#调用示例：
async def split_result(file: UploadFile = File(...),
    chunk_type: str = Form("01"),
    chunk_size: int = Form(256),
    chunk_overlap: int = Form(50),
    max_level: Optional[int]=Form(3)):
    """
    拆分结果
    """
    filename = file.filename
    file_ext = os.path.splitext(filename)[1] 

    if file_ext == ".docx":
        # 处理DOCX文件
        converted_path = await convert_docx_to_pdf(os.getenv("CONVERT_DOC_URL","http://172.18.127.124:8000"), file)
            
        # 读取转换后的DOCX文件
        with open(converted_path, 'rb') as f:
            converted_file = UploadFile(filename=f"{PATH(filename).stem}.pdf", file=f,headers=headers)
            #调用Mineru
            md_content = await process_pdf_logic(converted_file)