"""
core/msg_builder.py

Resolve configured message templates into concrete per-target messages.
"""

import random
from datetime import date
from typing import Dict, List, Optional

from utils.config import get_config
from utils.hitokoto import request_hitokoto


FESTIVAL_WINDOW_START = date(2026, 2, 16)
FESTIVAL_WINDOW_END = date(2026, 3, 3)


def _is_holiday_mode_enabled(active_config: dict, today: date) -> bool:
    return bool(active_config.get("happyNewYear", {}).get("enabled", False)) and FESTIVAL_WINDOW_START <= today <= FESTIVAL_WINDOW_END


def _render_holiday_message(active_config: dict, today: date) -> str:
    from utils.chinese_new_year_2026_mare import get_lunar_date, get_random_festival_quote

    message = str(active_config.get("happyNewYear", {}).get("messageTemplate", "[API]"))
    if "[data]" in message:
        message = message.replace("[data]", today.strftime("%Y年%m月%d日"))
    if "[data_lunar]" in message:
        lunar_date = get_lunar_date(today)
        message = message.replace("[data_lunar]", lunar_date if lunar_date else "未知农历日期")
    if "[API]" in message:
        message = message.replace("[API]", get_random_festival_quote())
    return message.strip()


def _get_message_templates(active_config: dict) -> List[str]:
    strategy = active_config.get("sendStrategy", {}) or {}
    variants = [str(item).strip() for item in strategy.get("messageVariants", []) if str(item).strip()]
    if variants:
        return variants
    return [str(active_config.get("messageTemplate", "续火花")).strip()]


def _render_regular_message(template: str) -> str:
    message = template
    if "[API]" in message:
        message = message.replace("[API]", request_hitokoto())
    return message.strip()


def build_message_candidates(config: Optional[dict] = None) -> List[str]:
    active_config = config or get_config()
    today = date.today()

    if _is_holiday_mode_enabled(active_config, today):
        return [_render_holiday_message(active_config, today)]

    candidates: List[str] = []
    for template in _get_message_templates(active_config):
        message = _render_regular_message(template)
        if message and message not in candidates:
            candidates.append(message)

    if candidates:
        return candidates
    return ["续火花"]


def _extract_previous_message(previous_messages: Optional[dict], target: str) -> str:
    if not previous_messages:
        return ""

    previous = previous_messages.get(target, "")
    if isinstance(previous, dict):
        return str(previous.get("message", "")).strip()
    return str(previous).strip()


def _choose_message(candidates: List[str], previous_message: str, last_message: str) -> str:
    filtered = [message for message in candidates if message != previous_message and message != last_message]
    if filtered:
        return random.choice(filtered)

    filtered = [message for message in candidates if message != previous_message]
    if filtered:
        return random.choice(filtered)

    filtered = [message for message in candidates if message != last_message]
    if filtered:
        return random.choice(filtered)

    return random.choice(candidates)


def build_message(previous_message: str = "", config: Optional[dict] = None, last_message: str = "") -> str:
    candidates = build_message_candidates(config)
    return _choose_message(candidates, previous_message.strip(), last_message.strip()).strip()


def build_messages_for_targets(
    targets: List[str],
    previous_messages: Optional[dict] = None,
    config: Optional[dict] = None,
) -> Dict[str, str]:
    active_config = config or get_config()
    strategy = active_config.get("sendStrategy", {}) or {}

    ordered_targets = []
    seen_targets = set()
    for target in targets:
        normalized = str(target).strip()
        if not normalized or normalized in seen_targets:
            continue
        seen_targets.add(normalized)
        ordered_targets.append(normalized)

    if strategy.get("shuffleTargets", True):
        random.shuffle(ordered_targets)

    planned_messages: Dict[str, str] = {}
    last_message = ""
    for target in ordered_targets:
        previous_message = _extract_previous_message(previous_messages, target)
        message = build_message(previous_message=previous_message, config=active_config, last_message=last_message)
        planned_messages[target] = message
        last_message = message

    return planned_messages
