# -*- coding: utf-8 -*-
r"""B91: so giá dung môi 3 kỳ (29/09, 06/10, 13/10) -> (a) cập nhật 'bang_gia_nguyen_lieu .md' (backup trước),
(b) xuất Word 'BAO_CAO_TANG_GIAM_GIA_DUNG_MOI_13-10-2026.docx'."""
import os, re, shutil, sys, datetime
import pymupdf
from docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH

GOC = r'C:\Claw 2\Nghien cuu\Tinh-Gia-Thanh\GIA-NGUYEN-LIEU'
MD = os.path.join(GOC, 'bang_gia_nguyen_lieu .md')
DIR = os.path.join(GOC, '_mail_hang_1310')
WORD = os.path.join(GOC, 'BAO_CAO_TANG_GIAM_GIA_DUNG_MOI_13-10-2026.docx')
KY = [('29/09/26', os.path.join(DIR, 'ky_truoc', 'GIÁ DUNG MÔI 29.09.26.pdf')),
      ('06/10/26', os.path.join(DIR, 'ky_truoc', 'GIÁ DUNG MÔI 06.10.26.pdf')),
      ('13/10/26', os.path.join(DIR, 'GIÁ DUNG MÔI 13.10.26.pdf'))]
NUM = re.compile(r'\d{1,3}(?:[.,]\d{3})+|\b\d{4,6}\b')


def so(t):
    t = (t or '').strip()
    m = NUM.search(t)
    if not m:
        return None
    s = m.group(0)
    if re.match(r'^\d{1,3}([.,]\d{3})+$', s):
        return int(re.sub(r'[.,]', '', s))
    return int(s)


def loc(nums):
    """Bỏ các số không phải giá VNĐ/kg (ví dụ 0.835$ -> 835)."""
    return [x for x in nums if x and x >= 1000] or [None]


def doc_ky(p):
    d = pymupdf.open(p)
    pg = d[0]
    g = pg.find_tables().tables[0].extract()
    tieu_de = (g[0][0] or '').strip()
    ncc = [(c or '').strip() for c in g[1][3:]]
    ds, dang_ghi = [], []
    hang = g[2:]
    i = 0
    while i < len(hang):
        r = hang[i]
        ten = (r[1] or '').replace('\n', ' ').strip()
        dd = (r[2] or '').strip()
        if not ten and dd.startswith('*phuy'):   # dòng phụ của E.ACETATE
            i += 1
            if ds:
                nums = loc([so(x) for x in re.findall(r'\d{1,3}(?:[.,]\d{3})+|\b\d{4,6}\b', dd)]) if re.search(r'\d', dd) else [None]
                nhan = dd.replace('|', '\n').split('\n')[0].strip()
                ds[-1]['phu'].append((nhan, (nums or [None])[-1],
                                      [ (ncc[k], (r[3 + k] or '').strip(), so(r[3 + k])) for k in range(len(ncc)) if (r[3 + k] or '').strip() ]))
            continue
        if ten in ('Hiệu lực báo giá',) or ten.startswith('Ghi chú') or not ten:
            i += 1
            continue
        gia_ncc = []
        for k, n in enumerate(ncc):
            v = (r[3 + k] or '').strip() if 3 + k < len(r) else ''
            if v:
                gia_ncc.append((n, v.replace('\n', ' '), so(v)))
        ds.append({'stt': (r[0] or '').strip(), 'ten': ten, 'dd_raw': dd.replace('\n', ' | '),
                   'dd_nums': loc([so(x) for x in re.findall(r'\d{1,3}(?:[.,]\d{3})+|\b\d{4,6}\b', dd)]) if re.search(r'\d', dd) else [None],
                   'ncc': [(a, b, c) for a, b, c in gia_ncc], 'phu': []})
        i += 1
    hl = ''
    for r in hang:
        if (r[0] or '').strip().startswith('Hiệu lực'):
            hl = ' | '.join('%s: %s' % (a, b) for a, b in zip([''] + ncc, [(c or '').replace('\n', ' ').strip() for c in r[3:]]) if b)
    noi = ''
    for r in hang:
        for c in r:
            if c and 'Tỷ giá áp dụng' in c:
                noi = c.replace('\n', ' ')
    return {'tieu_de': tieu_de, 'ncc': ncc, 'items': ds, 'hieu_luc': hl, 'ghi_chu': noi}


cac_ky = {}
for ten_ky, p in KY:
    cac_ky[ten_ky] = doc_ky(p)
    print('  %s: %-38s %d mặt hàng | NCC: %s' % (ten_ky, cac_ky[ten_ky]['tieu_de'][:38], len(cac_ky[ten_ky]['items']), ', '.join(cac_ky[ten_ky]['ncc'])))

# gom theo tên hàng (chuẩn hoá)
def chuan(t):
    return re.sub(r'\s+', ' ', re.sub(r'[^a-z0-9 ]', ' ', t.lower())).strip()

theo_ten = {}
for ten_ky, d in cac_ky.items():
    for it in d['items']:
        theo_ten.setdefault(chuan(it['ten']), {'ten': it['ten'], 'ky': {}})[ 'ky'][ten_ky] = it

TANG, GIAM, KHONG = [], [], []
def them_so_sanh(ten_hien, av, bv, la_phu=False):
    """So 2 kỳ cho một dòng (kể cả dòng phụ phuy cũ/phuy mới). av/bv = int hoặc tuple."""
    ga = av[0] if isinstance(av, (tuple, list)) else av
    gb = bv[0] if isinstance(bv, (tuple, list)) else bv
    if ga is None or gb is None:
        return None
    if ga == gb:
        KHONG.append((ten_hien, ga, gb)); return None
    d_ = gb - ga
    (TANG if d_ > 0 else GIAM).append((ten_hien, ga, gb, d_, round(100.0 * d_ / ga, 1)))
    return d_


for k, v in sorted(theo_ten.items(), key=lambda x: (x[1]['ky'].get('13/10/26', {}).get('stt') or '99')):
    a = v['ky'].get('06/10/26')
    b = v['ky'].get('13/10/26')
    if not a or not b:
        continue
    them_so_sanh(v['ten'], (a['dd_nums'] or [None])[-1], (b['dd_nums'] or [None])[-1])
    # dòng phụ (E.ACETATE phuy cũ / phuy mới) — ghép theo thứ tự
    for i, ph in enumerate(b.get('phu', [])):
        if i < len(a.get('phu', [])):
            ten_phu = '%s — %s' % (v['ten'], re.sub(r'^\*', '', ph[0]))
            them_so_sanh(ten_phu, a['phu'][i][1], ph[1])

# mặt hàng ĐANG MUA (có giá đang sử dụng) nhưng kỳ này KHÔNG có báo giá mới từ NCC nào
KHONG_BAO_GIA = [(it['ten'], (it['dd_nums'] or [None])[-1]) for it in cac_ky['13/10/26']['items']
                 if not [x for x in it['ncc'] if x[2]]]
print()
print('  === GIÁ ĐANG SỬ DỤNG: kỳ 06/10 -> 13/10 (ĐVT: VNĐ/kg)')
print('  TĂNG (%d):' % len(TANG))
for t, a, b, d, p in sorted(TANG, key=lambda x: -x[3]):
    print('     %-28s %8s -> %8s  +%s  (+%s%%)' % (t, a, b, '{:,}'.format(d).replace(',', '.'), str(p).replace('.', ',')))
print('  GIẢM (%d):' % len(GIAM))
for t, a, b, d, p in sorted(GIAM, key=lambda x: x[3]):
    print('     %-28s %8s -> %8s  %s  (%s%%)' % (t, a, b, '{:,}'.format(d).replace(',', '.'), str(p).replace('.', ',')))
print('  KHÔNG ĐỔI (%d): %s' % (len(KHONG), ', '.join(t for t, a, b in KHONG)))

# ---------- (a) cập nhật MD ----------
if not os.path.exists(MD + '.bak_20261013'):
    shutil.copy2(MD, MD + '.bak_20261013')
else:                                    # chạy lại: phục hồi bản gốc để không nhân đôi mục
    shutil.copy2(MD + '.bak_20261013', MD)
s = open(MD, encoding='utf-8').read()
s = s.replace('**Cập nhật:** Đến ngày 10/09/26 (PO đặt hàng đến 14/09/2026)',
              '**Cập nhật:** Đến ngày 10/09/26 (PO đặt hàng đến 14/09/2026) · **Bổ sung giá dung môi tuần 13/10/2026** (Phòng Vật tư – Nguyễn Thị Thúy Hằng, mail 13/10/2026)')
s = re.split(r'\n## GIÁ DUNG MÔI THEO TUẦN \(Phòng Vật tư báo giá\)\n', s)[0]
sec = []
sec.append('\n## GIÁ DUNG MÔI THEO TUẦN (Phòng Vật tư báo giá)\n')
sec.append('### Kỳ 13/10/2026 — báo giá ngày 13/10/2026\n')
sec.append('| STT | Tên hàng | Giá đang sử dụng (VNĐ/kg) | Giá tốt nhất kỳ này | Nhà cung cấp | Hiệu lực | Ghi chú NCC |')
sec.append('|----:|---------|--------------------------:|-------------------:|--------------|---------|-------------|')
for it in cac_ky['13/10/26']['items']:
    dd = ' / '.join('{:,}'.format(x).replace(',', '.') for x in it['dd_nums'] if x) or it['dd_raw']
    ncc = [x for x in it['ncc'] if x[2]]
    if ncc:
        m = min(ncc, key=lambda x: x[2])
        gia, nha = '{:,}'.format(m[2]).replace(',', '.'), m[0]
        note = ' · '.join('%s %s' % (a, b) for a, b, c in ncc if c != m[2])[:150]
    else:
        gia, nha, note = '', '', ''
    sec.append('| %s | %s | %s | %s | %s | | %s |' % (it['stt'], it['ten'], dd, gia, nha, note))
    for phu_ten, phu_so, phu_ncc in it['phu']:
        n2 = [x for x in phu_ncc if x[2]]
        if n2:
            m2 = min(n2, key=lambda x: x[2])
            sec.append('|  | %s | %s | %s | %s | | |' % (re.sub(r'^\*', '', phu_ten), '{:,}'.format(phu_so).replace(',', '.') if phu_so else '', '{:,}'.format(m2[2]).replace(',', '.'), m2[0]))
sec.append('')
sec.append('**Tỷ giá áp dụng:** 26.500 · **Hiệu lực báo giá:** %s' % cac_ky['13/10/26']['hieu_luc'])
sec.append('')
sec.append('**Ghi chú của Phòng Vật tư (13/10/2026):** %s' % cac_ky['13/10/26']['ghi_chu'])
sec.append('')
sec.append('### Biến động giá kỳ 13/10/26 so với 06/10/26 (tóm tắt)\n')
sec.append('| Mặt hàng | Giá đang dùng 06/10/26 | Giá đang dùng 13/10/26 | Chênh lệch | % |')
sec.append('|---------|----------------------:|----------------------:|---:|--:|')
for t, a, b, d, p in sorted(TANG, key=lambda x: -x[3]) + sorted(GIAM, key=lambda x: x[3]):
    sec.append('| %s | %s | %s | %s%s | %s |' % (t, '{:,}'.format(a).replace(',', '.'), '{:,}'.format(b).replace(',', '.'),
               '+' if d > 0 else '-', '{:,}'.format(abs(d)).replace(',', '.'), str(p).replace('.', ',')))
if KHONG:
    sec.append('| | | | | |')
    sec.append('| **Không đổi (%d mặt hàng)** | %s | | | |' % (len(KHONG), ', '.join(t for t, a, b in KHONG)))
sec.append('')
s2 = s.rstrip('\r\n') + '\n' + '\n'.join(sec) + '\n'
open(MD, 'w', encoding='utf-8', newline='').write(s2)
print()
print('  MD: %d -> %d ký tự (thêm %d) | backup: %s' % (len(s), len(s2), len(s2) - len(s), os.path.basename(MD) + '.bak_20261013'))

# ---------- (b) Word ----------
d = Document()
d.styles['Normal'].font.name = 'Calibri'
d.styles['Normal'].font.size = Pt(10.5)
for sec_ in d.sections:
    sec_.left_margin = sec_.right_margin = Cm(1.4)
p = d.add_paragraph(); r = p.add_run('BÁO CÁO TĂNG GIẢM GIÁ DUNG MÔI — KỲ 13/10/2026'); r.bold = True; r.font.size = Pt(14)
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
for t in ['Nguồn: bảng báo giá dung môi của Phòng Vật tư (Nguyễn Thị Thúy Hằng) — mail ngày 13/10/2026, đối chiếu 2 kỳ trước (06/10/2026 và 29/09/2026)',
          'Phạm vi: 30 mặt hàng dung môi; cột “Giá đang sử dụng” = giá Công ty đang mua/đang áp dụng · ĐVT: VNĐ/kg (chưa VAT) · Tỷ giá áp dụng 26.500 · Hiệu lực báo giá 10 ngày']:
    q = d.add_paragraph(t); q.alignment = WD_ALIGN_PARAGRAPH.CENTER
    for rr in q.runs:
        rr.italic = True; rr.font.size = Pt(9)

def hh(t):
    x = d.add_paragraph(); rr = x.add_run(t); rr.bold = True; rr.font.size = Pt(12)

hh('1. Kết quả chung')
d.add_paragraph('- Số mặt hàng TĂNG giá (theo cột “Giá đang sử dụng”): %d' % len(TANG), style='List Bullet')
d.add_paragraph('- Số mặt hàng GIẢM giá: %d' % len(GIAM), style='List Bullet')
d.add_paragraph('- Số mặt hàng KHÔNG ĐỔI: %d' % len(KHONG), style='List Bullet')
if TANG:
    tb = max(TANG, key=lambda x: x[3])
    d.add_paragraph('- Tăng mạnh nhất: %s (+%s VNĐ/kg, %s%%)' % (tb[0], '{:,}'.format(tb[3]).replace(',', '.'), str(tb[4]).replace('.', ',')), style='List Bullet')
if GIAM:
    tg = min(GIAM, key=lambda x: x[3])
    d.add_paragraph('- Giảm mạnh nhất: %s (%s VNĐ/kg, %s%%)' % (tg[0], '{:,}'.format(tg[3]).replace(',', '.'), str(tg[4]).replace('.', ',')), style='List Bullet')

hh('2. Chi tiết theo mặt hàng (giá đang sử dụng kỳ 06/10 → 13/10)')
d.add_paragraph('- Giá dùng để so là giá CÔNG TY ĐANG MUA (cột “Giá đang sử dụng”); nếu một kỳ có 2 số (giá cũ/giá mới) thì lấy số MỚI NHẤT.')
tb = d.add_table(rows=1, cols=7); tb.style = 'Table Grid'
for i, t in enumerate(['Mặt hàng', 'Giá 29/09/26', 'Giá 06/10/26', 'Giá 13/10/26', 'Chênh lệch', '%', 'Đánh giá']):
    c = tb.rows[0].cells[i]; c.text = t
    for rr in c.paragraphs[0].runs:
        rr.bold = True; rr.font.size = Pt(9)
for t, a, b, dd_, pct in sorted(TANG, key=lambda x: -x[3]) + sorted(KHONG and [] or [], key=lambda x: 0) + sorted(GIAM, key=lambda x: x[3]):
    g29 = None if ' — ' in t else theo_ten.get(chuan(t.split(' — ')[0]), {}).get('ky', {}).get('29/09/26')
    g29v = (g29['dd_nums'] or [None])[-1] if g29 else None
    row = tb.add_row().cells
    for i, v in enumerate([t, '{:,}'.format(g29v).replace(',', '.') if g29v else '—', '{:,}'.format(a).replace(',', '.'),
                           '{:,}'.format(b).replace(',', '.'), ('+' if dd_ > 0 else '-') + '{:,}'.format(abs(dd_)).replace(',', '.'),
                           str(pct).replace('.', ',') + '%', 'TĂNG' if dd_ > 0 else 'GIẢM']):
        row[i].text = v
        for rr in row[i].paragraphs[0].runs:
            rr.font.size = Pt(9)
            if i == 6:
                rr.bold = True
                rr.font.color.rgb = RGBColor(0xC0, 0x00, 0x00) if dd_ > 0 else RGBColor(0x00, 0x70, 0x30)
for t, a, b in KHONG:
    g29 = theo_ten.get(chuan(t), {}).get('ky', {}).get('29/09/26')
    g29v = (g29['dd_nums'] or [None])[-1] if g29 else None
    row = tb.add_row().cells
    for i, v in enumerate([t, '{:,}'.format(g29v).replace(',', '.') if g29v else '—', '{:,}'.format(a).replace(',', '.') if a else '—',
                           '{:,}'.format(b).replace(',', '.') if b else '—', '0', '0%', 'KHÔNG ĐỔI']):
        row[i].text = v
        for rr in row[i].paragraphs[0].runs:
            rr.font.size = Pt(9)

hh('3. Giá báo tốt nhất kỳ 13/10/2026 (rẻ nhất trong các nhà cung cấp)')
tb2 = d.add_table(rows=1, cols=5); tb2.style = 'Table Grid'
for i, t in enumerate(['Mặt hàng', 'Giá đang dùng', 'Giá tốt nhất', 'Nhà cung cấp', 'Các NCC khác cùng kỳ']):
    c = tb2.rows[0].cells[i]; c.text = t
    for rr in c.paragraphs[0].runs:
        rr.bold = True; rr.font.size = Pt(9)
for it in cac_ky['13/10/26']['items']:
    n2 = [x for x in it['ncc'] if x[2]]
    if not n2:
        continue
    m = min(n2, key=lambda x: x[2])
    row = tb2.add_row().cells
    vals = [it['ten'], '{:,}'.format((it['dd_nums'] or [None])[-1]).replace(',', '.') if (it['dd_nums'] or [None])[-1] else '—',
            '{:,}'.format(m[2]).replace(',', '.'), m[0], '; '.join('%s %s' % (a, b) for a, b, c in n2 if c != m[2])[:120]]
    for i, v in enumerate(vals):
        row[i].text = v
        for rr in row[i].paragraphs[0].runs:
            rr.font.size = Pt(9)

hh('4. Ghi chú của Phòng Vật tư & khuyến nghị theo dõi')
d.add_paragraph(cac_ky['13/10/26']['ghi_chu'])
for t in ['SBAC đã hết tồn kho (từ 22/08/2026) — chuyển ngang qua NBAC',
          'MEK giá cao — thay thế bằng Acetone (chỉ đạo 05/09/2026)',
          'BCS giá cao — báo R&D tính toán thay thế (12/09/2026)',
          'Methanol: Phòng Vật tư thông báo hết hàng, NGỪNG MUA (02/10/2026)',
          'KRT 100 + PMA EEP và E.ACETATE có giá riêng cho phuy cũ / phuy mới; giá “làm cứng” phải cộng thêm tiền phuy (Top, Samchem, Kaiser, Thiên Nghĩa, DVL 1.200/kg; Petro 1.500/kg; Brenntag, Gia Anh 1.000/kg; Vân Long 1.300/kg)']:
    d.add_paragraph(t, style='List Bullet')
p = d.add_paragraph()
hh('5. Mặt hàng Công ty ĐANG MUA nhưng kỳ này không có báo giá mới từ nhà cung cấp')
d.add_paragraph('- %d mặt hàng: %s' % (len(KHONG_BAO_GIA), ', '.join('%s (%s)' % (t, '{:,}'.format(v).replace(',', '.') if v else '—') for t, v in KHONG_BAO_GIA)))
d.add_paragraph('- Nghĩa là giá đang áp dụng vẫn giữ như kỳ trước, chưa có giá chào mới để đối chiếu — đề nghị Phòng Vật tư bổ sung ở kỳ sau.')
p = d.add_paragraph()
p.add_run('Ghi chú kỹ thuật: bảng này lập tự động từ 3 file PDF báo giá dung môi (29/09, 06/10, 13/10/2026); số liệu bóc trực tiếp từ bảng PDF, không sửa tay. Giá tốt nhất chỉ là giá chào — cần đối chiếu số lượng đặt (p = phuy) và hiệu lực báo giá trước khi chốt PO.').italic = True
d.save(WORD)
print('  Word: %s (%d B, %d đoạn, %d bảng)' % (os.path.basename(WORD), os.path.getsize(WORD), len(d.paragraphs), len(d.tables)))
