#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""盘点「产品资料（说明书/COA/MSDS）」目录，并与知识库缺口对账。

只读目录（不解压、不物化），产出一份对账报告：
  · 各子目录文件数
  · 说明书按货号前缀归类
  · 与核心货号/缺说明书货号的重叠
"""
import json
import os
import re
from collections import Counter

W = '/Users/liuxinyuan/Desktop/Hermes输出-工作类'
BASE = ('/Users/liuxinyuan/Desktop/hermas输入-工作台数据库/宝锐产品资料/'
        '宝锐产品资料（说明书、COA、MSDS）/2026_10_12_01 成品COA【QA维护】')


def walk(d):
    out = []
    for root, _, files in os.walk(d):
        for f in files:
            if f.startswith('.'):
                continue
            out.append(os.path.join(root, f))
    return out


def main():
    print('=== 各子目录 ===')
    trees = {}
    for sub in sorted(os.listdir(BASE)):
        p = os.path.join(BASE, sub)
        if os.path.isdir(p):
            fs = walk(p)
            trees[sub] = fs
            print('  %-28s %5d 个文件' % (sub, len(fs)))
    # 说明书
    man = [f for k, v in trees.items() if '产品说明书' in k for f in v]
    coa = [f for k, v in trees.items() if 'COA' in k for f in v]
    msds = [f for k, v in trees.items() if 'MSDS' in k for f in v]
    print('\n说明书 %d ｜ COA %d ｜ MSDS %d ｜ 验证资料 %d' % (
        len(man), len(coa), len(msds), sum(len(v) for k, v in trees.items() if '验证' in k)))

    # 说明书按货号前缀
    pref = Counter()
    for f in man:
        b = os.path.basename(f)
        m = re.match(r'^(?:说明书[-_])?([A-Z]{1,4})', b)
        pref[m.group(1) if m else '(其他)'] += 1
    print('\n=== 说明书货号前缀 TOP20 ===')
    for k, v in pref.most_common(20):
        print('   %-8s %4d' % (k, v))

    # 与知识库缺口对账
    d = json.load(open(os.path.join(W, '数据/diag_knowledge.json'), encoding='utf-8'))
    items = d['items']
    need = [r for r in items if not r.get('说明书本地文件')]
    print('\n=== 缺本地说明书的核心货号 %d 个，逐个查这批目录 ===' %
          len(need))
    hit = []
    for r in need:
        sku = r['货号']
        loose = re.sub(r'[^A-Z0-9]', '', sku)
        found = [f for f in man if loose and loose in re.sub(r'[^A-Z0-9]', '', os.path.basename(f).upper())]
        if found:
            hit.append((sku, r.get('品名') or '(无品名)', [os.path.basename(x) for x in found[:2]]))
    print('  命中 %d / %d' % (len(hit), len(need)))
    for sku, nm, fs in hit[:30]:
        print('   ✅ %-20s %-34s → %s' % (sku, nm[:34], fs))
    miss = [r['货号'] for r in need if r['货号'] not in {h[0] for h in hit}]
    print('\n  仍未命中 %d 个: %s' % (len(miss), miss[:25]))

    json.dump({'说明书画': len(man), 'COA': len(coa), 'MSDS': len(msds),
               '命中补件': [{'货号': a, '品名': b, '文件': c} for a, b, c in hit],
               '未命中': miss},
              open(os.path.join(W, '数据/产品资料目录对账.json'), 'w', encoding='utf-8'),
              ensure_ascii=False, indent=1)
    print('\n→ 数据/产品资料目录对账.json')


if __name__ == '__main__':
    main()
