# -*- coding: utf-8 -*-
"""공공기관 L 재분류 — '페이지'로 오분류된 게시판 교정(eGov ESF board_pager/list/권호 위젯 누락 보강).
대상: L=='페이지' 행만 재검. 게시판이면 L=게시판·M산출. 기존 게시판/사이트 불변.
사용: python _공공기관_lfix.py [기관명 ...]
"""
import sys, os, re, json, importlib.util, warnings
import openpyxl
warnings.filterwarnings('ignore')
spec = importlib.util.spec_from_file_location('p234', r'D:\01.프로젝트\DB수집\_스크립트\_공공기관_phase234.py')
P = importlib.util.module_from_spec(spec); spec.loader.exec_module(P)
specm = importlib.util.spec_from_file_location('mf', r'D:\01.프로젝트\DB수집\_스크립트\_공공기관_mfix.py')
MF = importlib.util.module_from_spec(specm); specm.loader.exec_module(MF)
OUTDIR = r'D:\01.프로젝트\DB수집\공공기관'
LOG = open(r'D:\01.프로젝트\DB수집\_스크립트\_lfix_result.txt', 'w', encoding='utf-8')


def say(s):
    LOG.write(s + '\n'); LOG.flush()


def is_board(body):
    """강화 게시판 판별. 콘텐츠 스코프(get_body) 가정."""
    # 1) 페이징 위젯(board_pager 포함)
    if body.select('[class*=pager], [class*=paging], [class*=pagination], [class*=paginate]'):
        # 단, 1페이지뿐인 빈 위젯 배제 위해 링크/번호 존재 확인은 생략(존재 자체가 게시판형)
        return True, '페이징위젯'
    # 2) 게시판 리스트 컨테이너
    if body.select('[class*=board_list], [class*=bbs_list], [class*=gallery_list], [class*=photo_list], [class*=galleryList], table.bbs, [class*=board] table tbody tr'):
        return True, '리스트컨테이너'
    # 3) 발간물/정기간행물 권호 아카이브(select 또는 통권 다수)
    if body.select('select[name*=vol], select[name*=issue], select[id*=vol], [class*=volume], [class*=kwon], [class*=issue_list]'):
        return True, '권호아카이브'
    txt = body.get_text(' ', strip=True)
    if len(re.findall(r'통권\s*\d+\s*권', txt)) >= 3 or len(re.findall(r'제?\s*\d+\s*호', txt)) >= 4:
        return True, '권호다수'
    # 4) 총건수 텍스트
    if P.TOTAL_PAT.search(txt) or re.search(r'(?:전체|총)\s*[:\-]?\s*\d[\d,]*\s*건', txt):
        return True, '총건수'
    # (list 링크다수 규칙은 부서소개 등 페이지 오탐이 많아 제외)
    return False, ''


def run(name, sess):
    xlsx = os.path.join(OUTDIR, f'{name}.xlsx')
    wb = openpyxl.load_workbook(xlsx)
    ws = wb.active
    changed = 0
    for r in range(3, ws.max_row + 1):
        if ws.cell(r, 2).value is None:
            break
        if ws.cell(r, 12).value != '페이지':
            continue
        url = ws.cell(r, 11).value
        if not url or not isinstance(url, str) or not url.startswith('http'):
            continue
        soup, final = P.fetch(sess, url)
        if not soup:
            continue
        body = P.get_body(soup, P.BODY_SEL)
        ok, why = is_board(body)
        if not ok:
            continue
        # 게시판으로 승격 + M 산출
        c, how = MF.board_count(body)
        ws.cell(r, 12).value = '게시판'
        ws.cell(r, 13).value = c if c > 0 else 0
        changed += 1
        say(f'  {name} r{r} 페이지→게시판 M={c}({how}) [{why}] {ws.cell(r,5).value or ws.cell(r,4).value}')
    wb.save(xlsx)
    say(f'[{name}] 페이지→게시판 {changed}행')
    return changed


def main():
    probe = {r['name']: r for r in json.load(open(r'D:\01.프로젝트\DB수집\_스크립트\_공공기관_probe.json', encoding='utf-8'))}
    order = sorted(probe.values(), key=lambda x: -int(x['num']))
    only = sys.argv[1:]
    if only:
        order = [p for p in order if p['name'] in only or str(p['num']) in only]
    sess = P.make_session()
    tot = 0
    for p in order:
        try:
            tot += run(p['name'], sess)
        except Exception as e:
            say(f"[{p['name']}] 실패: {e}")
    say(f'=== L재분류 합계 {tot}행 페이지→게시판 ===')
    LOG.close()


if __name__ == '__main__':
    main()
