import json
import csv
import pytz
import os
from datetime import datetime
import lark_oapi as lark
from lark_oapi.api.attendance.v1 import *
from lark_oapi.api.contact.v3 import *
from flask import Flask, request, jsonify, send_from_directory

# Flask app 配置
app = Flask(__name__)


def str_to_timestamp_seconds(dt_str):
    """将时间字符串转为秒级时间戳"""
    try:
        dt = datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S")
        return int(dt.timestamp())
    except Exception as e:
        raise ValueError(f"时间格式错误，应为 'YYYY-MM-DD HH:MM:SS', 但收到: {dt_str}")


def convert_timestamp_to_datetime(timestamp, timezone="Asia/Shanghai"):
    """将时间戳转换为本地日期时间格式"""
    # 将时间戳转换为 UTC 时间
    utc_time = datetime.utcfromtimestamp(int(timestamp)).replace(tzinfo=pytz.utc)

    # 转换为指定的本地时区时间（默认为上海时间）
    local_timezone = pytz.timezone(timezone)
    local_time = utc_time.astimezone(local_timezone)

    # 格式化为 'YYYY-MM-DD HH:MM:SS'
    return local_time.strftime('%Y-%m-%d %H:%M:%S')


def get_user_ids_and_names(client, department_id):
    """获取部门内所有用户的 user_id 和 name"""
    request: FindByDepartmentUserRequest = FindByDepartmentUserRequest.builder() \
        .user_id_type("open_id") \
        .department_id_type("open_department_id") \
        .department_id(department_id) \
        .page_size(10) \
        .build()

    # 发起请求
    response: FindByDepartmentUserResponse = client.contact.v3.user.find_by_department(request)

    if not response.success():
        lark.logger.error(f"获取部门用户失败，错误信息: {response.msg}")
        return [], {}

    user_ids = []
    user_names = {}

    # 提取所有用户的 user_id 和 name
    for item in response.data.items:
        user_ids.append(item.user_id)
        user_names[item.user_id] = item.name

    return user_ids, user_names


def get_attendance_data(client, user_ids, start_time, end_time, user_names):
    """获取多个用户的打卡记录"""
    all_records = []

    # 构造请求对象
    request: QueryUserFlowRequest = QueryUserFlowRequest.builder() \
        .employee_type("employee_id") \
        .include_terminated_user(True) \
        .request_body(QueryUserFlowRequestBody.builder()
                      .user_ids(user_ids)  # 传入所有的 user_id
                      .check_time_from(start_time)
                      .check_time_to(end_time)
                      .build()) \
        .build()

    # 发起请求
    response: QueryUserFlowResponse = client.attendance.v1.user_flow.query(request)

    if not response.success():
        lark.logger.error(f"获取用户打卡记录失败，错误信息: {response.msg}")
        return []

    # 访问 user_flow_results 属性，而不是使用 .get() 方法
    records = response.data.user_flow_results  # 直接访问属性

    if not records:
        return all_records

    # 将当前页的记录添加到所有记录中
    for record in records:
        try:
            # 获取打卡时间、地点、照片链接
            check_in_time = convert_timestamp_to_datetime(record.check_time)
            location_name = record.location_name if hasattr(record, 'location_name') else '无位置'
            photo_urls = record.photo_urls if hasattr(record, 'photo_urls') else []
            photo_urls_str = ", ".join(photo_urls)  # 将多个照片链接拼接为字符串
            comment = record.comment if hasattr(record, 'comment') else ''
            # 获取用户名（通过之前获取的 user_names 字典）
            user_name = user_names.get(record.user_id, "未知用户")

            # 将打卡记录添加到统计数据中
            all_records.append([record.user_id, user_name, check_in_time, location_name, photo_urls_str, comment])
        except Exception as e:
            lark.logger.error(f"处理打卡记录时出错: {e}")

    return all_records


def save_to_csv(data):
    """Save attendance records to a CSV file and return structured data"""
    os.makedirs("output", exist_ok=True)
    file_path = os.path.join("output", "attendance_report.csv")

    header = ["user_id", "name", "check_in_time", "location_name", "photo_urls", "comment"]

    # Debug: print data to be saved
    print(f"Preparing to save the following data to {file_path}:")
    for row in data:
        print(row)

    # Write data to CSV (overwrite if file exists)
    with open(file_path, "w", newline="", encoding="utf-8-sig") as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(header)
        for row in data:
            writer.writerow(row)

    # Return structured list of dicts
    structured_data = [
        {header[i]: row[i] for i in range(len(header))}
        for row in data
    ]

    return structured_data, file_path
def get_all_department_ids(client):
    """分页获取所有 open_department_id"""
    all_department_ids = []
    page_token = None

    while True:
        req_builder = ChildrenDepartmentRequest.builder() \
            .department_id("0") \
            .user_id_type("open_id") \
            .department_id_type("department_id") \
            .fetch_child(True) \
            .page_size(50)
        if page_token:
            req_builder.page_token(page_token)

        request = req_builder.build()
        response: ChildrenDepartmentResponse = client.contact.v3.department.children(request)

        if not response.success():
            print(f"获取部门失败: {response.msg}")
            break

        for item in response.data.items:
            all_department_ids.append(item.open_department_id)

        if not response.data.has_more:
            break
        page_token = response.data.page_token

    return all_department_ids

@app.route('/attendance', methods=['POST'])
def attendance():
    data = request.get_json()
    app_id = data.get("app_id")
    app_secret = data.get("app_secret")
    start_time_str = data.get("start_time")
    end_time_str = data.get("end_time")

    if not all([app_id, app_secret, start_time_str, end_time_str]):
        return jsonify({"error": "缺少必要的参数: app_id, app_secret, start_time, end_time"}), 400

    start_time = str_to_timestamp_seconds(start_time_str)
    end_time = str_to_timestamp_seconds(end_time_str)

    client = lark.Client.builder() \
        .app_id(app_id) \
        .app_secret(app_secret) \
        .log_level(lark.LogLevel.ERROR) \
        .build()

    # 获取所有部门 ID
    department_ids = get_all_department_ids(client)
    print(f"共获取到 {len(department_ids)} 个部门")

    all_check_in_records = []

    for dep_id in department_ids:
        user_ids, user_names = get_user_ids_and_names(client, dep_id)
        p
        dep_records = get_attendance_data(client, user_ids, start_time, end_time, user_names)
        all_check_in_records.extend(dep_records)

    structured_data, file_path = save_to_csv(all_check_in_records)
    return jsonify({
        "message": "打卡统计已保存",
        "file_path": file_path,
        "data": structured_data
    }), 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8789)
