from __future__ import annotations

from pathlib import Path
import sqlite3

from eightmem.core.paths import memory_dir
from eightmem.core.pipeline import analyze_chat_export
from eightmem.core.templates import copy_default_templates
from eightmem.mirror.summary import build_mirror_text


def test_analyze_updates_memory(fake_home, tmp_path: Path):
    sample = tmp_path / "sample.json"
    sample.write_text(
        '[{"role":"user","content":"I am a backend engineer. Please keep answers short. We decided to launch beta."}]',
        encoding="utf-8",
    )

    mem = memory_dir()
    mem.mkdir(parents=True, exist_ok=True)
    copy_default_templates(mem)

    stats = analyze_chat_export(sample, mem)
    assert any(v >= 0 for v in stats.values())

    identity = (mem / "IDENTITY.md").read_text(encoding="utf-8")
    prefs = (mem / "PREFERENCES.md").read_text(encoding="utf-8")
    assert "backend engineer" in identity.lower()
    assert "keep answers short" in prefs.lower()

    db_path = fake_home / ".memory_facts.sqlite3"
    with sqlite3.connect(db_path) as conn:
        rows = conn.execute(
            "SELECT file_name, object_text FROM facts WHERE valid_to IS NULL ORDER BY file_name, object_text"
        ).fetchall()

    assert any(file_name == "IDENTITY.md" and "backend engineer" in object.lower() for file_name, object in rows)
    assert any(file_name == "PREFERENCES.md" and "keep answers short" in object.lower() for file_name, object in rows)


def test_preferences_are_sentence_level_and_clean(fake_home, tmp_path: Path):
    sample = tmp_path / "prefs.json"
    sample.write_text(
        '[{"role":"user","content":"Please keep answers short and practical. Avoid buzzwords and emojis. Don\\u2019t use emojis."}]',
        encoding="utf-8",
    )

    mem = memory_dir()
    mem.mkdir(parents=True, exist_ok=True)
    copy_default_templates(mem)

    analyze_chat_export(sample, mem)
    prefs = (mem / "PREFERENCES.md").read_text(encoding="utf-8").lower()

    assert "keep answers short and practical." in prefs
    assert "avoid buzzwords and emojis." in prefs
    assert "short and practical. avoid buzzwords and emojis" not in prefs


def test_mirror_non_empty(fake_home):
    mem = memory_dir()
    mem.mkdir(parents=True, exist_ok=True)
    copy_default_templates(mem)

    summary = build_mirror_text(mem)
    assert "AI Believes About You" in summary
    assert "Identity" in summary


def test_prefixed_decision_and_correction_lines_map_to_correct_buckets(fake_home, tmp_path: Path):
    sample = tmp_path / "day2_style.txt"
    sample.write_text(
        "\n".join(
            [
                "Correction: don't assume I only care about CLI; UI onboarding is now priority.",
                "Preference update: use numbered steps.",
                "Decision: add collaborator testing checklist before public sharing.",
            ]
        ),
        encoding="utf-8",
    )

    mem = memory_dir()
    mem.mkdir(parents=True, exist_ok=True)
    copy_default_templates(mem)

    analyze_chat_export(sample, mem)

    prefs = (mem / "PREFERENCES.md").read_text(encoding="utf-8").lower()
    corrections = (mem / "CORRECTIONS.md").read_text(encoding="utf-8").lower()
    decisions = (mem / "DECISIONS.md").read_text(encoding="utf-8").lower()

    assert "prefers numbered steps." in prefs
    assert "do not assume i only care about cli" in corrections
    assert "add collaborator testing checklist before public sharing" in decisions


def test_analyze_splits_correction_sentences_and_keeps_only_real_corrections(fake_home, tmp_path: Path):
    sample = tmp_path / "corrections.json"
    sample.write_text(
        '[{"role":"user","content":"Avoid buzzwords. Don\\u2019t use emojis. That\\u2019s wrong, use common language instead."}]',
        encoding="utf-8",
    )

    mem = memory_dir()
    mem.mkdir(parents=True, exist_ok=True)
    copy_default_templates(mem)

    analyze_chat_export(sample, mem)
    corrections = (mem / "CORRECTIONS.md").read_text(encoding="utf-8").lower()

    assert "avoid buzzwords. don't use emojis" not in corrections
    assert "do not use emojis" in corrections
    assert "use common language instead." in corrections
