"""
So sánh mô hình AI trên các hội thoại THẬT: phát lại từng tin khách theo thứ tự,
cùng lõi, cùng kho, chỉ khác mô hình (ép bằng NguCanh.mo_hinh cho mọi lượt gọi AI).

    moitruong/bin/python thu/so_sanh.py <ca.json> <mô hình> <tệp kết quả.json> [che_do]

<mô hình> = "-" thì không ép mô hình (theo vai trong Cài đặt). Có tên mô hình thì TOÀN TRÌNH một mô hình
(chủ dự án 29/09/2026: "không phân chính phụ"): trả lời, đọc lại, phân loại ý định, tóm gọn phiên, việc vặt
đều dùng nó và KHÔNG rơi sang mô hình dự phòng — lỗi hạ tầng thì ghi "(LỖI ...)" chứ không mượn hãng khác. che_do = cu | agent (29/09/2026: chấm mù
lõi cũ với agent tư vấn nao/agent.py) — bỏ trống thì theo Cài đặt.

ca.json: [{"ma": "...", "tin": ["tin khách 1", "tin khách 2", ...]}, ...]
Nhật ký các phiên thử chuyển sang khong_gian 'thu_nghiem' cho khỏi lẫn số liệu.
"""
from __future__ import annotations

import json
import os
import sys
import time
import uuid

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from congcu import csdl  # noqa: E402
from giao_uoc import NguCanh  # noqa: E402
from nao.tra_loi import tra_loi, _lay_nha_cung_cap_dung_chung  # noqa: E402


def _mot_mo_hinh(ncc, mo_hinh):
    """Ép mọi vai trò về một mô hình, tắt dự phòng — chỉ trong tiến trình chạy thử này."""
    from congcu import cau_hinh_ai
    doc_goc = cau_hinh_ai.doc

    def doc(khong_gian='tradingauto', _nguon=None):
        ch = dict(doc_goc(khong_gian, _nguon))
        for k in list(cau_hinh_ai.MAC_DINH) + list(ch):
            if k.startswith('mo_hinh_'):
                ch[k] = '' if k.startswith('mo_hinh_du_phong') else mo_hinh
        return ch

    cau_hinh_ai.doc = doc
    # Mọi lượt gọi chờ như mô hình mạnh: mô hình rẻ mà nghĩ ngầm (DeepSeek 4.1 Flash) hay quá mốc 30s.
    from llm import tuongthich_openai
    tuongthich_openai._THOI_GIAN_CHO = tuongthich_openai._THOI_GIAN_CHO_MANH
    ncc._model_phan_loai = ncc._model_dien_giai = mo_hinh
    ncc._model_du_phong = None
    os.environ['LLM_MODEL_TOM_TAT'] = mo_hinh


def chay(cac_ca, mo_hinh, che_do=''):
    ncc = _lay_nha_cung_cap_dung_chung()
    if mo_hinh != '-':
        _mot_mo_hinh(ncc, mo_hinh)
    ket_qua, cac_phien = [], []
    for ca in cac_ca:
        phien = 'sosanh' + uuid.uuid4().hex[:8]
        cac_phien.append(phien)
        luot = []
        for cau in ca['tin']:
            bat_dau = time.time()
            try:
                kq = tra_loi(cau, NguCanh(phien=phien, khong_gian='tradingauto', kenh='messenger',
                                          mo_hinh='' if mo_hinh == '-' else mo_hinh, che_do=che_do))
                luot.append({
                    'khach': cau, 'bot': kq.tra_loi, 'tang': kq.tang,
                    'mo_hinh': (getattr(ncc, 'model_da_gui_gan_nhat', None) if kq.da_goi_llm else None),
                    'giay': round(time.time() - bat_dau, 1),
                })
            except Exception as loi:  # noqa: BLE001
                luot.append({'khach': cau, 'bot': f'(LỖI: {loi})', 'tang': 0, 'mo_hinh': None,
                             'giay': round(time.time() - bat_dau, 1)})
            print(f"[{mo_hinh}] {ca['ma']} lượt {len(luot)}: {luot[-1]['giay']}s", flush=True)
        ket_qua.append({'ma': ca['ma'], 'luot': luot})
    conn = csdl.ket_noi()
    if conn is not None:
        with conn:
            with conn.cursor() as ct:
                for p in cac_phien:
                    ct.execute("UPDATE chat_hoi_thoai SET khong_gian = 'thu_nghiem' WHERE phien = %s", (p,))
                    ct.execute("UPDATE chat_phien SET khong_gian = 'thu_nghiem' WHERE phien = %s", (p,))
            conn.commit()
    return ket_qua


if __name__ == '__main__':
    if len(sys.argv) not in (4, 5):
        raise SystemExit(__doc__)
    che_do = sys.argv[4] if len(sys.argv) == 5 else ''
    cac_ca = json.load(open(sys.argv[1], encoding='utf-8'))
    kq = chay(cac_ca, sys.argv[2], che_do)
    json.dump({'mo_hinh': sys.argv[2], 'che_do': che_do, 'ca': kq}, open(sys.argv[3], 'w', encoding='utf-8'), ensure_ascii=False, indent=1)
    print('XONG', sys.argv[2])
