#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Text template card message bot implementation.

This module provides the :class:`TextCardBot` class for sending text-style
template cards to Wecom Group Bots. Template cards provide rich, structured
layouts with titles, emphasized content, horizontal key-value pairs, and
action buttons.

Card Components:
    - ``main_title`` (dict): Main title with optional description
    - ``emphasis_content`` (dict): Emphasized content (large text)
    - ``sub_title_text`` (str): Subtitle text
    - ``horizontal_content_list`` (list): Key-value pairs displayed horizontally
    - ``jump_list`` (list): Quick action buttons
    - ``card_action`` (dict): Card click action configuration

Requirements:
    Either ``main_title.title`` or ``sub_title_text`` must be provided.

Example:
    Deployment notification card::

        from pywgb.bot import TextCardBot
        
        bot = TextCardBot("your-webhook-key")
        
        bot.send(
            main_title={
                "title": "Deployment Notification",
                "desc": "Production Environment"
            },
            emphasis_content={
                "title": "SUCCESS",
                "desc": "Status"
            },
            sub_title_text="Deployed by: DevOps Team",
            horizontal_content_list=[
                {"keyname": "Version", "value": "v2.1.0"},
                {"keyname": "Time", "value": "2026-01-19 10:00"},
                {"keyname": "Duration", "value": "5 minutes"}
            ],
            card_action={
                "type": 1,
                "url": "https://example.com/deployment/details"
            }
        )

:author: Rex Zhou <879582094@qq.com>
:copyright: Copyright © 2025 Rex Zhou. All rights reserved.
"""
from functools import partial
from logging import getLogger
from typing import List

from jmespath import search

from . import TemplateCardKeys, TemplateCardRequirements
from .._abstract import ConvertedData, AbstractBot

logger = getLogger(__name__)


class TextCardBot(AbstractBot):
    """
    Text template card message bot for Wecom Group.

    Sends structured template cards with text-focused layouts. Supports
    titles, emphasized content, key-value pairs, and action buttons.

    Args:
        key (str): Webhook key or full webhook URL.

    Raises:
        ValueError: If neither ``main_title.title`` nor ``sub_title_text``
            is provided, or if other validation rules fail.

    Example:
        System alert card::

            from pywgb.bot import TextCardBot

            bot = TextCardBot("your-key")
            
            bot.send(
                main_title={"title": "System Alert", "desc": "Production"},
                emphasis_content={"title": "85%", "desc": "CPU Usage"},
                horizontal_content_list=[
                    {"keyname": "Server", "value": "web-01"},
                    {"keyname": "Time", "value": "2026-01-19 09:30"}
                ],
                card_action={"type": 1, "url": "https://monitor.example.com"}
            )

        Minimal card::

            bot.send(
                sub_title_text="Quick notification message",
                card_action={"type": 1, "url": "https://example.com"}
            )

        Complete card with all features::

            bot.send(
                main_title={
                    "title": "Monthly Report",
                    "desc": "January 2026"
                },
                emphasis_content={
                    "title": "98.5%",
                    "desc": "Success Rate"
                },
                sub_title_text="Generated by Analytics Team",
                horizontal_content_list=[
                    {"keyname": "Total Requests", "value": "1,234,567"},
                    {"keyname": "Avg Response", "value": "45ms"},
                    {"keyname": "Errors", "value": "18"}
                ],
                jump_list=[
                    {"type": 1, "title": "View Details", "url": "https://..."},
                    {"type": 1, "title": "Download PDF", "url": "https://..."}
                ],
                card_action={"type": 1, "url": "https://dashboard.example.com"}
            )

    See Also:
        :class:`NewsCardBot`: For image-focused template cards
        :class:`SmartBot`: For automatic type detection

    Note:
        - Either ``main_title.title`` or ``sub_title_text`` required
        - ``card_action.type``: 1 for URL, 2 for mini-program
        - Rate limit: 20 messages per minute
    """

    _VALID_KEYS: List[str] = TemplateCardKeys + ["emphasis_content", "sub_title_text"]

    @property
    def _doc_key(self) -> str:
        return "文本通知模版卡片"

    def _verify_arguments(self, *args, **kwargs) -> None:
        """
        Verify the arguments passed.
        :param args: Positional arguments.
        :param kwargs: Keyword arguments.
        :return:
        """
        reqs = {
            "Either `main_title.title` should be existed or `sub_title_text` be existed": partial(
                search,
                """
                    (main_title.title == null || main_title.title == '') &&
                    (sub_title_text == null || sub_title_text == '')
                """,
            ),
            **TemplateCardRequirements,
        }
        for msg, cmd in reqs.items():
            logger.debug("Validating parameter error: %s", msg)
            if cmd(kwargs):
                logger.critical("[NO PASS] Parameter validation error: %s", msg)
                raise ValueError(msg)

    def _convert_arguments(self, *args, **kwargs) -> ConvertedData:
        """
        Convert the message to text card format data.
        :param args: Positional arguments.
        :param kwargs: Other keyword arguments.
        :return: Converted data.
        """
        kw_ = {key: val for key, val in kwargs.items() if key in self._VALID_KEYS}
        result = (
            {
                "msgtype": "template_card",
                "template_card": {
                    "card_type": "text_notice",
                    **kw_,
                },
            },
        )
        return result, kwargs
