from __future__ import annotations

import hashlib
import re
from datetime import datetime, timedelta, timezone
from typing import Any

from niannian.schemas.models import Atom


def normalize_for_dedup(text: str) -> str:
    t = (text or "").lower().strip()
    t = re.sub(r"\s+", " ", t)
    t = re.sub("[，。！？、；：""''（）【】《》.,!?;:'\"()\\[\\]{}]", "", t)
    return t[:500]


def chat_dedup_key(text: str) -> str:
    norm = normalize_for_dedup(text)
    return "chat:" + hashlib.sha256(norm.encode()).hexdigest()[:16]


def consolidate_remember_text(
    user_text: str,
    assistant_text: str,
    *,
    max_chars: int = 2000,
) -> str:
    user_text = (user_text or "").strip()
    assistant_text = (assistant_text or "").strip()
    pref = re.search(r"我(喜欢|偏好|习惯|想要|需要|决定|计划)(.+)", user_text)
    if pref:
        return f"用户{pref.group(1)}{pref.group(2).strip()}"[:max_chars]
    return f"用户: {user_text}\n助手: {assistant_text}"[:max_chars]


def dedup_exists_recently(
    left_store: Any,
    dedup_key: str,
    project: str,
    *,
    hours: int = 24,
) -> bool:
    cutoff = datetime.now(timezone.utc) - timedelta(hours=hours)
    for atom in reversed(left_store.list_atoms(project=project, limit=2000)):
        if not isinstance(atom, Atom):
            continue
        if atom.meta.get("dedup_key") != dedup_key:
            continue
        try:
            created = datetime.fromisoformat(atom.created_at)
        except ValueError:
            continue
        if created.tzinfo is None:
            created = created.replace(tzinfo=timezone.utc)
        if created >= cutoff:
            return True
    return False
