import argparse
import json
import sys
import uuid

from lark_common import (
    LarkApiError,
    api_request,
    configure_output_encoding,
    get_tenant_access_token,
    load_dotenv,
    require_env,
)


TITLE_BY_METHOD = {
    "deploy": "部署完成",
    "package": "打包完成",
    "hotfix": "热更完成",
    "subpack": "分包完成",
    "subpackage": "分包完成",
}

DEFAULT_TEXT_BY_METHOD = {
    "deploy": "资源部署完成！",
    "package": "{platform}打包完成，请检查是否需要部署文件!",
    "hotfix": "{platform}热更打完了，别忘了部署！",
    "subpack": "{platform}分包打完了，别忘了部署！",
    "subpackage": "{platform}分包打完了，别忘了部署！",
}

CARD_TEMPLATE_BY_METHOD = {
    "deploy": "green",
    "package": "blue",
    "hotfix": "orange",
    "subpack": "orange",
    "subpackage": "orange",
}


def parse_args():
    parser = argparse.ArgumentParser(description="Send a Lark build notification.")
    parser.add_argument(
        "--method",
        required=True,
        choices=sorted(TITLE_BY_METHOD),
        help="Build method, for example: deploy, package, hotfix.",
    )
    parser.add_argument(
        "--branch",
        default="",
        help="Branch name. Required for deploy.",
    )
    parser.add_argument(
        "--platform",
        choices=["Android", "iOS"],
        help="Build platform. Required for package and hotfix.",
    )
    parser.add_argument(
        "--text",
        default="",
        help="Optional message body override. Defaults to a method-specific text.",
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Print the request body without sending it.",
    )
    parser.add_argument(
        "--plain",
        action="store_true",
        help="Send a plain text message instead of an interactive card.",
    )
    return parser.parse_args()


def validate_args(args):
    if args.method == "deploy" and not args.branch:
        raise RuntimeError("--branch is required when --method is deploy")
    if args.method in ("package", "hotfix", "subpack", "subpackage") and not args.platform:
        raise RuntimeError(f"--platform is required when --method is {args.method}")


def build_message_body(args):
    if args.text:
        return args.text
    template = DEFAULT_TEXT_BY_METHOD[args.method]
    return template.format(platform=args.platform or "")


def build_message_text(args):
    title = TITLE_BY_METHOD[args.method]
    body = build_message_body(args)
    if args.branch:
        return f"{title}\n[{args.branch}] {body}"
    return f"{title}\n{body}"


def build_plain_request_body(chat_id, message):
    return {
        "receive_id": chat_id,
        "msg_type": "text",
        "content": json.dumps({"text": message}, ensure_ascii=False),
        "uuid": str(uuid.uuid4()),
    }


def build_card_content(args):
    title = TITLE_BY_METHOD[args.method]
    body = build_message_body(args)
    content = f"[{args.branch}] {body}" if args.branch else body

    return {
        "config": {"wide_screen_mode": True},
        "header": {
            "template": CARD_TEMPLATE_BY_METHOD[args.method],
            "title": {"tag": "plain_text", "content": title},
        },
        "elements": [
            {
                "tag": "div",
                "text": {"tag": "lark_md", "content": content},
            }
        ],
    }


def build_card_request_body(chat_id, args):
    return {
        "receive_id": chat_id,
        "msg_type": "interactive",
        "content": json.dumps(build_card_content(args), ensure_ascii=False),
        "uuid": str(uuid.uuid4()),
    }


def send_message(body):
    token = get_tenant_access_token()
    return api_request(
        "POST",
        "/im/v1/messages",
        token=token,
        query={"receive_id_type": "chat_id"},
        body=body,
    )


def main():
    configure_output_encoding()
    load_dotenv()
    args = parse_args()
    validate_args(args)
    chat_id = require_env("LARK_CHAT_ID")
    if args.plain:
        message = build_message_text(args)
        body = build_plain_request_body(chat_id, message)
    else:
        body = build_card_request_body(chat_id, args)

    if args.dry_run:
        print(json.dumps(body, ensure_ascii=False, indent=2))
        return

    payload = send_message(body)
    data = payload.get("data", {})
    message_id = data.get("message_id", "")
    if message_id:
        print(f"Message sent: {message_id}")
    else:
        print("Message sent.")


if __name__ == "__main__":
    try:
        main()
    except (RuntimeError, LarkApiError) as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        if isinstance(exc, LarkApiError) and exc.log_id:
            print(f"X-Tt-Logid: {exc.log_id}", file=sys.stderr)
        sys.exit(1)
