import json
import logging
import time
import uuid
import oss2
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException, ServerException
# 尝试导入最新的 API 版本，如果有问题可能需要调整
try:
    from aliyunsdktingwu.request.v20230930 import CreateTaskRequest, GetTaskInfoRequest
except ImportError:
    # Fallback or error handling if version differs
    pass
    
from django.conf import settings

logger = logging.getLogger(__name__)

class AliyunTingwuService:
    def __init__(self):
        self.access_key_id = settings.ALIYUN_ACCESS_KEY_ID
        self.access_key_secret = settings.ALIYUN_ACCESS_KEY_SECRET
        self.oss_bucket_name = settings.ALIYUN_OSS_BUCKET_NAME
        self.oss_endpoint = settings.ALIYUN_OSS_ENDPOINT
        self.tingwu_app_key = settings.ALIYUN_TINGWU_APP_KEY
        self.region_id = "cn-shanghai" # 听悟服务区域，根据文档应与OSS区域一致，或者使用 'cn-beijing'

        # 初始化 OSS Bucket
        if self.access_key_id and self.access_key_secret and self.oss_endpoint:
             auth = oss2.Auth(self.access_key_id, self.access_key_secret)
             self.bucket = oss2.Bucket(auth, self.oss_endpoint, self.oss_bucket_name)
        else:
            self.bucket = None
            logger.warning("Aliyun OSS configuration missing.")
        
        # 初始化听悟 Client
        if self.access_key_id and self.access_key_secret:
            self.client = AcsClient(
                self.access_key_id,
                self.access_key_secret,
                self.region_id
            )
            # 显式添加听悟服务的 Endpoint 映射，解决 EndpointResolvingError
            # 听悟 API 的服务接入点通常是 tingwu.cn-beijing.aliyuncs.com
            # 但新版听悟 API (tingwu.aliyuncs.com) 可能不同，需根据实际情况添加
            # 这里添加一个通用的 Endpoint 映射
            try:
                # 尝试为 tingwu 产品设置 Endpoint
                # 注意：听悟服务主要部署在北京，Endpoint 通常为 tingwu.cn-beijing.aliyuncs.com
                # 如果您的服务在上海，也可能需要连接到北京的接入点
                self.client.add_endpoint(self.region_id, "tingwu", "tingwu.cn-beijing.aliyuncs.com")
            except Exception as e:
                logger.warning(f"Failed to add endpoint: {e}")

        else:
            self.client = None
            logger.warning("Aliyun AccessKey configuration missing.")

    def upload_to_oss(self, file_obj, file_name):
        """
        上传文件到 OSS 并返回带签名的 URL (有效期 3 小时)
        """
        if not self.bucket:
            raise Exception("OSS Client not initialized")
            
        try:
            # 上传文件
            # file_obj 应该是打开的文件对象或字节流
            self.bucket.put_object(file_name, file_obj)
            
            # 生成签名 URL，有效期 3 小时 (3600 * 3)
            url = self.bucket.sign_url('GET', file_name, 3600 * 3)
            return url
        except Exception as e:
            logger.error(f"OSS Upload failed: {e}")
            raise e

    def create_transcription_task(self, file_url, language="cn"):
        """
        创建听悟转写任务
        """
        if not self.client:
             raise Exception("Tingwu Client not initialized")

        request = CreateTaskRequest.CreateTaskRequest()
        
        # 针对阿里云 SDK 不同版本的兼容性处理
        # "type" 参数是听悟 API (ROA 风格) 的必填项，用于指定任务类型
        # 根据官方文档，离线任务的 type 通常就是 'offline'
        request.add_query_param('type', 'offline') 
        
        # 构造请求体 (Body)
        # 根据听悟 API 文档，AppKey, Input, Parameters 应位于 JSON Body 中
        # 而不是 Query Parameter
        body = {
            "AppKey": self.tingwu_app_key,
            "Input": {
                "FileUrl": file_url,
                "SourceLanguage": language,
                "TaskKey": str(uuid.uuid4())
            },
            "Parameters": {
                "Transcoding": {
                    "TargetAudioFormat": "mp3"
                },
                "AutoChaptersEnabled": True,
                "SummarizationEnabled": True,
                "Summarization": {
                    "Types": ["Paragraph", "Conversational", "QuestionsAnswering", "MindMap"]
                } 
            }
        }
        
        # 设置 Body 内容
        request.set_content(json.dumps(body))
        request.add_header('Content-Type', 'application/json')
        
        # 强制设置 Endpoint，避免 SDK.EndpointResolvingError
        # 听悟目前主要服务点在北京
        request.set_endpoint("tingwu.cn-beijing.aliyuncs.com")

        # 显式设置 Method 为 PUT
        request.set_method('PUT')

        try:
            response = self.client.do_action_with_exception(request)
            return json.loads(response)
        except (ClientException, ServerException) as e:
            logger.error(f"Tingwu CreateTask failed: {e}")
            raise e

    def get_task_info(self, task_id):
        """
        查询任务状态和结果
        """
        if not self.client:
             raise Exception("Tingwu Client not initialized")

        request = GetTaskInfoRequest.GetTaskInfoRequest()
        request.set_TaskId(task_id)
        
        try:
            response = self.client.do_action_with_exception(request)
            return json.loads(response)
        except (ClientException, ServerException) as e:
            logger.error(f"Tingwu GetTaskInfo failed: {e}")
            raise e
