# -*- coding: utf-8 -*-
import openpyxl, time, json, re, ssl, urllib.request, sys
from urllib.parse import urlparse
from bs4 import BeautifulSoup
ctx=ssl.create_default_context();ctx.check_hostname=False;ctx.verify_mode=ssl.CERT_NONE
HDR={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/124 Safari/537.36'}
def fetch(u): return urllib.request.urlopen(urllib.request.Request(u,headers=HDR),timeout=25,context=ctx).read()
UI=re.compile(r'banner|/common/|icon|btn|logo|bullet|sprite|blank|no_img|arrow|/dot|/bg|popup|/sns|/mark|webwatch',re.I)
DIAG=re.compile(r'조직도|체계도|순서도|흐름도|구성도|개념도|체계$|절차도|로드맵|추진체계|다이어그램|한눈|chart|graph|플랫폼\s*구축|구성$')

ws=openpyxl.load_workbook('한국중부발전.xlsx').active
rows=[]
for r in range(3,ws.max_row+1):
    if all(ws.cell(r,c).value in (None,'') for c in range(2,16)): continue
    rows.append((r,ws.cell(r,2).value,ws.cell(r,11).value,ws.cell(r,12).value,ws.cell(r,13).value,ws.cell(r,14).value))
out=[]
for (r,b,K,L,M,N) in rows:
    if not K or 'komipo.co.kr' not in str(K):  # 사이트/외부
        continue
    try: soup=BeautifulSoup(fetch(str(K)),'html.parser')
    except Exception as e: out.append((r,b,'FETCHERR',L,M,N,str(e)[:30])); time.sleep(0.4); continue
    isboard='/board/' in str(K) and ('boardMain' in str(K) or 'boardList' in str(K))
    isfr='/fr/' in str(K)
    rL=rM=rN=None
    if isboard or isfr:
        em=soup.select_one('div.total em.count') or soup.select_one('.total .count')
        rM=int(re.sub(r'[^0-9]','',em.get_text())) if em else 0
        rL='게시판'
        cont=soup.select_one('#content') or soup
        thumbs=[im for im in cont.find_all('img') if 'getImage' in im.get('src','') and not UI.search(im.get('src',''))]
        rN='없음' if rM==0 else ('어문,이미지' if thumbs else '어문')
    else:
        # in-page tabs?
        ntab=0
        for ul in soup.find_all('ul'):
            cls=' '.join(ul.get('class') or [])
            if 'tab' in cls and 'tab_link' not in cls:
                tt=[li for li in ul.find_all('li',recursive=False) if li.find('a') and (li.find('a').get('data-tab') or (li.find('a').get('href','') or '').startswith('#'))]
                if len(tt)>=2: ntab=max(ntab,len(tt))
        rL='페이지'; rM=ntab if ntab>=2 else 1
        cont=soup.select_one('#content') or soup.select_one('div.contents')
        real=[]
        if cont:
            for im in cont.find_all('img'):
                src=im.get('src','');alt=im.get('alt','')
                if UI.search(src): continue
                if 'getImage' in src and ('코로나' in alt or '정규직' in alt): continue
                real.append((src,alt))
        diag_only=real and all(DIAG.search(a or '') for s,a in real)
        rN='어문,이미지' if (real and not diag_only) else '어문'
    # compare (normalize trailing spaces)
    sN=(N or '').strip()
    flags=[]
    if rL!=(L or '').strip(): flags.append('L:%s!=%s'%(L,rL))
    if rM!=M: flags.append('M:%s!=%s'%(M,rM))
    if rN!=sN: flags.append('N:%s!=%s'%(sN,rN))
    if flags:
        out.append((r,b,'DIFF',L,M,sN,rL,rM,rN,' '.join(flags),str(K)[:46],[a or s.split('/')[-1] for s,a in (real if not (isboard or isfr) else [])][:4]))
    time.sleep(0.55)
json.dump(out,open('recheck.json','w',encoding='utf-8'),ensure_ascii=False,indent=1,default=str)
print('대조 mismatch:',len([x for x in out if x[2]=='DIFF']),'/ fetch err:',len([x for x in out if x[2]=='FETCHERR']))
for x in out:
    if x[2]=='DIFF':
        print(f'r{x[0]} b{x[1]} [{x[9]}] {x[10]} {x[11]}')
    else:
        print(f'r{x[0]} b{x[1]} FETCHERR {x[6]}')
