from flask import Flask, request, jsonify
from dingding_attendance import DingTalkDocsFetcher  # 你保存代码的文件名
from dingding_calendars import DingTalkHelper
import concurrent.futures
from dingding_wiki_team_file import get_access_token,get_unionid,create_wiki_client,list_workspaces,list_all_nodes,get_admin_userid,get_workspaces_details
from dingding_wiki_file import get_user_root_node_id,get_department_list,get_department_users
from DingConfig import APP_KEY, APP_SECRET
from flask import Blueprint
app_dingding = Blueprint("dingding", __name__)
def obj_to_dict(obj):
    if isinstance(obj, list):
        return [obj_to_dict(i) for i in obj]
    if isinstance(obj, dict):
        return {k: obj_to_dict(v) for k,v in obj.items()}
    if hasattr(obj, 'to_map'):
        return obj.to_map()
    if hasattr(obj, '__dict__'):
        return {k: obj_to_dict(v) for k, v in obj.__dict__.items() if not k.startswith('_')}
    return obj
def to_dict(ws):
    return {
        "name": getattr(ws, "name", ""),
        "workspace_id": getattr(ws, "workspace_id", ""),
        "type": getattr(ws, "type", ""),
        "url": getattr(ws, "url", ""),
    }

#获取钉钉打卡信息
@app_dingding.route('/dingding_attendance', methods=['POST'])
def attendance():
    data = request.json
    app_key = APP_KEY
    app_secret = APP_SECRET
    date_from = data.get('date_from')
    date_to = data.get('date_to')

    if not all([date_from, date_to]):
        return jsonify({"error": "date_from, date_to 均为必填参数"}), 400

    token = DingTalkDocsFetcher.get_access_token(app_key, app_secret)
    if not token:
        return jsonify({"error": "获取AccessToken失败"}), 500

    departments = DingTalkDocsFetcher.get_all_departments(token)
    if not departments:
        return jsonify({"error": "获取部门失败"}), 500

    user_ids = list(DingTalkDocsFetcher.get_all_user_ids(token, departments))
    if not user_ids:
        return jsonify({"error": "没有获取到用户ID"}), 500

    records = DingTalkDocsFetcher.get_attendance_records(token, user_ids, date_from, date_to)
    if records is None:
        return jsonify({"error": "获取打卡记录失败"}), 500

    user_cache = {}

    def fetch_user_detail(uid):
        if uid in user_cache:
            return uid, user_cache[uid]
        detail = DingTalkDocsFetcher.get_user_detail(token, uid)
        user_cache[uid] = detail
        return uid, detail

    user_ids_in_records = list({r.get("userId") for r in records if r.get("userId")})

    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        futures = [executor.submit(fetch_user_detail, uid) for uid in user_ids_in_records]
        for future in concurrent.futures.as_completed(futures):
            uid, detail = future.result()
            user_cache[uid] = detail

    for r in records:
        detail = user_cache.get(r.get("userId"))
        r["user_name"] = detail.get("name", "") if detail else ""
        r["user_unionid"] = detail.get("unionid", "") if detail else ""

    return jsonify({
        "departments_count": len(departments),
        "users_count": len(user_ids),
        "attendance_records_count": len(records),
        "attendance_records": records
    })

#获取钉钉日历日程信息
@app_dingding.route('/dingding_calendar', methods=['GET'])
def user_calendar():
    app_key = APP_KEY
    app_secret = APP_SECRET
   

    token = DingTalkHelper.get_access_token(app_key, app_secret)
    if not token:
        return jsonify({"error": "获取AccessToken失败"}), 500

    departments = DingTalkHelper.get_all_departments(token)
    if not departments:
        return jsonify({"error": "获取部门失败"}), 500

    all_userids = set()
    for dept in departments:
        userids = DingTalkHelper.get_users_by_dept(token, dept["dept_id"])
        all_userids.update(userids)
    if not all_userids:
        return jsonify({"error": "没有获取到用户ID"}), 500

    calendar_client = DingTalkHelper.create_calendar_client()

    user_cache = {}

    def fetch_user_events(userid):
        user_detail = DingTalkHelper.get_user_detail(token, userid)
        if not user_detail:
            return None
        unionid = user_detail.get("unionid")
        name = user_detail.get("name")
        events = []
        if unionid:
            events = DingTalkHelper.get_user_calendar_events(calendar_client, token, unionid)
        return {
            "userid": userid,
            "name": name,
            "unionid": unionid,
            "events": events
        }

    results = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        futures = [executor.submit(fetch_user_events, uid) for uid in all_userids]
        for future in concurrent.futures.as_completed(futures):
            res = future.result()
            if res:
                results.append(res)

    # 转换 events
    for user_data in results:
        user_data['events'] = obj_to_dict(user_data.get('events', []))

    return jsonify({
        "departments_count": len(departments),
        "users_count": len(all_userids),
        "users": results
    })


@app_dingding.route('/wiki_workspaces', methods=['POST'])
def wiki_workspaces():
    data = request.json or {}
    app_key = APP_KEY
    app_secret = APP_SECRET


    try:
        token = get_access_token(app_key, app_secret)

        userid = get_admin_userid(token)
        operator_id = get_unionid(token, userid)
        client = create_wiki_client()

        workspaces_ids = list_workspaces(client, token, operator_id)
        workspaces = get_workspaces_details(client, token, operator_id, workspaces_ids)

        for ws in workspaces:
            ws["nodes"] = list_all_nodes(client, operator_id, ws["root_node_id"], token)

        workspaces_serializable = workspaces  # 已经是字典列表

        return jsonify({
            "workspaces_count": len(workspaces_serializable),
            "workspaces": workspaces_serializable
        })
    except Exception as e:
        return jsonify({"error": str(e)}), 500


@app_dingding.route("/get_all_users_wiki", methods=["GET"])
def get_all_users_wiki():
    app_key = APP_KEY
    app_secret = APP_SECRET
    
   
    try:
        token = get_access_token(app_key, app_secret)

        dept_ids = [1] + get_department_list(token)
        all_users = set()
        for dept_id in dept_ids:
            all_users.update(get_department_users(token, dept_id))

        client = create_wiki_client()
        result = []

        for userid in all_users:
            operator_id = get_unionid(token, userid)
            if not operator_id:
                continue

            root_node_id = get_user_root_node_id(client, token, operator_id)
            if not root_node_id:
                continue

            nodes = list_all_nodes(client, operator_id, root_node_id, token)
            result.append({
                "userid": userid,
                "operator_id": operator_id,
                "root_node_id": root_node_id,
                "nodes": nodes
            })

        return jsonify({"users": result, "total_users": len(result)})
    except Exception as e:
        return jsonify({"error": str(e)}), 500


