from __future__ import annotations

import json
import base64
import hashlib
import hmac
import time
import urllib.error
import urllib.request
from typing import Any

TENANT_TOKEN_URL = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
MESSAGE_URL = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id"


def _button(text: str, url: str) -> dict[str, Any]:
    return {
        "tag": "button",
        "text": {"tag": "plain_text", "content": text},
        "type": "primary",
        "url": url,
    }


def create_reminder_payload(submit_url: str, title: str = "每日工作汇报提醒") -> dict[str, Any]:
    return {
        "msg_type": "interactive",
        "card": {
            "header": {
                "title": {"tag": "plain_text", "content": title},
                "template": "blue",
            },
            "elements": [
                {"tag": "div", "text": {"tag": "lark_md", "content": "请提交今日日报。"}},
                {"tag": "action", "actions": [_button("填写日报", submit_url)]},
            ],
        },
    }


def create_summary_payload(manager_url: str, summary: dict[str, Any]) -> dict[str, Any]:
    missing_names = "、".join(employee["name"] for employee in summary["missing"]) or "无"
    return {
        "msg_type": "interactive",
        "card": {
            "header": {
                "title": {"tag": "plain_text", "content": f"{summary['date']} 日报提交汇总"},
                "template": "orange" if summary["missingCount"] > 0 else "green",
            },
            "elements": [
                {
                    "tag": "div",
                    "text": {
                        "tag": "lark_md",
                        "content": f"已提交：{summary['submittedCount']}/{summary['expectedCount']}\n未提交：{missing_names}",
                    },
                },
                {"tag": "action", "actions": [_button("查看全部日报", manager_url)]},
            ],
        },
    }


def create_bot_message_body(payload: dict[str, Any]) -> dict[str, str]:
    return {
        "receive_id": "",
        "msg_type": "interactive",
        "content": json.dumps(payload["card"], ensure_ascii=False),
    }


def get_tenant_access_token(app_id: str, app_secret: str) -> str:
    if not app_id or not app_secret:
        raise ValueError("FEISHU_APP_ID and FEISHU_APP_SECRET are required")

    request = urllib.request.Request(
        TENANT_TOKEN_URL,
        data=json.dumps({"app_id": app_id, "app_secret": app_secret}).encode("utf-8"),
        headers={"content-type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(request, timeout=10) as response:
        result = json.loads(response.read().decode("utf-8"))

    token = result.get("tenant_access_token")
    if not token:
        raise RuntimeError(f"Feishu tenant token response missing token: {result}")
    return str(token)


def send_bot_interactive_message(tenant_access_token: str, receive_id: str, payload: dict[str, Any]) -> dict[str, Any]:
    if not receive_id:
        raise ValueError("receive_id is required")

    body = create_bot_message_body(payload)
    body["receive_id"] = receive_id
    request = urllib.request.Request(
        MESSAGE_URL,
        data=json.dumps(body, ensure_ascii=False).encode("utf-8"),
        headers={
            "authorization": f"Bearer {tenant_access_token}",
            "content-type": "application/json",
        },
        method="POST",
    )
    with urllib.request.urlopen(request, timeout=10) as response:
        result = json.loads(response.read().decode("utf-8"))
    return result


def create_webhook_sign(timestamp: str, secret: str) -> str:
    string_to_sign = f"{timestamp}\n{secret}".encode("utf-8")
    sign = hmac.new(string_to_sign, digestmod=hashlib.sha256).digest()
    return base64.b64encode(sign).decode("utf-8")


def send_webhook(webhook_url: str, payload: dict[str, Any], secret: str = "") -> dict[str, Any]:
    if not webhook_url:
        raise ValueError("FEISHU_WEBHOOK_URL is required")

    request_payload = dict(payload)
    if secret:
        timestamp = str(int(time.time()))
        request_payload["timestamp"] = timestamp
        request_payload["sign"] = create_webhook_sign(timestamp, secret)

    request = urllib.request.Request(
        webhook_url,
        data=json.dumps(request_payload).encode("utf-8"),
        headers={"content-type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(request, timeout=10) as response:
            body = response.read().decode("utf-8")
            return json.loads(body) if body else {"ok": True}
    except urllib.error.HTTPError as error:
        raise RuntimeError(f"Feishu webhook failed with status {error.code}") from error
