# -*- coding: utf-8 -*-
"""Dựng gói kiến thức 3 kho cho Agent-Lab: CSDL A (quy trình) + B (màu) + D (vật liệu & yêu cầu chất lượng)."""
import os, re, sqlite3, sys, hashlib, json

A = r'C:\Claw 2\Nghien cuu\Du-an-A-Quy-trinh-son\CSDLA.db'
B = r'C:\Claw 2\Nghien cuu\Du-an-B-He-mau-Stain-Glaze\CSDLB.db'
D = r'C:\Claw 2\Nghien cuu\Du-an-D-Ho-so-vat-lieu\CSDLD.db'
OUT_DIR = r'C:\Claw 2\Nghien cuu\Agent-Lab\kien_thuc'
os.makedirs(OUT_DIR, exist_ok=True)
OUT = os.path.join(OUT_DIR, 'CSDL_KIEN_THUC_ABC.md')


def ro(db):
    return sqlite3.connect('file:' + db + '?mode=ro', uri=True).cursor()


def gon(s, n=400):
    s = '' if s is None else str(s)
    s = re.sub(r'\s+', ' ', s).strip()
    return s if len(s) <= n else s[:n - 1] + '…'


L = []
W = L.append
ca, cb, cd = ro(A), ro(B), ro(D)

W('# GÓI KIẾN THỨC NỘI BỘ — 3 KHO (A: QUY TRÌNH · B: MÀU · D: VẬT LIỆU & YÊU CẦU CHẤT LƯỢNG)')
W('')
W('*Gói này do hệ thống nội bộ dựng tự động từ CSDL A + B + D. Dùng để: (1) phân tích ảnh gỗ mộc + mẫu màu; (2) chọn bước xử lý theo loài gỗ/đặc tính; (3) lên tối đa 2 phương án quy trình và công thức pha màu cho từng công đoạn phủ sơn.*')
W('')

# ---------- A1: luật ----------
W('## PHẦN A1 — %d LUẬT KINH NGHIỆM (bắt buộc tuân thủ)' % cd.execute('SELECT COUNT(*) FROM huan_luyen').fetchone() if False else '## PHẦN A1 — LUẬT KINH NGHIỆM (bắt buộc tuân thủ)')
for i, r in enumerate(ca.execute('SELECT id,nhom,quy_tac,pham_vi FROM huan_luyen ORDER BY id').fetchall(), 1):
    W('%d. **[%s]** %s%s' % (i, r[1] or 'khác', gon(r[2], 700), ('  *(phạm vi: %s)*' % gon(r[3], 120)) if r[3] else ''))
W('')

# ---------- A2: 34 bước chuẩn ----------
W('## PHẦN A2 — BỘ 34 BƯỚC CHUẨN (chỉ dùng SỐ BƯỚC + TÊN CHUẨN khi mô tả quy trình)')
for r in ca.execute('SELECT so,ten_vi,dinh_nghia_vi FROM buoc_chuan ORDER BY so').fetchall():
    W('- **%s. %s** — %s' % (r[0], r[1], gon(r[2], 220)))
W('')

# ---------- A3: quy trình chuẩn hay dùng ----------
W('## PHẦN A3 — QUY TRÌNH CHUẨN THAM CHIẾU')
for qt in ca.execute("SELECT id,ten,loai,he_son,so_buoc,mo_ta FROM quy_trinh WHERE id IN (112,116,118) ORDER BY id").fetchall():
    W('### QT %s — %s (%s · %s · %s bước)' % (qt[0], qt[1], qt[2] or '', qt[3] or '', qt[4]))
    if qt[5]:
        W('*%s*' % gon(qt[5], 300))
    for b in ca.execute('SELECT thu_tu,buoc_nguyen_van,buoc_chuan_so,ghi_chu FROM buoc_quy_trinh WHERE quy_trinh_id=? ORDER BY thu_tu', (qt[0],)).fetchall():
        so = ('[bước %s]' % b[2]) if b[2] else '[chưa map]'
        W('  %s %s %s' % (b[0], so, gon(b[1], 200)))
    W('')

# ---------- B1: danh mục màu ----------
W('## PHẦN B1 — DANH MỤC MÀU CSDL B (%d mã; chỉ dùng mã CÓ trong danh mục này)' % cb.execute('SELECT COUNT(*) FROM mau').fetchone()[0])
W('| Tên màu | Mã | Phân loại | Hãng | Tồn (kg) | Bền sáng | Đánh giá |')
W('|---|---|---|---|---|---|---|')
for r in cb.execute('SELECT ten,ma,phan_loai,hang_ncc,ton_kg,ben_sang,danh_gia FROM mau ORDER BY nhom,ten').fetchall():
    W('| %s | %s | %s | %s | %s | %s | %s |' % tuple([gon(x, 60) or '' for x in r]))
W('')

# ---------- B2: bảng màu đã đo ----------
W('## PHẦN B2 — %d Ô MÀU ĐÃ ĐO (L*a*b* · hex; số đọc từ ẢNH mẫu, KHÔNG phải máy đo màu — dùng làm tham chiếu, phải làm thẻ mẫu xác nhận)'
  % cb.execute('SELECT COUNT(*) FROM mau_bang_in').fetchone()[0])
W('| Mã màu (nguyên văn) | Nồng độ | L* | a* | b* | hex | Tin cậy |')
W('|---|---|---|---|---|---|---|')
for r in cb.execute("SELECT COALESCE(NULLIF(nhan_goc,''), ma_mau), COALESCE(nong_do,''), L_star,a_star,b_star,hex,do_tin_cay "
                    "FROM mau_bang_in ORDER BY (mau_id IS NULL), nhom, ma_mau").fetchall():
    W('| %s | %s | %s | %s | %s | %s | %s |' % tuple([gon(x, 40) or '' for x in r]))
W('')

# ---------- D: vật liệu & yêu cầu chất lượng ----------
W('## PHẦN D1 — HỒ SƠ %d LOÀI/NỀN GỖ (đặc tính ảnh hưởng màu & quy trình)' % cd.execute('SELECT COUNT(*) FROM loai_go').fetchone()[0])
W('| Loài/nền | Mạch gỗ | Dầu–nhựa | Tanin | Hút màu | Loang đốm | Ngả vàng | Độ cứng | Vấn đề khi sơn | Khuyến nghị | Tin cậy |')
W('|---|---|---|---|---|---|---|---|---|---|---|')
for r in cd.execute('SELECT ten_vn,mach_go,dau_nhua,tanin_axit,do_hut_mau,nguy_co_loang,nguy_co_nga_vang,do_cung,van_de_khi_son,khuyen_nghi,do_tin_cay FROM loai_go ORDER BY id').fetchall():
    W('| %s |' % ' | '.join([gon(x, 150) or '' for x in r]) + '')
W('')

W('## PHẦN D2 — MAP %d NHÓM NỀN → BƯỚC BẮT BUỘC / NÊN CÓ / PHẢI TRÁNH (theo số bước ở Phần A2)'
  % cd.execute('SELECT COUNT(*) FROM map_buoc_quy_trinh').fetchone()[0])
W('| Nhóm nền | Bắt buộc | Nên có | Phải tránh | Ghi chú |')
W('|---|---|---|---|---|')
for r in cd.execute('SELECT nhom_nen,buoc_bat_buoc,buoc_nen_co,buoc_tranh,ghi_chu FROM map_buoc_quy_trinh ORDER BY id').fetchall():
    W('| %s |' % ' | '.join([gon(x, 220) or '' for x in r]) + '')
W('')

W('## PHẦN D3 — YÊU CẦU CHẤT LƯỢNG → HỆ SƠN & QUY TRÌNH')
W('| Yêu cầu | Ngưỡng đo | Hệ sơn phù hợp | Số lớp tối thiểu | Bước bắt buộc | Cảnh báo |')
W('|---|---|---|---|---|---|')
for r in cd.execute('SELECT yeu_cau,nguong_do,he_son_phu_hop,so_lop_toi_thieu,buoc_bat_buoc,han_che_canh_bao FROM yeu_cau_chat_luong ORDER BY id').fetchall():
    W('| %s |' % ' | '.join([gon(x, 200) or '' for x in r]) + '')
W('')

W('## PHẦN D4 — HIỆU CHỈNH THEO ĐỘ HÚT MÀU CỦA GỖ')
for r in cd.execute('SELECT muc_hut_mau,vi_du_loai,cach_hieu_chinh_nong_do,thoi_gian_luu_lau,so_lan_phu,buoc_chan_truoc,cach_bu FROM hieu_chinh_theo_do_hut_mau ORDER BY id').fetchall():
    W('- **%s** (ví dụ: %s) → %s · lưu–lau: %s · số lần phủ: %s · bước chặn trước: %s · cách bù khi lệch: %s'
      % tuple([gon(x, 260) or '—' for x in r]))
W('')

W('## PHẦN D5 — %d YẾU TỐ ẢNH HƯỞNG MÀU & QUY TRÌNH' % cd.execute('SELECT COUNT(*) FROM yeu_to_anh_huong').fetchone()[0])
for r in cd.execute('SELECT yeu_to,anh_huong_mau,anh_huong_quy_trinh,cach_xu_ly FROM yeu_to_anh_huong ORDER BY id').fetchall():
    W('- **%s** → màu: %s | quy trình: %s | xử lý: %s' % tuple([gon(x, 300) or '—' for x in r]))
W('')

W('## PHẦN D6 — 3 VIỆC ỔN ĐỊNH MÀU NHẤT · 3 SAI LẦM LÀM TÍNH TOÁN VÔ NGHĨA')
for r in cd.execute('SELECT nhom,noi_dung,ly_do FROM luu_y_van_hanh ORDER BY id').fetchall():
    W('- *(%s)* %s — %s' % (gon(r[0], 40), gon(r[1], 300), gon(r[2], 200)))
W('')

W('## PHẦN D7 — ĐIỀU KIỆN CHỤP ẢNH ĐỂ AI ĐỌC MÀU ĐÚNG (nhắc Lab khi ảnh không đạt)')
for r in cd.execute('SELECT hang_muc,yeu_cau,cach_kiem_tra FROM huong_dan_chup_anh ORDER BY id').fetchall():
    W('- **%s**: %s — kiểm tra: %s' % tuple([gon(x, 200) or '—' for x in r]))
W('')

# ---------- Hợp đồng đầu ra ----------
W('## PHẦN E — HỢP ĐỒNG ĐẦU RA BẮT BUỘC (áp cho mọi câu trả lời quy trình/công thức)')
for t in [
    'Trả **tối đa 2 phương án**; **PA1 = khuyến nghị**, PA2 = thay thế (nêu rõ vì sao khác nhau).',
    'Bảng quy trình **chỉ gồm các công đoạn PHỦ SƠN**, gọn (≤ 2 trang A4), **KHÔNG ghi tên thương mại/mã sản phẩm trong bảng** — mã/tỉ lệ để ở phần công thức pha màu tách riêng.',
    'Bảng quy trình **mỗi dòng 1 công đoạn**, cột: *Công đoạn (số bước chuẩn + tên chuẩn) | Mục đích | Cách làm (phun/lau/nhúng/pad/…) | Định lượng nếu có | Khô/chờ* .',
    '**Sau MỖI lần chà nhám phải có dòng: “KIỂM TRA MÀU – DẶM MÀU NẾU LÁC”.**',
    'Công thức pha màu: **bảng riêng cho TỪNG công đoạn có màu**, mỗi dòng *mã · tỉ lệ % · vai trò trong màu*; ghi thứ tự cho nguyên liệu vào, thời gian khuấy, yêu cầu lọc.',
    'Ưu tiên **DYE** cho stain/nhuộm (stain chủ yếu là dye); pigment chỉ dùng lượng nhỏ siêu mịn (kìm rực/làm đều) hoặc cho lớp lót phủ màu.',
    'Phân loại màu theo **4 nhóm: không màu / có màu (pigment) / màu trong suốt / loại khác** — KHÔNG ghi hệ NC/PU/nước/UV/2K trong phần phân loại màu.',
    '**Màu chiều sâu (luật #20):** lớp dưới đậm hơn lớp trên; pad stain/glaze đi **tối → sáng**.',
    '**Lau màu tạo highlight (luật #28):** bạt màu vùng cần sáng; **cấm** hướng dẫn “lau đều theo chiều thớ”.',
    'Chỉ nêu **mã nguyên liệu có tồn kho**; mã không có trong danh mục/tồn kho thì ghi rõ *“không có tồn kho — phải chọn mã thay thế”* + đề xuất mã thay thế cùng loại màu.',
    'Kết thúc bằng mục **“CẦN LÀM THẺ MẪU XÁC NHẬN”**: các ô thử (nồng độ/ số lớp), tiêu chí đạt (độ bóng GU, màu so mẫu, bám dính), và những gì **không thể kết luận từ ảnh** (độ bóng thật, độ thấm, độ ẩm gỗ…).',
    'Nếu **thiếu ảnh gỗ mộc**: ghi rõ *“THIẾU ẢNH GỖ MỘC — đề nghị cung cấp”* hoặc nêu **giả định màu gỗ tự nhiên của loài** (nói rõ loài + tông giả định).',
]:
    W('- ' + t)

text = '\n'.join(L)
open(OUT, 'w', encoding='utf-8').write(text)
h = hashlib.md5(text.encode('utf-8')).hexdigest()[:12]
open(os.path.join(OUT_DIR, 'goi_kien_thuc.json'), 'w', encoding='utf-8').write(json.dumps(
    {'file': OUT, 'ky_tu': len(text), 'dong': text.count('\n') + 1, 'md5_12': h,
     'nguon': [A, B, D]}, ensure_ascii=False, indent=1))
print('ĐÃ DỰNG GÓI KIẾN THỨC:', OUT)
print('   %d ký tự · %d dòng · md5(12)=%s' % (len(text), text.count('\n') + 1, h))
print('   A: luật %d · bước %d · QT112/116/118' % (
    ca.execute('SELECT COUNT(*) FROM huan_luyen').fetchone()[0], ca.execute('SELECT COUNT(*) FROM buoc_chuan').fetchone()[0]))
print('   B: màu %d · ô đo %d' % (cb.execute('SELECT COUNT(*) FROM mau').fetchone()[0], cb.execute('SELECT COUNT(*) FROM mau_bang_in').fetchone()[0]))
print('   D: loài %d · map %d · yêu cầu CL %d · yếu tố %d · chụp ảnh %d' % tuple(
    cd.execute('SELECT COUNT(*) FROM %s' % t).fetchone()[0] for t in ('loai_go', 'map_buoc_quy_trinh', 'yeu_cau_chat_luong', 'yeu_to_anh_huong', 'huong_dan_chup_anh')))
