"""Tests for _extract_tokens() and _parse_summary_sections()."""

import pytest

from fetch_notifications import _extract_tokens, _parse_summary_sections


class TestExtractTokens:
    def test_dollar_sign_ticker(self):
        assert _extract_tokens("市場關注 $BTC 和 $ETH 走勢") == ["BTC", "ETH"]

    def test_bold_ticker(self):
        assert _extract_tokens("**SOL** 漲幅明顯，**AVAX** 跟漲") == ["SOL", "AVAX"]

    def test_signal_line_format(self):
        text = "- PEPE: 社群熱度上升\n- WOJAK: 新上線"
        assert _extract_tokens(text) == ["PEPE", "WOJAK"]

    def test_signal_line_chinese_colon(self):
        text = "- DOGE：馬斯克又發推"
        assert _extract_tokens(text) == ["DOGE"]

    def test_signal_line_with_paren(self):
        text = "- ARB(Arbitrum) 生態活躍"
        assert _extract_tokens(text) == ["ARB"]

    def test_mixed_patterns_dedup(self):
        text = "$BTC 持續上漲\n- BTC: 鯨魚買入"
        assert _extract_tokens(text) == ["BTC"]

    def test_preserves_order(self):
        text = "$ETH 先提到，$BTC 後提到"
        assert _extract_tokens(text) == ["ETH", "BTC"]

    def test_blacklist_stablecoin(self):
        assert _extract_tokens("$USDT 和 $USDC 穩定") == []

    def test_blacklist_english_words(self):
        assert _extract_tokens("$THE $AND $FOR $NOT") == []

    def test_blacklist_project_names(self):
        assert _extract_tokens("$BINANCE $GRAYSCALE $POLYMARKET") == []

    def test_ticker_not_blacklisted(self):
        result = _extract_tokens("$BTC $ETH $SOL $BNB")
        assert "BTC" in result
        assert "ETH" in result
        assert "SOL" in result

    def test_case_insensitive_normalized_to_upper(self):
        assert _extract_tokens("$btc and $Eth") == ["BTC", "ETH"]

    def test_too_short_rejected(self):
        assert _extract_tokens("$A") == []

    def test_too_long_partial_match(self):
        assert _extract_tokens("$ABCDEFGHIJKLM") == ["ABCDEFGHIJKL"]

    def test_max_length_accepted(self):
        assert _extract_tokens("$ABCDEFGHIJKL") == ["ABCDEFGHIJKL"]

    def test_empty_string(self):
        assert _extract_tokens("") == []

    def test_no_tokens(self):
        assert _extract_tokens("今天天氣不錯") == []

    def test_real_gemini_output(self):
        text = (
            "## 摘要\n"
            "加密市場整體偏多，$BTC 突破 95000，$ETH 站穩 3600。\n"
            "Meme 板塊 $PEPE 和 $WOJAK 交易量激增。\n\n"
            "## 交易信號\n"
            "- $BTC: 鯨魚持續買入\n"
            "- $PEPE: 社群熱度創新高\n"
            "- $AUCTION: Bounce Finance 品牌重塑"
        )
        tokens = _extract_tokens(text)
        assert tokens == ["BTC", "ETH", "PEPE", "WOJAK", "AUCTION"]

    def test_bold_catches_english_words(self):
        text = "**重要**消息：**Bitcoin** 創新高"
        result = _extract_tokens(text)
        assert "BITCOIN" in result

    def test_bold_skips_non_ascii(self):
        text = "**重要**消息"
        assert _extract_tokens(text) == []

    def test_signal_line_must_start_uppercase(self):
        text = "- some lowercase thing\n- VALID: token"
        assert _extract_tokens(text) == ["VALID"]


class TestParseSummarySections:
    def test_standard_format(self):
        raw = "## 摘要\n市場上漲。\n\n## 交易信號\n- $BTC: 鯨魚買入"
        main, signals = _parse_summary_sections(raw)
        assert main == "市場上漲。"
        assert signals == "- $BTC: 鯨魚買入"

    def test_no_signals_section(self):
        raw = "## 摘要\n今天很平靜。"
        main, signals = _parse_summary_sections(raw)
        assert main == "今天很平靜。"
        assert signals == ""

    def test_no_obvious_signal_normalized_to_empty(self):
        raw = "## 摘要\n沒事。\n\n## 交易信號\n無明顯交易信號"
        main, signals = _parse_summary_sections(raw)
        assert main == "沒事。"
        assert signals == ""

    def test_no_obvious_signal_with_period(self):
        raw = "## 摘要\n沒事。\n\n## 交易信號\n無明顯交易信號。"
        _, signals = _parse_summary_sections(raw)
        assert signals == ""

    def test_empty_string(self):
        assert _parse_summary_sections("") == ("", "")

    def test_no_headers_fallback(self):
        raw = "這是一段沒有標題的文字"
        main, signals = _parse_summary_sections(raw)
        assert main == "這是一段沒有標題的文字"
        assert signals == ""

    def test_multiline_summary(self):
        raw = "## 摘要\n第一句。\n第二句。\n第三句。\n\n## 交易信號\n- $ETH: 漲"
        main, signals = _parse_summary_sections(raw)
        assert "第一句。" in main
        assert "第三句。" in main
        assert signals == "- $ETH: 漲"

    def test_multiple_signals(self):
        raw = "## 摘要\n概要。\n\n## 交易信號\n- $BTC: 原因A\n- $ETH: 原因B\n- $SOL: 原因C"
        _, signals = _parse_summary_sections(raw)
        assert "- $BTC: 原因A" in signals
        assert "- $ETH: 原因B" in signals
        assert "- $SOL: 原因C" in signals

    def test_gemini_preamble_without_headers(self):
        raw = "好的，以下是分析結果：\n\n市場整體偏多。BTC 創新高。"
        main, signals = _parse_summary_sections(raw)
        assert "市場整體偏多" in main
        assert signals == ""

    def test_extra_whitespace_in_headers(self):
        raw = "##  摘要 \n內容。\n\n##  交易信號 \n- $BTC: 理由"
        main, signals = _parse_summary_sections(raw)
        assert main == "內容。"
        assert signals == "- $BTC: 理由"
