"""LEKO 下号（UIN）API 流程 RPA · step3 回执下号结果（API 流程专用）。

与 source 流程 `rpa_leko_step3_save.py` 对应：
- source 流程：直连 source 库写 `Base_AnnexesFile` + `EPRRegInfo.RegBackNumber` +
  `PushTaxBureauStatus=4`；
- API 流程：改调本服务回执接口 `POST /api/epr/leko-rpa/result`，服务端写目标库
  `reg_code`（UIN）/ `cert_oss_url`，并**由服务端**按契约 §13 调用 SaaS 统一异步
  通知（delivery/rpa/callback）——RPA 不直连 SaaS、不重试通知。

自包含约束：禁止 import 其它 rpa 脚本。
"""

import json

import requests

# ===== 部署常量（按环境修改）=====
FR_EPR_RPA_BASE_URL = 'http://automation.usaeu.com:8888/fr_epr_reg'
RESULT_PATH = '/api/epr/leko-rpa/result'
REQUEST_TIMEOUT_SECONDS = 30


def save_uin_result(
    task_id: int,
    reg_code: str,
    cert_key: str | None = None,
    cert_name: str | None = None,
    base_url: str = FR_EPR_RPA_BASE_URL,
) -> dict:
    """回执下号成功（UIN + 证书相对 key），服务端落库并触发 SaaS 异步通知。

    Args:
        task_id: step1 认领返回的 task_id
        reg_code: 下号结果（UIN / 注册码）
        cert_key: step2 上传返回的 OSS 相对路径（无证书时传 None）
        cert_name: 证书文件名（缺省取 cert_key 的末段）

    Returns:
        dict: {"task_id": ..., "notify_status": "success"|"failed"}
        （notify_status 为服务端向 SaaS 的投递结果；failed 表示 SaaS 通知未成功，
        服务端已记录 Notify* 列，可人工重发）

    Raises:
        RuntimeError: 接口返回非 200 code。
    """
    payload = {
        'task_id': task_id,
        'status': 'success',
        'reg_code': reg_code,
        'cert_key': cert_key,
    }
    if cert_name:
        payload['cert_name'] = cert_name

    return _post_result(payload, base_url)


def report_failure(
    task_id: int,
    error_message: str,
    base_url: str = FR_EPR_RPA_BASE_URL,
) -> dict:
    """回执下号失败：服务端标记任务失败并发送失败通知（契约 §13，data=null）。"""
    return _post_result({
        'task_id': task_id,
        'status': 'failed',
        'error_message': error_message,
    }, base_url)


def _post_result(payload: dict, base_url: str) -> dict:
    url = base_url.rstrip('/') + RESULT_PATH

    response = requests.post(
        url,
        data=json.dumps(payload, ensure_ascii=False),
        headers={'Content-Type': 'application/json; charset=utf-8'},
        timeout=REQUEST_TIMEOUT_SECONDS,
    )
    body = json.loads(response.text) if response.text else {}

    if response.status_code != 200 or body.get('code') != 200:
        raise RuntimeError(
            f"回执失败: HTTP {response.status_code} code={body.get('code')} msg={body.get('msg')}"
        )

    data = body.get('data') or {}
    print(
        '✅ 回执成功: task_id={task_id} notify_status={notify}'.format(
            task_id=data.get('task_id'),
            notify=data.get('notify_status'),
        )
    )
    return data


if __name__ == '__main__':
    # 本地自测：成功回执示例
    print(save_uin_result(
        task_id=1,
        reg_code='UIN123456',
        cert_key='common-test/generatefile/2026/fr_epr_reg/leko/FREPR2026000001/UIN-Certificate.pdf',
    ))
