from qcloud_cos import CosConfig, CosS3Client
import os
from datetime import datetime
from urllib.parse import quote

# API流程上传桶（COS 桶分流：与 source 流程桶不同）：API 流程结果归 SaaS 共享桶，
# 固定 usaeu-1259285998（与 es_haiya rpa_030_save.py API_FLOW_BUCKET_DEFAULT 同值）；
# RPA 为独立运行一次的程序，不读环境变量
API_FLOW_BUCKET = 'usaeu-1259285998'

# API流程 OSS 相对路径前缀（对象键 {前缀}{年}/{模块目录}/{文件名} 的前缀）：
# 按部署环境配置——测试环境 common-test/generatefile/、正式环境 common-prod/generatefile/；
# 与 es_haiya API_FLOW_OSS_PREFIX 同规则；RPA 进程与项目 .env 隔离，部署时保持为对应环境的常量
API_FLOW_OSS_PREFIX = 'common-test/generatefile/'

# API流程生成文件子目录（年份文件夹之后；注册回执/确认文件、VAT 证书、EORI 截图同目录存放）
API_FLOW_OSS_MODULE_DIR = 'uk_vat_register'


def upload_to_tencent_cos(
    local_file_path: str,
    cos_secret_id: str,
    cos_secret_key: str,
    cos_region: str,
    cos_bucket_name: str,
    cos_key_path: str,
    data_source: str = 'source',
    record_id: str = ''
) -> str:
    """
    上传文件到腾讯云COS，覆盖同名文件。成功返回地址，失败返回空字符串。

    按数据来源分流（与 es_haiya rpa_030_save.py 同模式）：
      - api（data_source='api'）：上传桶固定 API_FLOW_BUCKET（SaaS 共享桶 usaeu-1259285998，
        忽略传入桶，密钥/地域仍用传入值）；对象键 = {API_FLOW_OSS_PREFIX}{当前年}/
        {API_FLOW_OSS_MODULE_DIR}/[{record_id}/]{文件名}（忽略传入 cos_key_path，无时间戳子文件夹）；
        record_id（uk_vat_register 行主键）为记录唯一标识：本地文件名是 HMRC 页面标题固定名，
        缺省时不加记录子目录、两条记录同名文件会互相覆盖（后传覆盖先传），调用方务必传入；
        返回 OSS 相对路径（不带域名、不 URL 编码）——入库与 delivery 通知 files.url 均为
        相对路径，域名由接收方按自身规则拼接
      - source（缺省，原逻辑不变）：桶/路径用传入值，返回完整 URL

    Args:
        local_file_path (str): 本地文件路径
        cos_secret_id (str): 腾讯云SecretId
        cos_secret_key (str): 腾讯云SecretKey
        cos_region (str): 地域，如 'ap-guangzhou'
        cos_bucket_name (str): 存储桶名称（source 流程桶；api 流程忽略，改用固定共享桶）
        cos_key_path (str): COS上的路径前缀，如 'uploads/pva/12345'（api 流程忽略，改用固定模板）
        data_source (str): 数据来源 'api' / 'source'（缺省 source，旧调用不受影响）
        record_id (str): 记录主键（api 流程唯一标识，对象键插入 {record_id}/ 子目录；
            空串时退化为不加子目录的旧模板，仅兼容未升级调用方）

    Returns:
        str: api 流程成功返回 OSS 相对路径；source 流程成功返回完整 URL；失败返回空字符串 ""
    """
    # 检查本地文件是否存在
    if not os.path.exists(local_file_path):
        print(f"❌ 本地文件不存在: {local_file_path}")
        return ""

    try:
        # 初始化配置
        config = CosConfig(
            Region=cos_region,
            SecretId=cos_secret_id,
            SecretKey=cos_secret_key,
            Scheme='https'
        )
        client = CosS3Client(config)

        # 生成COS对象键
        filename = os.path.basename(local_file_path)
        is_api_flow = str(data_source or 'source').strip().lower() == 'api'
        if is_api_flow:
            # API流程：桶分流至 SaaS 共享桶，对象键用固定模板
            # {前缀}{年}/{模块目录}/[{record_id}/]{文件名}——record_id 子目录隔离不同记录，
            # 防同名文件覆盖（文件名来自 HMRC 页面标题，每条记录固定一致）
            if cos_bucket_name and cos_bucket_name != API_FLOW_BUCKET:
                print(f"🔄 API流程上传桶分流: {cos_bucket_name} → {API_FLOW_BUCKET}")
            upload_bucket = API_FLOW_BUCKET
            record_id = str(record_id or '').strip().strip('/')
            if not record_id:
                print(f"⚠️ API流程未传 record_id，对象键无记录唯一标识，同名文件将互相覆盖: {filename}")
            cos_object_key = '/'.join([
                API_FLOW_OSS_PREFIX.strip('/'),
                datetime.now().strftime('%Y'),
                API_FLOW_OSS_MODULE_DIR.strip('/'),
            ] + ([record_id] if record_id else []) + [filename])
        else:
            # source流程：原逻辑不变（传入桶 + cos_key_path/文件名）
            upload_bucket = cos_bucket_name
            cos_object_key = f"{cos_key_path.rstrip('/')}/{filename}"

        # 执行上传（自动覆盖同名文件）
        print(f"🔄 开始上传: {local_file_path} → {upload_bucket}/{cos_object_key}")
        response = client.upload_file(
            Bucket=upload_bucket,
            LocalFilePath=local_file_path,
            Key=cos_object_key,
            PartSize=1,
            MAXThread=5,
            EnableMD5=False
        )

        if response is not None:
            if is_api_flow:
                # API流程：返回 OSS 相对路径（不带域名，delivery 接收方自行拼接下载域名）
                print(f"✅ 上传成功（API流程相对路径）: {cos_object_key}")
                return cos_object_key
            # source流程：返回完整 URL（原逻辑）
            encoded_key = quote(cos_object_key, safe='/ ')
            file_url = f'https://{upload_bucket}.cos.{cos_region}.myqcloud.com/{encoded_key}'
            print(f"✅ 上传成功: {file_url}")
            return file_url
        else:
            print("❌ 上传失败：响应为空")
            return ""

    except Exception as e:
        print(f"❌ 上传异常: {str(e)}")
        return ""
