"""
Index swept Slack documents from SQLite into the embedding engine.

Usage:
    python tools/index_slack.py              # index all unindexed docs
    python tools/index_slack.py --reindex    # re-index everything (ignore indexed flag)

Required env vars (set in .env or environment):
    EMBEDDING_ENGINE_URL    Base URL of the embedding engine (default: http://localhost:8000)
    SLACK_USER_ID           Slack user ID (used to derive REPO_ID if not set)
    SLACK_SWEEP_REPO_ID     repo_id (default: slack-<user_id>)
    SLACK_SWEEP_SNAPSHOT_ID snapshot_id (default: snap-<YYYY-MM-DD>)
    SLACK_SQLITE_DB         Path to SQLite DB (default: tools/slack_data.db)
"""

import os
import sys
import sqlite3
import time
import logging
from datetime import datetime, timezone
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from dotenv import load_dotenv
load_dotenv(Path(__file__).parent.parent / ".env")

import requests

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("index_slack")

ENGINE_URL    = os.environ.get("EMBEDDING_ENGINE_URL", "http://localhost:8000")
SLACK_USER_ID = os.environ.get("SLACK_USER_ID", "")
REPO_ID       = os.environ.get("SLACK_SWEEP_REPO_ID",     f"slack-{SLACK_USER_ID}")
TODAY         = datetime.now(timezone.utc).strftime("%Y-%m-%d")
SNAPSHOT_ID   = os.environ.get("SLACK_SWEEP_SNAPSHOT_ID", f"snap-{TODAY}")
SQLITE_DB     = os.environ.get("SLACK_SQLITE_DB", str(Path(__file__).parent / "slack_data.db"))


def _post(path: str, payload: dict, max_retries: int = 5) -> dict:
    backoff = 15
    for attempt in range(max_retries):
        try:
            resp = requests.post(f"{ENGINE_URL}{path}", json=payload, timeout=120)
            resp.raise_for_status()
            return resp.json()
        except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as exc:
            if attempt == max_retries - 1:
                raise
            wait = backoff * (attempt + 1)
            log.warning("Request failed (%s), retrying in %ds", exc, wait)
            time.sleep(wait)
        except requests.exceptions.HTTPError as exc:
            log.error("HTTP %s on %s: %s", exc.response.status_code, path, exc.response.text[:200])
            raise


def run(reindex: bool = False) -> None:
    if not Path(SQLITE_DB).exists():
        log.error("SQLite DB not found: %s — run fetch_slack.py first", SQLITE_DB)
        sys.exit(1)

    con = sqlite3.connect(SQLITE_DB)
    con.row_factory = sqlite3.Row

    where = "1=1" if reindex else "indexed = 0"
    rows = con.execute(f"""
        SELECT id, repo_id, channel_name, doc_path, snapshot_id, content
        FROM slack_documents
        WHERE {where}
        ORDER BY id
    """).fetchall()

    total = con.execute("SELECT COUNT(*) FROM slack_documents").fetchone()[0]
    log.info(
        "DB: %s | total=%d  to_index=%d  reindex=%s  repo=%s  snapshot=%s",
        SQLITE_DB, total, len(rows), reindex, REPO_ID, SNAPSHOT_ID,
    )

    if not rows:
        log.info("Nothing to index.")
        con.close()
        return

    indexed = 0
    failed  = 0
    for row in rows:
        try:
            data = _post("/api/v1/ingest/", {
                "repo_id":     row["repo_id"],
                "doc_path":    row["doc_path"],
                "content":     row["content"],
                "commit_hash": row["snapshot_id"],
            })
            con.execute(
                "UPDATE slack_documents SET indexed=1, indexed_at=? WHERE id=?",
                (datetime.now(timezone.utc).isoformat(), row["id"]),
            )
            con.commit()
            log.info("  Indexed #%s → run_id=%s", row["channel_name"], data.get("run_id"))
            indexed += 1
        except Exception as exc:
            log.error("  FAILED #%s: %s", row["channel_name"], exc)
            failed += 1
        time.sleep(0.3)

    con.close()
    log.info("Indexed: %d  Failed: %d", indexed, failed)

    if indexed > 0:
        log.info("Triggering embedding pipeline repo=%s snapshot=%s", REPO_ID, SNAPSHOT_ID)
        try:
            data = _post("/api/v1/pipeline/snapshots/embed", {
                "repo_id":     REPO_ID,
                "snapshot_id": SNAPSHOT_ID,
                "commit_sha":  TODAY.replace("-", ""),
            })
            log.info("Embedding run queued: %s", data.get("run_id"))
            log.info(
                "Update slack-bot-service .env:\n"
                "  REPO_ID=%s\n  SNAPSHOT_ID=%s",
                REPO_ID, SNAPSHOT_ID,
            )
        except Exception as exc:
            log.error("Failed to trigger embedding: %s", exc)


if __name__ == "__main__":
    reindex_all = "--reindex" in sys.argv
    run(reindex=reindex_all)
