# -*- coding: utf-8 -*-
"""NHÀ CUNG CẤP RỖNG — không gọi mạng, không cần khoá API.

VÌ SAO cần tệp này dù không "thông minh": hai lý do.
1. Chạy test: mọi module khác (tìm kiếm, lõi, cổng web) phải test được mà
   không cần khoá Anthropic/OpenAI thật và không tốn tiền mỗi lần chạy CI.
2. Hệ vẫn phải SỐNG khi chưa cấu hình khoá hoặc khi ngân sách ngày đã hết
   (`bao_ve/ngan_sach.py` báo hết) — thà trả lời cộc bằng chính đoạn tài
   liệu tìm được còn hơn bot im lặng hoặc 500.
"""
from __future__ import annotations

import re
import sys
import os
from typing import List

try:
    from .giao_dien import NhaCungCap
    from ..giao_uoc import NguCanh, KetQuaTim, Ydinh
except ImportError:
    sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    from llm.giao_dien import NhaCungCap  # type: ignore
    from giao_uoc import NguCanh, KetQuaTim, Ydinh  # type: ignore


# Cắt câu đơn giản theo dấu chấm/chấm hỏi/chấm than/xuống dòng — đủ dùng
# cho việc lấy "2 câu đầu", không cần bộ tách câu đầy đủ (spaCy...) vì đây
# chỉ là chế độ dự phòng, không phải đường chính.
_MAU_CAT_CAU = re.compile(r'(?<=[.!?…])\s+|\n+')


def _hai_cau_dau(van_ban: str) -> str:
    if not van_ban:
        return ""
    cau = [c.strip() for c in _MAU_CAT_CAU.split(van_ban.strip()) if c.strip()]
    return " ".join(cau[:2])


class NhaCungCapRong(NhaCungCap):
    """Không gọi mạng. `dien_giai` ghép câu trả lời từ chính đoạn điểm cao
    nhất — không bao giờ trả chuỗi rỗng, kể cả khi không có đoạn nào.
    """

    ten = 'rong'

    def phan_loai(self, cau_hoi: str, ngu_canh: NguCanh) -> Ydinh:
        # Không có mô hình để phân loại thật — luôn trả 'khac', lõi tự lo
        # phần định tuyến còn lại (vd dò từ khoá giá bằng congcu/).
        return 'khac'

    def dien_giai(self, cau_hoi: str, cac_doan: List[KetQuaTim], ngu_canh: NguCanh) -> str:
        # Câu dẫn này KHÁCH THẬT đọc được, nên viết như nói với khách chứ
        # không phải như ghi chú cho lập trình viên.
        #
        # Bản đầu để '(chế độ không có AI — trích thẳng từ tài liệu)' và nó
        # đã lên thẳng trang production trong lúc deploy. Khách không cần
        # biết bên trong có mô hình hay không; họ cần biết đây là trích từ
        # tài liệu và đọc bản đầy đủ ở đâu — mà phần 'Nguồn tham khảo' do
        # lõi gắn vào đã nói đúng điều đó rồi.
        ghi_chu = {
            'vi': '— trích từ tài liệu, anh/chị xem bản đầy đủ ở đường dẫn bên dưới ạ.',
            'en': '— quoted from the documentation; the full page is linked below.',
        }.get(ngu_canh.ngon_ngu,
              '— trích từ tài liệu, anh/chị xem bản đầy đủ ở đường dẫn bên dưới ạ.')

        if not cac_doan:
            khong_co = {
                'vi': 'Em chưa tìm được tài liệu phù hợp cho câu hỏi này.',
                'en': 'I could not find a matching document for this question.',
            }.get(ngu_canh.ngon_ngu, 'Em chưa tìm được tài liệu phù hợp cho câu hỏi này.')
            return f"{khong_co} {ghi_chu}"

        # cac_doan đã được tầng tìm kiếm sắp theo điểm giảm dần (hợp đồng
        # `tim()` trong giao_uoc.py), nên đoạn đầu tiên là đoạn điểm cao nhất.
        doan_cao_nhat = cac_doan[0].doan
        noi_dung = doan_cao_nhat.van_ban_en if (
            ngu_canh.ngon_ngu == 'en' and doan_cao_nhat.van_ban_en
        ) else doan_cao_nhat.van_ban_vi

        trich = _hai_cau_dau(noi_dung)
        if not trich:
            # Đoạn tồn tại nhưng rỗng/không cắt được câu — vẫn không được
            # trả rỗng, nên rơi về nguyên văn đoạn (đã được đảm bảo không rỗng
            # bởi tầng nạp tri thức) hoặc câu ghi chú.
            trich = noi_dung.strip() or "(nội dung trống)"

        return f"{trich} {ghi_chu}"


if __name__ == '__main__':
    # ---- Tự kiểm NhaCungCapRong bằng vài đoạn giả ----
    try:
        from ..giao_uoc import Doan
    except ImportError:
        from giao_uoc import Doan  # type: ignore

    d1 = Doan(
        ma='dcabot/huong_dan/0001',
        van_ban_vi='Cài DCA Bot bằng cách tải EA từ trang chủ. Sau đó gắn vào biểu đồ MT5. Cuối cùng nhập license key.',
        van_ban_en='Install DCA Bot by downloading the EA from the homepage. Then attach it to an MT5 chart. Finally enter the license key.',
        san_pham='dcabot',
        loai='huong_dan',
        duong_dan='/guilde/dcabot',
        tieu_de='Hướng dẫn cài DCA Bot',
        nguon_tep='guilde/dcabot.php',
    )
    d2 = Doan(
        ma='dcabot/faq/0002',
        van_ban_vi='Lỗi Invalid Master Code xảy ra khi nhập sai mã kích hoạt.',
        van_ban_en='',
        san_pham='dcabot',
        loai='faq',
        duong_dan='/faq/dcabot',
        tieu_de='FAQ lỗi kích hoạt',
        nguon_tep='faq/dcabot.php',
    )

    kq1 = KetQuaTim(doan=d1, diem=9.5)
    kq2 = KetQuaTim(doan=d2, diem=3.1)

    nc = NguCanh(phien='test-phien', ngon_ngu='vi')
    ncc = NhaCungCapRong()

    print("=== phan_loai ===")
    print("ten nha cung cap:", ncc.ten)
    print("phan_loai(...) =", ncc.phan_loai('DCA Bot cài sao vậy em', nc))

    print("\n=== dien_giai với 2 đoạn (vi) ===")
    print(ncc.dien_giai('Cài DCA Bot thế nào?', [kq1, kq2], nc))

    print("\n=== dien_giai với 2 đoạn (en, đoạn top có bản EN) ===")
    nc_en = NguCanh(phien='test-phien', ngon_ngu='en')
    print(ncc.dien_giai('How to install DCA Bot?', [kq1, kq2], nc_en))

    print("\n=== dien_giai với đoạn top KHÔNG có bản EN (rơi về VI) ===")
    print(ncc.dien_giai('Invalid Master Code là lỗi gì?', [kq2], nc_en))

    print("\n=== dien_giai không có đoạn nào ===")
    ket_qua_rong = ncc.dien_giai('Câu hỏi lạ hoắc', [], nc)
    print(repr(ket_qua_rong))
    assert ket_qua_rong.strip() != "", "LỖI: dien_giai không được trả chuỗi rỗng"

    print("\nKẾT LUẬN: NhaCungCapRong hoạt động đúng, không có trường hợp trả rỗng.")
