"""حافظهٔ سایت هوشمارک برای مدل پایتونی (بدون نیاز به torch و FastAPI).

سایت جفت‌های «سؤال/پاسخ»ِ حافظهٔ مشترک را می‌فرستد و این ماژول آن‌ها را به فایل
data/site_memory.txt (با همان قالب train.txt) تبدیل می‌کند. هر بار کل فایل جایگزین می‌شود،
پس عبارتی که در سایت حذف شود، در آموزش بعدی هم دیگر نخواهد بود.

مدل نویسه‌ای فقط نمونه‌هایی را یاد می‌گیرد که در BLOCK جا شوند؛ جواب‌های بلندتر
بریده نمی‌شوند (جواب بریده‌شده غلط است) و رد می‌شوند و در گزارش می‌آیند.
"""
from datetime import datetime, timezone
from pathlib import Path
import json
import os

from text_utils import BLOCK, SITE_MEMORY_FILE, fix_chars, normalize_question

META_FILE = SITE_MEMORY_FILE.with_suffix('.meta.json')
HEADER = ('# حافظهٔ سایت هوشمارک — خودکار از سایت ساخته می‌شود؛ دستی ویرایش نکنید.\n'
          '# هر بار همگام‌سازی، کل این فایل جایگزین می‌شود.\n')
MAX_LINE = BLOCK - 1  # یک نویسه برای خط‌جدید انتهای نمونه


def build_lines(entries):
    """(خط‌های گفتگو، گزارش) را از فهرست {question, answer} می‌سازد."""
    report = {'received': 0, 'accepted': 0, 'tooLong': 0, 'invalid': 0, 'duplicates': 0}
    by_question = {}
    for entry in entries or []:
        report['received'] += 1
        question = normalize_question(str((entry or {}).get('question') or ''))
        answer = ' '.join(fix_chars(str((entry or {}).get('answer') or '')).split())
        if not question or not answer:
            report['invalid'] += 1
            continue
        line = f'کاربر: {question} | مدل: {answer}'
        if len(line) > MAX_LINE:
            report['tooLong'] += 1
            continue
        if question in by_question:
            report['duplicates'] += 1
        by_question[question] = line  # آخرین نسخه می‌ماند
    report['accepted'] = len(by_question)
    return list(by_question.values()), report


def _atomic_write(path: Path, text: str):
    path.parent.mkdir(parents=True, exist_ok=True)
    tmp = path.with_name(path.name + '.tmp')
    tmp.write_text(text, encoding='utf-8')
    os.replace(tmp, path)


def save(entries, path: Path = SITE_MEMORY_FILE, meta_path: Path = META_FILE):
    """حافظهٔ سایت را جایگزین می‌کند و گزارش را برمی‌گرداند."""
    lines, report = build_lines(entries)
    _atomic_write(path, HEADER + ''.join(line + '\n' for line in lines))
    report['maxLineLength'] = MAX_LINE
    report['updatedAt'] = datetime.now(timezone.utc).isoformat()
    _atomic_write(meta_path, json.dumps(report, ensure_ascii=False))
    return report


def info(path: Path = SITE_MEMORY_FILE, meta_path: Path = META_FILE):
    """آخرین گزارش همگام‌سازی؛ اگر هرگز همگام‌سازی نشده باشد accepted صفر است."""
    if path.exists() and meta_path.exists():
        try:
            return json.loads(meta_path.read_text(encoding='utf-8'))
        except (OSError, ValueError):
            pass
    return {'received': 0, 'accepted': 0, 'tooLong': 0, 'invalid': 0, 'duplicates': 0,
            'maxLineLength': MAX_LINE, 'updatedAt': None}
