# -*- coding: utf-8 -*-
"""写入 SQLite 并确保 situation_update 表存在"""
import sqlite3
import hashlib
import os
from datetime import datetime, timezone
from typing import List, Optional

from config import DB_PATH

CATEGORIES = ("deployment", "alert", "intel", "diplomatic", "other")
SEVERITIES = ("low", "medium", "high", "critical")


def _ensure_table(conn: sqlite3.Connection) -> None:
    conn.execute("""
        CREATE TABLE IF NOT EXISTS situation_update (
            id TEXT PRIMARY KEY,
            timestamp TEXT NOT NULL,
            category TEXT NOT NULL,
            summary TEXT NOT NULL,
            severity TEXT NOT NULL
        )
    """)
    conn.commit()


def _make_id(title: str, url: str, published: str) -> str:
    raw = f"{title}|{url}|{published}"
    return "nw_" + hashlib.sha256(raw.encode("utf-8")).hexdigest()[:16]


def _to_utc_iso(dt: datetime) -> str:
    if dt.tzinfo:
        dt = dt.astimezone(timezone.utc)
    return dt.strftime("%Y-%m-%dT%H:%M:%S.000Z")


def insert_update(
    conn: sqlite3.Connection,
    title: str,
    summary: str,
    url: str,
    published: datetime,
    category: str = "other",
    severity: str = "medium",
) -> bool:
    """插入一条更新，若 id 已存在则跳过。返回是否插入了新记录。"""
    _ensure_table(conn)
    ts = _to_utc_iso(published)
    uid = _make_id(title, url, ts)
    if category not in CATEGORIES:
        category = "other"
    if severity not in SEVERITIES:
        severity = "medium"
    try:
        conn.execute(
            "INSERT OR IGNORE INTO situation_update (id, timestamp, category, summary, severity) VALUES (?, ?, ?, ?, ?)",
            (uid, ts, category, summary[:500], severity),
        )
        conn.commit()
        return conn.total_changes > 0
    except Exception:
        conn.rollback()
        return False


def touch_situation_updated_at(conn: sqlite3.Connection) -> None:
    """更新 situation 表的 updated_at"""
    conn.execute(
        "INSERT OR REPLACE INTO situation (id, data, updated_at) VALUES (1, '{}', ?)",
        (datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.000Z"),),
    )
    conn.commit()


def touch_situation_updated_at_path(db_path: Optional[str] = None) -> bool:
    """仅更新 situation.updated_at 为当前时间（每次爬虫运行都调用，便于前端显示「最后抓取时间」）。返回是否成功。"""
    path = db_path or DB_PATH
    if not os.path.exists(path):
        return False
    conn = sqlite3.connect(path, timeout=10)
    try:
        touch_situation_updated_at(conn)
        return True
    finally:
        conn.close()


def write_updates(updates: List[dict], db_path: Optional[str] = None) -> int:
    """
    updates: [{"title","summary","url","published","category","severity"}, ...]
    db_path: 与 pipeline 一致，缺省用 config.DB_PATH
    返回新增条数。
    """
    path = db_path or DB_PATH
    if not os.path.exists(path):
        return 0
    conn = sqlite3.connect(path, timeout=10)
    try:
        count = 0
        for u in updates:
            pub = u.get("published")
            if isinstance(pub, str):
                try:
                    pub = datetime.fromisoformat(pub.replace("Z", "+00:00"))
                except ValueError:
                    pub = datetime.utcnow()
            elif pub is None:
                pub = datetime.utcnow()
            ok = insert_update(
                conn,
                title=u.get("title", "")[:200],
                summary=u.get("summary", "") or u.get("title", ""),
                url=u.get("url", ""),
                published=pub,
                category=u.get("category", "other"),
                severity=u.get("severity", "medium"),
            )
            if ok:
                count += 1
        if count > 0:
            touch_situation_updated_at(conn)
        return count
    finally:
        conn.close()
