# -*- coding: utf-8 -*-
"""미검수 기관 새창열림(target=_blank)→사이트 일괄 (사용자룰 2026-06-04).
각 사이트 GNB/메뉴(홈+샘플 콘텐츠페이지)에서 target=_blank 앵커 수집.
같은 정규화URL에서 _blank 우세(blank수>=일반수)인 것만 '사이트'(내부보드 배너 _blank 오탐 방지).
xlsx의 그 URL 행(현재 페이지/게시판) → L=사이트, M·N 비움.

사용: python -X utf8 _재검수_blanksite.py <기관...> [--write]
"""
import sys, os, re, shutil, importlib.util
from collections import Counter
from urllib.parse import urljoin, urldefrag, urlparse
import openpyxl

# 실게시판 보호: 게시판 엔드포인트 URL이면서 현재 L=게시판이면 사이트로 안 뒤집음
BOARD_URL = re.compile(r'selectBbsNttList|/bbs/|BBSMSTR|board/list|list\.buan|selectBoardList|selectCntrct|selectPric|/list\.do|nttList|selectEminwonNoticeList|selectInhAuthPgmList', re.I)

HERE = os.path.dirname(os.path.abspath(__file__))
MODULES = ['_chungnam_phase234_all.py','_chungbuk_phase234_all.py','_jeonbuk_phase234_all.py']
# 파일문서(_blank여도 보류) 제외 안 함 — 사용자 확정: 새창이면 PDF도 사이트.

def load():
    sites,mods={},{}
    for f in MODULES:
        sp=importlib.util.spec_from_file_location(f[:-3],os.path.join(HERE,f));m=importlib.util.module_from_spec(sp);sp.loader.exec_module(m)
        for k,v in m.SITES.items(): sites[k]=v;mods[k]=m
    return sites,mods

def mkfetch(M,cfg):
    if hasattr(M,'make_session'):
        s=M.make_session(weak_ssl=cfg.get('weak_ssl',False)); return lambda u:M.fetch(s,u)
    return lambda u:M.fetch(u)

def norm(base,h):
    h=urljoin(base,h); h=urldefrag(h)[0]
    return h.replace('http://','https://').rstrip('/')

def collect_blank(fetch, sample_urls):
    """샘플 페이지들에서 _blank 우세 정규화URL 집합 반환."""
    bl,nb=Counter(),Counter()
    pages=0
    for su in sample_urls:
        soup=fetch(su)
        if soup is None: continue
        pages+=1
        for a in soup.find_all('a',href=True):
            h=a['href']
            if not h or h.startswith('#') or 'javascript' in h.lower(): continue
            key=norm(su,h)
            if not key.startswith('http'): continue
            if (a.get('target') or '')=='_blank': bl[key]+=1
            else: nb[key]+=1
    site=set(k for k in bl if bl[k]>=1 and bl[k]>=nb[k])
    return site,pages

def run(name,cfg,M,write,minrow=3):
    xlsx=cfg['xlsx']
    wb=openpyxl.load_workbook(xlsx); ws=wb.active
    # 샘플: 홈 + xlsx 상위 데이터 URL 3개(헤더 GNB 확보)
    urls=[ws.cell(r,11).value for r in range(3,ws.max_row+1) if isinstance(ws.cell(r,11).value,str) and ws.cell(r,11).value.startswith('http')]
    if not urls:
        print(f'{name}: URL없음'); return
    host=urlparse(urls[0]).netloc; scheme='https'
    # 권위 있는 메뉴(GNB)만 사용 — 임의 콘텐츠페이지의 _blank 관련링크 노이즈 차단
    samples=[f'{scheme}://{host}/', f'{scheme}://{host}/main/',
             f'{scheme}://{host}/main/main.do', f'{scheme}://{host}/index.do']
    fetch=mkfetch(M,cfg)
    site_urls,pages=collect_blank(fetch,samples)
    def lab(r):
        for c in range(10,3,-1):
            v=ws.cell(r,c).value
            if v not in (None,''): return str(v).strip()[:18]
        return ''
    flips=[]
    for r in range(max(3,minrow),ws.max_row+1):
        K=ws.cell(r,11).value
        if not (isinstance(K,str) and K.startswith('http')): continue
        curL=ws.cell(r,12).value
        if curL=='사이트': continue
        if curL=='게시판' and BOARD_URL.search(K):  # 실게시판 보호
            continue
        if norm(samples[0],K) in site_urls:
            flips.append((r,lab(r),curL,K))
    if write and flips:
        bak=xlsx.replace('.xlsx','_backup_새창사이트전.xlsx')
        if not os.path.exists(bak): shutil.copy(xlsx,bak)
        for r,l,L,K in flips:
            ws.cell(r,12).value='사이트'; ws.cell(r,13).value=None; ws.cell(r,14).value=None
        wb.save(xlsx)
    print(f'{name}: 메뉴페이지{pages}개·_blank우세링크{len(site_urls)} → 사이트전환 {len(flips)}행 {"[적용]" if write else "[DRY]"}')
    for r,l,L,K in sorted(flips)[:20]:
        print(f'    r{r} {L}→사이트 {l} | {K[:58]}')
    if len(flips)>20: print(f'    …외 {len(flips)-20}행')

def main():
    args=sys.argv[1:]; write='--write' in args
    minrow=3
    for a in args:
        if a.startswith('--minrow='): minrow=int(a.split('=')[1])
    names=[a for a in args if not a.startswith('--')]
    sites,mods=load()
    for n in names:
        if n in sites: run(n,sites[n],mods[n],write,minrow)
        else: print(f'{n}: 없음')

if __name__=='__main__': main()
