#!/usr/bin/env python3
"""(bản cho bài thương hiệu) Kiểm tra file nội dung: python3 validate.py [key ...]  (mặc định: tất cả *.json)"""
import json,sys,re,os,glob
here=os.path.dirname(os.path.abspath(__file__))
ICONS=set("laptop monitor cpu mainboard ram vga ssd hdd psu case cooler keyboard mouse mousepad headset speaker webcam chair desk router netcard nas printer software handheld camera ups accessory grid check bolt shield info star clock target link chat user doc".split())
BUNDLE={"monitor": ["mouse", "keyboard", "accessory", "vga"], "laptop": ["mouse", "headset", "ssd", "ram", "accessory"], "pc": ["monitor", "keyboard", "mouse", "ups"], "cpu": ["mainboard", "cooler", "ram", "psu"], "mainboard": ["cpu", "ram", "ssd", "case"], "ram": ["mainboard", "ssd", "cooler"], "vga": ["psu", "case", "monitor", "cooler"], "ssd": ["mainboard", "ram", "accessory"], "hdd": ["nas", "case", "accessory"], "psu": ["case", "vga", "ups"], "case": ["psu", "cooler", "mainboard"], "cooler": ["cpu", "case", "mainboard"], "keyboard": ["mouse", "mousepad", "headset"], "mouse": ["mousepad", "keyboard", "headset"], "mousepad": ["mouse", "keyboard"], "headset": ["webcam", "mouse", "keyboard"], "speaker": ["headset", "pc"], "webcam": ["headset", "monitor"], "chair": ["desk", "monitor", "keyboard"], "desk": ["chair", "monitor", "mousepad"], "router": ["netcard", "nas", "camera"], "netcard": ["router", "pc"], "printer": ["software", "ups"], "software": ["laptop", "pc"], "handheld": ["accessory", "ssd"], "camera": ["router", "nas", "ups"], "ups": ["pc", "router", "nas"], "nas": ["hdd", "router", "ups"], "accessory": ["laptop", "monitor"]}
BAD=['trả góp','dữ liệu được cung cấp','dữ kiện','không có thông tin','tốt nhất thế giới','số 1','#1','cam kết hoàn tiền','miễn phí','giảm giá','khuyến mãi','giá rẻ nhất','chắc chắn 100%']
def words(o):
    t=json.dumps(o,ensure_ascii=False); t=re.sub(r'"[a-z_]+":','',t); return len(re.findall(r'\w+',t))
def check(path):
    e=[]; key=os.path.basename(path)[:-5]
    try: d=json.load(open(path,encoding='utf-8'))
    except Exception as x: return ['JSON lỗi: %s'%x]
    for k in ['title','seo_title','meta_desc','intro','hero','chips','sections','quick','checklist','bundle','faq','conclusion']:
        if k not in d: e.append('thiếu '+k)
    if e: return e
    if not 35<=len(d['intro'].split())<=75: e.append('intro nên 35-75 từ (hiện %d)'%len(d['intro'].split()))
    if len(d['meta_desc'])>155 or len(d['meta_desc'])<90: e.append('meta_desc 90-155 ký tự (hiện %d)'%len(d['meta_desc']))
    if len(d['seo_title'])>62: e.append('seo_title <=62 ký tự (hiện %d)'%len(d['seo_title']))
    if len(d['chips'])!=3: e.append('chips phải đúng 3')
    types=[s.get('type','text') for s in d['sections']]
    for t in ['cards','compare','steps','callout','table']:
        if t not in types: e.append('thiếu khối '+t)
    if not 6<=len(d['sections'])<=8: e.append('sections 6-8 (hiện %d)'%len(d['sections']))
    kw=[w for w in d['title'].lower().split() if len(w)>=2]
    hit=sum(1 for s in d['sections'] if any(w in s['h2'].lower() for w in kw))
    if hit<3: e.append('cần >=3 h2 chứa từ khóa "%s"'%d['title'])
    for s in d['sections']:
        t=s.get('type','text')
        if len(s.get('p',''))>320: e.append('p quá dài ở "%s"'%s['h2'])
        if t=='cards':
            if len(s.get('cards',[]))!=4: e.append('cards phải đúng 4')
            for c in s.get('cards',[]):
                if c.get('ic') not in ICONS: e.append('icon lạ: %s'%c.get('ic'))
                if len(c.get('d','').split())>30: e.append('card dài: '+c.get('t',''))
        if t=='compare':
            if len(s.get('compare',[]))!=2: e.append('compare phải đúng 2')
            for c in s.get('compare',[]):
                if len(c.get('pts',[]))!=3: e.append('compare mỗi bên đúng 3 pts')
        if t=='steps' and len(s.get('steps',[]))!=4: e.append('steps phải đúng 4')
        if t=='callout' and not s.get('callout',{}).get('t'): e.append('callout thiếu')
        if t=='table':
            n=len(s.get('head',[]))
            if not 2<=n<=4 or not 3<=len(s.get('rows',[]))<=6 or any(len(r)!=n for r in s.get('rows',[])): e.append('table: 2-4 cột, 3-6 hàng, hàng đủ cột')
    if len(d['quick'])!=3: e.append('quick đúng 3')
    if not 5<=len(d['checklist'])<=6: e.append('checklist 5-6')
    if not 5<=len(d['faq'])<=6: e.append('faq 5-6')
    for f in d['faq']:
        if len(f['a'].split())>60: e.append('faq trả lời quá dài: '+f['q'])
    for b in d['bundle']:
        if b.get('key') not in BUNDLE.get(key,[]): e.append('bundle key không hợp lệ: %s'%b.get('key'))
    txt=json.dumps(d,ensure_ascii=False).lower()
    for b in BAD:
        if b in txt: e.append('cụm bị cấm: '+b)
    if re.search(r'\d[\d.,]*\s?(triệu|tr\b|₫|đ\b|vnđ|vnd)',txt): e.append('có giá tiền')
    w=words(d)
    if not 650<=w<=1500: e.append('tổng ~650-1500 từ (hiện %d)'%w)
    return e
files=[os.path.join(here,k+'.json') for k in sys.argv[1:]] or sorted([x for x in glob.glob(here+'/*.json') if not os.path.basename(x).startswith('_')])
bad=0
for f in files:
    er=check(f)
    print(('OK  ' if not er else 'LỖI ')+os.path.basename(f)+(' — '+'; '.join(er) if er else '')); bad+=bool(er)
sys.exit(1 if bad else 0)
