import requests
import hashlib
import json
from bs4 import BeautifulSoup
from datetime import datetime
import time


def send_to_feishu(webhook_url, content, keyword="bug"):
    """
    发送消息到飞书机器人

    Args:
        webhook_url: 飞书机器人的webhook地址
        content: 要发送的消息内容
        keyword: 关键词，需要包含在消息中
    """
    try:
        # 构建消息体
        message = {
            "msg_type": "text",
            "content": {
                "text": f"{keyword}\n{content}"
            }
        }

        # 发送请求
        headers = {'Content-Type': 'application/json'}
        response = requests.post(webhook_url,
                                 data=json.dumps(message),
                                 headers=headers,
                                 timeout=10)

        if response.status_code == 200:
            print(f"✅ 消息发送成功到飞书")
            return True
        else:
            print(f"❌ 飞书消息发送失败: {response.status_code}")
            print(f"响应: {response.text}")
            return False

    except Exception as e:
        print(f"❌ 发送飞书消息异常: {e}")
        return False


def get_all_bugs_and_send():
    """获取所有产品的Bug并发送到飞书"""
    base_url = "http://39.170.26.156:8888"
    username = "qiaoxinjiu"
    password = "Qiao123456"

    # 飞书配置
    feishu_webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/c7288ada-1c0c-472a-b652-a475a9586302"
    keyword = "bug"

    print("获取禅道Bug列表")
    print("=" * 50)

    # 登录
    session = requests.Session()
    password_md5 = hashlib.md5(password.encode()).hexdigest()

    login_resp = session.post(f"{base_url}/api.php/v1/tokens",
                              json={"account": username, "password": password_md5},
                              headers={'Content-Type': 'application/json'})

    if login_resp.status_code not in [200, 201]:
        error_msg = f"❌ 禅道登录失败: {login_resp.status_code}"
        print(error_msg)
        send_to_feishu(feishu_webhook, error_msg, keyword)
        return

    token = login_resp.json().get('token')
    session.headers.update({'Token': token})

    print("✅ 登录成功")

    # 获取所有产品
    products_resp = session.get(f"{base_url}/api.php/v1/products")
    if products_resp.status_code != 200:
        error_msg = f"❌ 获取产品列表失败: {products_resp.status_code}"
        print(error_msg)
        send_to_feishu(feishu_webhook, error_msg, keyword)
        return

    products = products_resp.json().get('products', [])
    print(f"📦 共 {len(products)} 个产品")

    all_bugs = []

    # 遍历每个产品获取Bug（只获取产品ID为2的）
    for product in products:
        product_id = product.get('id')
        product_name = product.get('name')

        # 只获取产品ID为2的
        if product_id != 2:
            continue

        print(f"\n获取产品 '{product_name}' 的Bug...")

        # 获取HTML页面
        bugs_url = f"{base_url}/bug-browse-{product_id}.html"
        bugs_resp = session.get(bugs_url, params={'product': product_id, 'limit': 100})

        if bugs_resp.status_code == 200:
            try:
                html = bugs_resp.text
                soup = BeautifulSoup(html, "html.parser")

                # 找 bug 列表的 table
                table = (
                        soup.find("table", id="bugList")
                        or soup.find("table", class_="table")
                        or soup.find("table")
                )
                if not table:
                    print("  ❌ 未找到 bug 列表 table")
                    continue

                # 解析表头
                header_tr = table.find("tr")
                if not header_tr:
                    print("  ❌ 未找到表头行")
                    continue

                header_map = {}
                for idx, th in enumerate(header_tr.find_all(["th", "td"])):
                    text = th.get_text(strip=True)
                    if not text:
                        continue
                    if "ID" == text or text == "编号":
                        header_map["id"] = idx
                    elif "标题" in text:
                        header_map["title"] = idx
                    elif "状态" in text:
                        header_map["status"] = idx
                    elif "严重" in text:
                        header_map["severity"] = idx
                    elif "优先" in text or "优先级" in text:
                        header_map["pri"] = idx
                    elif "指派" in text:
                        header_map["assignedTo"] = idx
                    elif "创建" in text or "打开" in text:
                        header_map["openedDate"] = idx

                bugs = []

                # 遍历表体行
                for tr in table.find_all("tr")[1:]:
                    tds = tr.find_all("td")
                    if not tds:
                        continue

                    # id
                    bug_id = tr.get("data-id")
                    if not bug_id and "id" in header_map and header_map["id"] < len(tds):
                        bug_id = tds[header_map["id"]].get_text(strip=True)
                    if not bug_id:
                        continue

                    # 标题
                    title = ""
                    if "title" in header_map and header_map["title"] < len(tds):
                        cell = tds[header_map["title"]]
                        link = cell.find("a")
                        title = (link or cell).get_text(strip=True)

                    # 状态
                    status = ""
                    if "status" in header_map and header_map["status"] < len(tds):
                        status = tds[header_map["status"]].get_text(strip=True)

                    # 严重程度
                    severity = ""
                    if "severity" in header_map and header_map["severity"] < len(tds):
                        sev_cell = tds[header_map["severity"]]
                        severity = sev_cell.get_text(strip=True)
                        if not severity:
                            sev_span = sev_cell.find("span")
                            if sev_span and sev_span.get("title"):
                                severity = sev_span.get("title").strip()

                    # 优先级
                    pri = ""
                    if "pri" in header_map and header_map["pri"] < len(tds):
                        pri = tds[header_map["pri"]].get_text(strip=True)

                    # 指派给
                    assigned_to = ""
                    if "assignedTo" in header_map and header_map["assignedTo"] < len(tds):
                        assigned_to = tds[header_map["assignedTo"]].get_text(strip=True)

                    # 创建/打开日期
                    opened_date = ""
                    if "openedDate" in header_map and header_map["openedDate"] < len(tds):
                        opened_date = tds[header_map["openedDate"]].get_text(strip=True)

                    bug = {
                        "id": bug_id,
                        "title": title,
                        "statusName": status,
                        "severity": severity,
                        "pri": pri,
                        "assignedToName": assigned_to,
                        "openedDate": opened_date,
                        "product_name": product_name,
                    }
                    bugs.append(bug)

                print(f"  ✅ 解析出 {len(bugs)} 个Bug")
                all_bugs.extend(bugs)

            except Exception as e:
                print(f"  ❌ 解析失败: {e}")
        else:
            print(f"  ❌ 获取失败: {bugs_resp.status_code}")

    # 处理并发送统计信息
    if all_bugs:
        # 计算统计数据
        today_str = datetime.today().strftime("%Y-%m-%d")
        today_md_str = datetime.today().strftime("%m-%d")

        total_bugs = len(all_bugs)

        # 今日新增Bug
        today_bugs = [
            b for b in all_bugs
            if (
                    today_str in str(b.get("openedDate", "")).strip()
                    or today_md_str in str(b.get("openedDate", "")).strip()
            )
        ]

        # 未关闭Bug（状态不包含"已关闭"、"已解决"等）
        open_bugs = [
            b for b in all_bugs
            if not any(kw in str(b.get("statusName", "")).lower() for kw in ["closed", "resolved", "done", "cancel"])
               and not any(kw in str(b.get("statusName", "")) for kw in ["已关闭", "已解决", "已完成", "已取消"])
        ]

        # 按指派人员统计
        assigned_stats = {}
        for bug in all_bugs:
            assigned = bug.get("assignedToName", "未指派")
            assigned_stats[assigned] = assigned_stats.get(assigned, 0) + 1

        # 按状态统计
        status_stats = {}
        for bug in all_bugs:
            status = bug.get("statusName", "未知")
            status_stats[status] = status_stats.get(status, 0) + 1

        # 构建飞书消息
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        message = f"🐛 禅道Bug统计报告\n"
        message += f"⏰ 时间: {current_time}\n"
        message += f"📊 产品: 智慧运营平台V1.0\n"
        message += f"================================\n"
        message += f"📈 Bug统计概览:\n"
        message += f"  • 总Bug数: {total_bugs}\n"
        message += f"  • 今日新增: {len(today_bugs)}\n"
        message += f"  • 未关闭Bug: {len(open_bugs)}\n"
        message += f"\n📋 状态分布:\n"

        # 添加状态统计
        for status, count in sorted(status_stats.items()):
            message += f"  • {status}: {count}个\n"

        message += f"\n👥 指派人员统计:\n"
        # 添加指派统计（前5名）
        sorted_assigned = sorted(assigned_stats.items(), key=lambda x: x[1], reverse=True)[:5]
        for person, count in sorted_assigned:
            message += f"  • {person}: {count}个\n"

        # 今日新增Bug详情
        if today_bugs:
            message += f"\n🆕 今日新增Bug详情 ({len(today_bugs)}个):\n"
            today_bugs.sort(key=lambda x: int(x.get('id', 0)), reverse=True)
            for bug in today_bugs[:10]:  # 只显示前10个
                bug_url = f"http://39.170.26.156:8888/bug-view-{bug.get('id')}.html"
                message += f"  [#{bug.get('id')}] {bug.get('title', '')[:30]}...\n"
                message += f"     状态: {bug.get('statusName', '未知')} | 严重: {bug.get('severity', '未知')} | 指派: {bug.get('assignedToName', '未指派')}\n"

        # 未关闭Bug详情（前5个）
        if open_bugs:
            open_bugs.sort(key=lambda x: int(x.get('id', 0)), reverse=True)
            message += f"\n⚠️  最新未关闭Bug (前5个):\n"
            for bug in open_bugs[:5]:
                bug_url = f"http://39.170.26.156:8888/bug-view-{bug.get('id')}.html"
                message += f"  [#{bug.get('id')}] {bug.get('title', '')[:30]}...\n"
                message += f"     状态: {bug.get('statusName', '未知')} | 严重: {bug.get('severity', '未知')} | 指派: {bug.get('assignedToName', '未指派')}\n"

        message += f"\n🔗 禅道地址: {base_url}"

        # 打印到控制台
        print(f"\n{'=' * 80}")
        print(message)
        print(f"{'=' * 80}")

        # 发送到飞书
        print("\n发送消息到飞书...")
        success = send_to_feishu(feishu_webhook, message, keyword)

        if success:
            print(f"✅ Bug统计报告已发送到飞书")
        else:
            print(f"❌ 飞书消息发送失败")
    else:
        message = f"📭 禅道Bug统计报告\n"
        message += f"⏰ 时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
        message += f"📊 产品: 智慧运营平台V1.0\n"
        message += f"================================\n"
        message += f"✅ 当前没有Bug数据\n"
        message += f"🔗 禅道地址: {base_url}"

        print(message)
        send_to_feishu(feishu_webhook, message, keyword)


def send_simple_report():
    """发送简化的Bug统计报告到飞书"""
    base_url = "http://39.170.26.156:8888"
    username = "qiaoxinjiu"
    password = "Qiao123456"

    # 飞书配置
    feishu_webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/c7288ada-1c0c-472a-b652-a475a9586302"
    keyword = "bug"

    print("获取禅道Bug统计")
    print("=" * 50)

    try:
        # 登录
        session = requests.Session()
        password_md5 = hashlib.md5(password.encode()).hexdigest()

        login_resp = session.post(f"{base_url}/api.php/v1/tokens",
                                  json={"account": username, "password": password_md5},
                                  headers={'Content-Type': 'application/json'})

        if login_resp.status_code not in [200, 201]:
            error_msg = f"❌ 禅道登录失败"
            print(error_msg)
            send_to_feishu(feishu_webhook, error_msg, keyword)
            return

        token = login_resp.json().get('token')
        session.headers.update({'Token': token})
        print("✅ 登录成功")

        # 获取产品ID=2的Bug页面
        bug_url = f"{base_url}/bug-browse-2.html"
        response = session.get(bug_url)

        if response.status_code != 200:
            error_msg = f"❌ 无法获取Bug页面"
            print(error_msg)
            send_to_feishu(feishu_webhook, error_msg, keyword)
            return

        # 简单统计Bug数量
        import re
        bug_matches = re.findall(r'bug-view-(\d+)\.html', response.text)
        total_bugs = len(set(bug_matches))  # 去重

        # 构建简单消息
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        message = f"🐛 禅道Bug速报\n"
        message += f"⏰ 时间: {current_time}\n"
        message += f"📊 产品: 智慧运营平台V1.0\n"
        message += f"================================\n"
        message += f"📈 当前总Bug数: {total_bugs}\n"
        message += f"🔗 查看详情: {bug_url}\n"
        message += f"\n💡 提示: 详细统计请查看禅道系统"

        print(f"发现 {total_bugs} 个Bug")

        # 发送到飞书
        success = send_to_feishu(feishu_webhook, message, keyword)

        if success:
            print(f"✅ 简版Bug报告已发送到飞书")
        else:
            print(f"❌ 飞书消息发送失败")

    except Exception as e:
        error_msg = f"❌ 获取Bug统计异常: {str(e)}"
        print(error_msg)
        send_to_feishu(feishu_webhook, error_msg, keyword)


if __name__ == "__main__":
    # 运行完整版本（带详细统计）
    get_all_bugs_and_send()

    # 或者运行简化版本（只发速报）
    # send_simple_report()