# -*- coding: utf-8 -*-
"""KHUON_MAU.PY — ghép câu trả lời cho nhánh tra cứu, KHÔNG qua mô hình ngôn ngữ.

VÌ SAO KHÔNG ĐƯA CHO LLM VIẾT
------------------------------
Đây là tầng mà sai MỘT chữ số là mất khách (báo giá sai, báo nhầm ngày
hết hạn key). Mô hình ngôn ngữ giỏi diễn giải nhưng không đáng tin để tự
"nhớ" hoặc tự "làm tròn" một con số — nó có thể bịa ra một con số nghe
hợp lý nhưng sai. Vì vậy các hàm ở đây nhận dữ liệu ĐÃ ĐỌC XONG từ
`san_pham.py` / `licence.py` (tức là sự thật từ CSDL) và chỉ làm công
việc GHÉP CHUỖI — không suy diễn, không tính toán lại giá.

Cách chạy tự kiểm (không cần CSDL, dùng dữ liệu giả):
    python congcu/khuon_mau.py
"""
from __future__ import annotations

import os
import sys
from typing import List, Sequence

try:
    from ..giao_uoc import GiaGoi, KeyCuaKhach, SanPham
except ImportError:
    _THU_MUC_CHA = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    if _THU_MUC_CHA not in sys.path:
        sys.path.insert(0, _THU_MUC_CHA)
    from giao_uoc import GiaGoi, KeyCuaKhach, SanPham


DUONG_DAN_BANG_GIA = '/Pricing'


def _dinh_dang_so(gia: float) -> str:
    """9.0 -> '9', 9.5 -> '9.5'. Tránh in '9.0 credit' trông cứng nhắc."""
    try:
        so = float(gia)
        if so == int(so):
            return str(int(so))
        return f"{so:.2f}".rstrip('0').rstrip('.')
    except (TypeError, ValueError):
        return str(gia)


def _nhan_goi(goi: GiaGoi, ngon_ngu: str) -> str:
    if goi.nhan:
        return goi.nhan
    if goi.thang == 0:
        return 'Vĩnh viễn' if ngon_ngu == 'vi' else 'Lifetime'
    return f"{goi.thang} tháng" if ngon_ngu == 'vi' else f"{goi.thang} month(s)"


def _nhan_nguon_key(nguon: str, ngon_ngu: str) -> str:
    if ngon_ngu == 'vi':
        return 'website' if nguon == 'web' else 'máy chủ key'
    return 'website' if nguon == 'web' else 'key server'


# =====================================================================
# CÂU GIÁ MỘT SẢN PHẨM
# =====================================================================

def cau_gia(sp: SanPham, ngon_ngu: str = 'vi') -> str:
    ten = (sp.ten_vi or sp.ten) if ngon_ngu == 'vi' else (sp.ten or sp.ten_vi)

    if not sp.cac_goi:
        if ngon_ngu == 'vi':
            return (
                f"Dạ hiện em chưa lấy được giá của {ten} ạ. "
                f"Anh/chị xem tạm tại {DUONG_DAN_BANG_GIA} hoặc nhắn lại giúp em kiểm tra nhé."
            )
        return (
            f"Sorry, pricing for {ten} is not available right now. "
            f"Please check {DUONG_DAN_BANG_GIA} or ask again in a moment."
        )

    dong_gia = [
        f"- {_nhan_goi(goi, ngon_ngu)}: {_dinh_dang_so(goi.gia)} credit"
        for goi in sp.cac_goi
    ]

    if ngon_ngu == 'vi':
        dau = f"Dạ giá {ten} (đơn vị credit, 1 USD = 1 credit):"
        cuoi = f"Bảng giá đầy đủ: {DUONG_DAN_BANG_GIA} ạ."
    else:
        dau = f"{ten} pricing (unit: credit, 1 USD = 1 credit):"
        cuoi = f"Full price list: {DUONG_DAN_BANG_GIA}"

    return dau + "\n" + "\n".join(dong_gia) + "\n" + cuoi


# =====================================================================
# BẢNG GIÁ TẤT CẢ SẢN PHẨM
# =====================================================================

def cau_bang_gia_tat_ca(ds: List[SanPham], ngon_ngu: str = 'vi', them: Sequence[str] = ()) -> str:
    """`them`: dòng giá gọn của sản phẩm ngoài bảng `product` (HoSoShop.bang_gia_them, vd VipTrend)."""
    if not ds:
        if ngon_ngu == 'vi':
            return (
                f"Dạ hiện em chưa lấy được bảng giá ạ. "
                f"Anh/chị xem trực tiếp tại {DUONG_DAN_BANG_GIA} giúp em nhé."
            )
        return f"Sorry, I could not load the price list right now. Please check {DUONG_DAN_BANG_GIA}."

    # SAN PHAM MIEN PHI LEN DAU. Y kien chu du an 22/09/2026 (cau #1):
    # "Khi tra loi toan bo thi dua cai mt5 manager len truoc vi free."
    # Khong viet cung ma 'mt5manager' — xep theo TINH CHAT (khong co goi gia
    # nao, hoac moi goi deu gia 0) nen sau nay them san pham free khac thi no
    # tu dong len dau, khong phai sua lai cho nay. Cac san pham con lai giu
    # nguyen thu tu san_pham.py tra ve (sort_order cua trang quan tri).
    def _mien_phi(sp) -> bool:
        return bool(sp.cac_goi) and all(float(g.gia) == 0 for g in sp.cac_goi)

    ds = sorted(ds, key=lambda sp: 0 if _mien_phi(sp) else 1)

    dong: List[str] = []
    for sp in ds:
        ten = (sp.ten_vi or sp.ten) if ngon_ngu == 'vi' else (sp.ten or sp.ten_vi)
        if not sp.cac_goi:
            phan_gia = 'chưa có giá' if ngon_ngu == 'vi' else 'no pricing yet'
        elif _mien_phi(sp):
            phan_gia = 'MIỄN PHÍ' if ngon_ngu == 'vi' else 'FREE'
        else:
            phan_gia = ', '.join(
                f"{_nhan_goi(goi, ngon_ngu)} {_dinh_dang_so(goi.gia)} credit"
                for goi in sp.cac_goi
            )
        dong.append(f"- {ten}: {phan_gia}")
    dong.extend(f"- {d}" for d in them)

    if ngon_ngu == 'vi':
        dau = 'Dạ bảng giá các sản phẩm (đơn vị credit, 1 USD = 1 credit):'
        cuoi = f"Xem chi tiết: {DUONG_DAN_BANG_GIA} ạ."
    else:
        dau = 'Price list (unit: credit, 1 USD = 1 credit):'
        cuoi = f"Details: {DUONG_DAN_BANG_GIA}"

    return dau + "\n" + "\n".join(dong) + "\n" + cuoi


def cau_gia_them(ten: str, cac_dong: Sequence[str], ngon_ngu: str = 'vi') -> str:
    """Giá một sản phẩm NGOÀI bảng `product` (HoSoShop.bang_gia_them) — dòng giá chủ dự án
    khai sẵn, chỉ ghép chuỗi như cau_gia()."""
    if ngon_ngu == 'vi':
        dau = f"Dạ giá {ten} (đơn vị credit, 1 USD = 1 credit):"
        cuoi = f"Bảng giá đầy đủ: {DUONG_DAN_BANG_GIA} ạ."
    else:
        dau = f"{ten} pricing (unit: credit, 1 USD = 1 credit):"
        cuoi = f"Full price list: {DUONG_DAN_BANG_GIA}"
    return dau + "\n" + "\n".join(f"- {d}" for d in cac_dong) + "\n" + cuoi


# =====================================================================
# CÂU TRA KEY
# =====================================================================

def cau_key(ds: List[KeyCuaKhach] = None, ngon_ngu: str = 'vi') -> str:
    """TRA KEY ĐÃ TẮT — hàm này KHÔNG BAO GIỜ in dữ liệu key ra nữa.

    Chủ dự án quyết định 23/09/2026: "tắt phần tra key, tốt nhất ko nên lòi
    dữ liệu key của khách ra bảng tư vấn".

    Bản trước nhận danh sách key rồi liệt kê mã sản phẩm, trạng thái và
    NGÀY HẾT HẠN của từng key. Nay bỏ hẳn phần liệt kê đó. Tham số `ds` giữ
    lại để nơi gọi cũ không vỡ, nhưng NỘI DUNG CỦA NÓ BỊ BỎ QUA HOÀN TOÀN.

    VÌ SAO gut hẳn hàm chứ không chỉ thôi gọi nó: nếu chỉ sửa ở nơi gọi thì
    khả năng in key vẫn nằm đó, chờ một người sau đấu lại cho "tiện". Bỏ
    khả năng đi thì không còn gì để đấu lại. Khung chat là chỗ rò rỉ dễ
    nhất trong hệ — ảnh chụp màn hình, máy dùng chung, và nhật ký hội thoại
    lưu nguyên mã key nằm trong CSDL mãi mãi.

    Khách tự xem đầy đủ key và hạn dùng tại /orders, nơi đã có xác thực tử
    tế. Bot chỉ chỉ đường.
    """
    if ngon_ngu == 'en':
        return (
            "For security, I do not read out license keys here in chat. "
            "Please log in and open your order management page at /orders — "
            "every key and its expiry date is listed there.\n\n"
            "If something looks wrong on that page, tell me and I will help "
            "you sort it out."
        )
    return (
        "Dạ để an toàn cho anh/chị, em không đọc mã key ra ở khung chat ạ. "
        "Anh/chị đăng nhập rồi vào mục quản lý đơn hàng tại /orders — ở đó "
        "có đầy đủ key và hạn dùng của từng sản phẩm.\n\n"
        "Nếu vào xem mà thấy có gì chưa đúng thì anh/chị báo em, em hỗ trợ "
        "kiểm tra giúp ạ."
    )


# =====================================================================
# CÂU KHÔNG RÕ SẢN PHẨM
# =====================================================================

def cau_khong_ro(ngon_ngu: str = 'vi') -> str:
    if ngon_ngu == 'vi':
        return (
            'Dạ em chưa xác định được anh/chị đang hỏi về sản phẩm nào ạ. '
            'Anh/chị cho em xin tên cụ thể (vd: DCA Bot, Copytrade, TradingView...) '
            f'hoặc xem toàn bộ tại {DUONG_DAN_BANG_GIA} giúp em nhé.'
        )
    return (
        "I'm not sure which product you mean. Could you give the exact name "
        f"(e.g. DCA Bot, Copytrade, TradingView), or check the full list at {DUONG_DAN_BANG_GIA}?"
    )


# =====================================================================
# TỰ KIỂM — dữ liệu giả, không cần CSDL
# =====================================================================
if __name__ == '__main__':
    sp_co_gia = SanPham(
        ma='dcabot', slug='dcabot', ten='DCA Bot', ten_vi='DCA Bot',
        backend='dcabot', phien_ban='2.1',
        cac_goi=[
            GiaGoi(thang=1, gia=9, nhan='1 tháng'),
            GiaGoi(thang=3, gia=24, nhan='3 tháng'),
            GiaGoi(thang=0, gia=49, nhan='Vĩnh viễn'),
        ],
    )
    sp_khong_gia = SanPham(
        ma='trendbot', slug='trendbot', ten='TrendBot', ten_vi='TrendBot',
        backend='trendbot', phien_ban='1.0', cac_goi=[],
    )

    print('=== cau_gia (vi) ===')
    print(cau_gia(sp_co_gia, 'vi'))
    print()
    print('=== cau_gia (en) ===')
    print(cau_gia(sp_co_gia, 'en'))
    print()
    print('=== cau_gia — sản phẩm chưa có giá (vi) ===')
    print(cau_gia(sp_khong_gia, 'vi'))
    print()

    print('=== cau_bang_gia_tat_ca (vi) ===')
    print(cau_bang_gia_tat_ca([sp_co_gia, sp_khong_gia], 'vi'))
    print()
    print('=== cau_bang_gia_tat_ca (en) ===')
    print(cau_bang_gia_tat_ca([sp_co_gia, sp_khong_gia], 'en'))
    print()
    print('=== cau_bang_gia_tat_ca — danh sách rỗng (vi) ===')
    print(cau_bang_gia_tat_ca([], 'vi'))
    print()

    k1 = KeyCuaKhach(ma_san_pham='dcabot', license_key='ABCD-1234', het_han='2026-12-31', con_han=True, nguon='web')
    k2 = KeyCuaKhach(ma_san_pham='copytrade', license_key='ZXCV-9999', het_han='2025-01-01', con_han=False, nguon='may_chu_key')
    k3 = KeyCuaKhach(ma_san_pham='tradingview', license_key='TV-0001', het_han='', con_han=True, nguon='may_chu_key')

    print('=== cau_key — có key (vi) ===')
    print(cau_key([k1, k2, k3], 'vi'))
    print()
    print('=== cau_key — có key (en) ===')
    print(cau_key([k1, k2, k3], 'en'))
    print()
    print('=== cau_key — rỗng, chưa đăng nhập (vi) ===')
    print(cau_key([], 'vi'))
    print()
    print('=== cau_key — rỗng, chưa đăng nhập (en) ===')
    print(cau_key([], 'en'))
    print()

    print('=== cau_khong_ro (vi) ===')
    print(cau_khong_ro('vi'))
    print()
    print('=== cau_khong_ro (en) ===')
    print(cau_khong_ro('en'))


def cau_hoi_san_pham(ngon_ngu: str = 'vi') -> str:
    """Câu HỎI LẠI khi khách hỏi cài đặt/lỗi mà chưa nói rõ sản phẩm nào.

    Chủ dự án: "phải hỏi họ trước về sản phẩm nào, sau đó mới hướng dẫn cài
    đặt riêng theo từng sản phẩm" — và "khi tư vấn khách hàng cần hỏi từng
    bước theo ngữ cảnh, ko trả lời cộc lốc 1 đống".

    Hai thứ cố ý nhét vào câu này:
      - LIỆT KÊ SẴN vài sản phẩm, để khách bấm/gõ một chữ là xong, không
        phải tự nghĩ ra tên đúng.
      - Nói trước rằng kẹt ở bước nào cứ nói, để khách biết đây là hội
        thoại nhiều lượt chứ không phải máy trả bài một phát rồi thôi.
    """
    if ngon_ngu == 'en':
        return (
            "Happy to help. Which product are you installing? "
            "SMART DCA EA, Copytrade, TradingView Bot, Signal Trader, "
            "Signal Broadcaster, Trade Panel, VipTrend Bot, or MT5 Manager?\n\n"
            "Tell me which one and I will walk you through that exact setup. "
            "If you are already part-way and something failed, just say which "
            "step — I will take it from there."
        )
    return (
        "Dạ em hỗ trợ ngay ạ. Anh/chị đang cài sản phẩm nào để em hướng dẫn "
        "đúng phần đó: SMART DCA EA, Copytrade, TradingView Bot, Signal Trader, "
        "Signal Broadcaster, Trade Panel, VipTrend Bot, hay MT5 Manager ạ?\n\n"
        "Anh/chị cho em biết tên sản phẩm, em gửi hướng dẫn riêng cho cái đó. "
        "Nếu đang cài dở mà gặp trục trặc thì anh/chị nói giúp em đang kẹt ở "
        "bước nào, em hướng dẫn tiếp từng bước cho tới khi chạy được ạ."
    )
