"""SalmAlm Thought Stream — quick thought capture with SQLite storage and RAG integration."""

from __future__ import annotations
from salmalm.security.crypto import log

import re
from salmalm.db import get_connection
import time
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any, Dict, List, Optional

from salmalm.constants import KST, DATA_DIR

THOUGHTS_DIR = DATA_DIR
THOUGHTS_DB = THOUGHTS_DIR / "thoughts.db"


def _ensure_dir():
    """Ensure dir."""
    THOUGHTS_DIR.mkdir(parents=True, exist_ok=True)


def _extract_tags(content: str) -> str:
    """Extract hashtags from content. Returns comma-separated tags."""
    tags = re.findall(r"#(\w+)", content)
    return ",".join(tags) if tags else ""


class ThoughtStream:
    """Quick thought capture with SQLite storage."""

    def __init__(self, db_path: Optional[Path] = None) -> None:
        """Init  ."""
        _ensure_dir()
        self.db_path = db_path or THOUGHTS_DB
        self._ensure_db()

    def _ensure_db(self):
        """Ensure db."""
        with get_connection(self.db_path) as conn:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS thoughts (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    content TEXT NOT NULL,
                    tags TEXT DEFAULT '',
                    mood TEXT DEFAULT 'neutral',
                    created_at TEXT NOT NULL
                )
            """)
            conn.execute("""
                CREATE INDEX IF NOT EXISTS idx_thoughts_created
                ON thoughts(created_at)
            """)
            conn.execute("""
                CREATE INDEX IF NOT EXISTS idx_thoughts_tags
                ON thoughts(tags)
            """)

    def add(self, content: str, mood: str = "neutral") -> int:
        """Add a thought. Returns the thought ID."""
        tags = _extract_tags(content)
        now = datetime.now(KST).isoformat()

        with get_connection(self.db_path) as conn:
            cur = conn.execute(
                "INSERT INTO thoughts (content, tags, mood, created_at) VALUES (?, ?, ?, ?)", (content, tags, mood, now)
            )
            thought_id = cur.lastrowid

        # Try RAG indexing
        self._index_thought(thought_id, content, tags)

        return thought_id

    def _index_thought(self, thought_id: int, content: str, tags: str):
        """Index thought in RAG engine."""
        try:
            from salmalm.features.rag import rag_engine

            label = f"thought:{thought_id}"
            rag_engine._index_text(label, content, time.time())
        except Exception as e:  # noqa: broad-except
            pass  # RAG indexing is optional

    def list_recent(self, n: int = 10) -> List[Dict]:
        """List most recent N thoughts."""
        with get_connection(self.db_path) as conn:
            rows = conn.execute("SELECT * FROM thoughts ORDER BY created_at DESC LIMIT ?", (n,)).fetchall()
        return [dict(r) for r in rows]

    def search(self, query: str) -> List[Dict]:
        """Search thoughts using RAG or simple LIKE."""
        # Try RAG search first
        try:
            from salmalm.features.rag import rag_engine

            results = rag_engine.search(query)
            thought_ids = []
            for r in results:
                label = r.get("label", "")
                if label.startswith("thought:"):
                    try:
                        thought_ids.append(int(label.split(":")[1]))
                    except (ValueError, IndexError):
                        pass
            if thought_ids:
                placeholders = ",".join("?" * len(thought_ids))
                with get_connection(self.db_path) as conn:
                    rows = conn.execute(
                        f"SELECT * FROM thoughts WHERE id IN ({placeholders}) ORDER BY created_at DESC", thought_ids
                    ).fetchall()
                return [dict(r) for r in rows]
        except Exception as e:  # noqa: broad-except
            log.debug(f"Suppressed: {e}")

        # Fallback: simple LIKE search
        with get_connection(self.db_path) as conn:
            rows = conn.execute(
                "SELECT * FROM thoughts WHERE content LIKE ? ORDER BY created_at DESC LIMIT 20", (f"%{query}%",)
            ).fetchall()
        return [dict(r) for r in rows]

    def by_tag(self, tag: str) -> List[Dict]:
        """Filter thoughts by tag."""
        with get_connection(self.db_path) as conn:
            rows = conn.execute(
                "SELECT * FROM thoughts WHERE tags LIKE ? ORDER BY created_at DESC", (f"%{tag}%",)
            ).fetchall()
        return [dict(r) for r in rows]

    def timeline(self, date_str: Optional[str] = None) -> List[Dict]:
        """Get thoughts for a specific date (YYYY-MM-DD). Defaults to today."""
        if date_str is None:
            date_str = datetime.now(KST).strftime("%Y-%m-%d")

        with get_connection(self.db_path) as conn:
            rows = conn.execute(
                "SELECT * FROM thoughts WHERE created_at LIKE ? ORDER BY created_at ASC", (f"{date_str}%",)
            ).fetchall()
        return [dict(r) for r in rows]

    def stats(self) -> Dict[str, Any]:
        """Get thought statistics."""
        with get_connection(self.db_path) as conn:
            total = conn.execute("SELECT COUNT(*) FROM thoughts").fetchone()[0]

            # Weekly count
            week_ago = (datetime.now(KST) - timedelta(days=7)).isoformat()
            weekly = conn.execute("SELECT COUNT(*) FROM thoughts WHERE created_at >= ?", (week_ago,)).fetchone()[0]

            # Tag frequency
            rows = conn.execute('SELECT tags FROM thoughts WHERE tags != ""').fetchall()

        tag_counter = {}
        for r in rows:
            for tag in dict(r)["tags"].split(","):
                tag = tag.strip()
                if tag:
                    tag_counter[tag] = tag_counter.get(tag, 0) + 1

        # Sort tags by frequency
        top_tags = sorted(tag_counter.items(), key=lambda x: x[1], reverse=True)[:10]

        return {
            "total": total,
            "weekly": weekly,
            "top_tags": top_tags,
        }

    def export_markdown(self) -> str:
        """Export all thoughts as Markdown."""
        with get_connection(self.db_path) as conn:
            rows = conn.execute("SELECT * FROM thoughts ORDER BY created_at ASC").fetchall()

        if not rows:
            return "# Thought Stream\n\nNo thoughts recorded yet."

        lines = ["# Thought Stream\n"]
        current_date = ""
        for r in rows:
            d = dict(r)
            dt_str = d["created_at"][:10]
            if dt_str != current_date:
                current_date = dt_str
                lines.append(f"\n## {current_date}\n")

            time_str = d["created_at"][11:16] if len(d["created_at"]) > 16 else ""
            tags = f" `{d['tags']}`" if d["tags"] else ""
            mood_emoji = {
                "happy": "😊",
                "sad": "😢",
                "angry": "😠",
                "anxious": "😰",
                "excited": "🎉",
                "tired": "😴",
                "frustrated": "😤",
            }.get(d["mood"], "")
            lines.append(f"- **{time_str}** {mood_emoji} {d['content']}{tags}")

        return "\n".join(lines)

    def delete(self, thought_id: int) -> bool:
        """Delete a thought by ID."""
        with get_connection(self.db_path) as conn:
            cur = conn.execute("DELETE FROM thoughts WHERE id = ?", (thought_id,))
            return cur.rowcount > 0


def _format_thoughts(thoughts: List[Dict], title: str = "") -> str:
    """Format thought list for display."""
    if not thoughts:
        return "💭 기록된 생각이 없습니다."

    lines = []
    if title:
        lines.append(title)
    for t in thoughts:
        dt = t["created_at"][:16] if len(t["created_at"]) > 16 else t["created_at"]
        tags = f" [{t['tags']}]" if t.get("tags") else ""
        mood_emoji = {
            "happy": "😊",
            "sad": "😢",
            "angry": "😠",
            "anxious": "😰",
            "excited": "🎉",
            "tired": "😴",
            "frustrated": "😤",
        }.get(t.get("mood", ""), "")
        lines.append(f"#{t['id']} {dt} {mood_emoji} {t['content']}{tags}")
    return "\n".join(lines)


def _format_stats(s: Dict) -> str:
    """Format stats for display."""
    lines = [
        "📊 **Thought Stats**",
        f"• 총 생각: {s['total']}개",
        f"• 이번 주: {s['weekly']}개",
    ]
    if s["top_tags"]:
        tags_str = ", ".join(f"#{t}({c})" for t, c in s["top_tags"])
        lines.append(f"• 인기 태그: {tags_str}")
    return "\n".join(lines)


# Singleton
thought_stream = ThoughtStream()
