# -*- coding: utf-8 -*-
import requests
from alibabacloud_dingtalk.wiki_2_0.client import Client as dingtalkwiki_2_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dingtalk.wiki_2_0 import models as wiki_models
from alibabacloud_tea_util import models as util_models

APP_KEY = "dinguetojbaxvvhzpk3d"
APP_SECRET = "lMFqns_ceLIcXvfLL8GKfa3ZiPKHcaZq0VbGtJXJlDuK8AEJ2WV3-PN8zv61ajm3"

# ------------------- DingTalk 基础 -------------------
def get_access_token():
    url = "https://oapi.dingtalk.com/gettoken"
    resp = requests.get(url, params={"appkey": APP_KEY, "appsecret": APP_SECRET}).json()
    if resp.get("errcode") == 0:
        return resp["access_token"]
    raise Exception(f"获取token失败: {resp}")

def get_department_list(token, parent_id=1):
    """递归获取所有部门 ID"""
    url = "https://oapi.dingtalk.com/topapi/v2/department/listsub"
    resp = requests.post(url, params={"access_token": token}, json={"dept_id": parent_id}).json()
    if resp.get("errcode") != 0:
        raise Exception(f"获取部门失败: {resp}")

    dept_list = resp["result"]
    all_depts = [d["dept_id"] for d in dept_list]
    for d in dept_list:
        all_depts.extend(get_department_list(token, d["dept_id"]))
    return all_depts

def get_department_users(token, dept_id):
    """获取部门成员 userid 列表"""
    url = "https://oapi.dingtalk.com/topapi/user/listid"
    resp = requests.post(url, params={"access_token": token}, json={"dept_id": dept_id}).json()
    if resp.get("errcode") == 0:
        return resp.get("result", {}).get("userid_list", [])
    else:
        print(f"❌ 获取部门用户失败 dept_id={dept_id}: {resp}")
        return []

def get_unionid(token, userid):
    """通过 userId 获取 unionid"""
    url = "https://oapi.dingtalk.com/topapi/v2/user/get"
    resp = requests.post(url, params={"access_token": token}, json={"userid": userid}).json()
    if resp.get("errcode") != 0:
        raise Exception(f"获取unionid失败: {resp}")
    return resp["result"]["unionid"]

# ------------------- Wiki 部分 -------------------
def create_wiki_client():
    config = open_api_models.Config()
    config.protocol = 'https'
    config.region_id = 'central'
    return dingtalkwiki_2_0Client(config)

def get_user_root_node_id(client, token, operator_id):
    """获取用户个人空间 rootNodeId"""
    headers = wiki_models.GetMineWorkspaceHeaders()
    headers.x_acs_dingtalk_access_token = token
    req = wiki_models.GetMineWorkspaceRequest(operator_id=operator_id)
    try:
        result = client.get_mine_workspace_with_options(req, headers, util_models.RuntimeOptions())

        if hasattr(result.body, "workspace") and hasattr(result.body.workspace, "root_node_id"):
            return result.body.workspace.root_node_id
        return None
    except Exception as e:
        print(f"获取 {operator_id} rootNodeId 失败: {e}")
        return None

def list_all_nodes(client, operator_id, parent_node_id, token):
    """递归获取 Wiki 节点，返回有层级结构的列表"""
    headers = wiki_models.ListNodesHeaders()
    headers.x_acs_dingtalk_access_token = token
    request = wiki_models.ListNodesRequest(
        operator_id=operator_id,
        parent_node_id=parent_node_id
    )
    try:
        resp = client.list_nodes_with_options(request, headers, util_models.RuntimeOptions())
    except Exception as e:
        print(f"请求 ListNodes 出错: {e}")
        return []

    if not hasattr(resp.body, "nodes") or not resp.body.nodes:
        return []

    results = []
    for node in resp.body.nodes:
        node_dict = {
            "name": node.name,
            "node_id": node.node_id,
            "type": node.type,
            "url": getattr(node, "url", None)
        }

        if getattr(node, "has_children", False):
            # 递归获取子节点，放入children
            node_dict["children"] = list_all_nodes(client, operator_id, node.node_id, token)
        else:
            node_dict["children"] = []

        results.append(node_dict)

    return results


# ------------------- 主逻辑 -------------------
if __name__ == "__main__":
    token = get_access_token()
    print("✅ AccessToken:", token)

    dept_ids = [1] + get_department_list(token)
    print("✅ 部门总数:", len(dept_ids))

    all_users = set()
    for dept_id in dept_ids:
        users = get_department_users(token, dept_id)
        all_users.update(users)
    print("✅ 成员总数:", len(all_users))

    client = create_wiki_client()

    for userid in all_users:
        try:
            operator_id = get_unionid(token, userid)
            if not operator_id:
                print(f"⚠️ 用户 {userid} 未获取到 unionId，跳过。")
                continue

            root_node_id = get_user_root_node_id(client, token, operator_id)
            if not root_node_id:
                print(f"⚠️ 用户 {userid} ({operator_id}) 未获取到 rootNodeId，跳过。")
                continue

            wiki_files = list_all_nodes(client, operator_id, root_node_id, token)

            print(f"\n📂 用户 {userid} ({operator_id}) ({root_node_id})- 共 {len(wiki_files)} 个文件/文件夹：")
            for f in wiki_files:
                print(f"   - [{f['type']}] {f['name']} ({f['url']})")

        except Exception as e:
            print(f"❌ 处理用户 {userid} 出错: {e}")
