# -*- coding: utf-8 -*-
"""김제시 인페이지 탭(#anchor) 수량 → M 기입.
페이지 본문의 div[class*=basic_tab] 중 탭 링크가 전부 '#anchor'인 그룹(예 basic_tab2>ul.col4,
#tab1~#tabN)을 인페이지 스크롤탭으로 보고 M=탭수 기입(공주/금산 전례, 매뉴얼 1-5b: #anchor는 행 분리 안함).
menuCd 형제 nav(basic_tab depth4 등, href=실제 .gimje)는 제외. L은 페이지 유지.
대상: 17행~끝(요청). 3~16행은 참고 보고만.
사용: python -X utf8 _김제_인페이지탭수.py dry | run
"""
import os, sys, re, io, time, shutil
from concurrent.futures import ThreadPoolExecutor, as_completed
import warnings; warnings.filterwarnings('ignore')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', line_buffering=True)
import requests
from bs4 import BeautifulSoup
import openpyxl
HERE = os.path.dirname(os.path.abspath(__file__))
XP = os.path.join(HERE, '작업파일', '광역_사이트맵', '전북특별자치도', '3.김제시', '전북특별자치도_김제시.xlsx')
UA = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120 Safari/537.36'}


def fetch(session, url):
    r = session.get(url, headers=UA, verify=False, timeout=10, allow_redirects=True)
    meta = re.search(rb'charset=["\']?\s*([\w-]+)', r.content[:3000], re.I)
    r.encoding = meta.group(1).decode('ascii', 'ignore') if meta else r.apparent_encoding
    return BeautifulSoup(r.text, 'html.parser')


BASIC_TAB = re.compile('basic_tab')

def inpage_tabs(soup):
    """가장 큰 '전부 #anchor' basic_tab 그룹의 (탭수, 라벨)."""
    best, labels = 0, None
    for d in soup.find_all('div', class_=BASIC_TAB):
        ul = d.find('ul')
        if not ul:
            continue
        links = ul.select('li > a')
        if len(links) < 2:
            continue
        hrefs = [(a.get('href') or '').strip() for a in links]
        if all(h.startswith('#') for h in hrefs):
            if len(links) > best:
                best = len(links)
                labels = [a.get_text(strip=True) for a in links]
    return best, labels


def main():
    mode = sys.argv[1] if len(sys.argv) > 1 else 'dry'
    wb = openpyxl.load_workbook(XP); ws = wb.active
    last = max(r for r in range(3, ws.max_row + 1) if ws.cell(r, 2).value not in (None, ''))

    def lab(r):
        return ' > '.join(str(ws.cell(r, c).value) for c in range(4, 11) if ws.cell(r, c).value not in (None, ''))

    # 대상 수집: L=페이지 & http URL
    def targets(lo, hi):
        out = []
        for r in range(lo, hi + 1):
            L = ws.cell(r, 12).value
            url = ws.cell(r, 11).value
            if L == '페이지' and isinstance(url, str) and url.startswith('http'):
                out.append((r, url))
        return out

    main_t = targets(17, last)
    pre_t = targets(3, 16)
    session = requests.Session()

    def scan(rows_urls):
        res = {}
        def w(ru):
            r, u = ru
            try:
                n, ls = inpage_tabs(fetch(session, u))
                return r, n, ls
            except Exception:
                return r, 0, None
        with ThreadPoolExecutor(max_workers=10) as ex:
            for f in as_completed([ex.submit(w, ru) for ru in rows_urls]):
                r, n, ls = f.result()
                if n >= 2:
                    res[r] = (n, ls)
        return res

    print(f'스캔: 17~{last} ({len(main_t)}개 페이지), 참고 3~16 ({len(pre_t)}개)')
    t0 = time.time()
    main_hits = scan(main_t)
    pre_hits = scan(pre_t)
    print(f'스캔완료 {time.time()-t0:.0f}s')

    print(f'\n[대상 17~끝] 인페이지탭 발견 {len(main_hits)}행:')
    for r in sorted(main_hits):
        n, ls = main_hits[r]
        old = ws.cell(r, 13).value
        print(f'  r{r}: M {old}→{n}  [{lab(r)}]  탭={ls}')
    if pre_hits:
        print(f'\n[참고 3~16] 인페이지탭 {len(pre_hits)}행 (요청범위 밖, 미적용):')
        for r in sorted(pre_hits):
            n, ls = pre_hits[r]
            print(f'  r{r}: M {ws.cell(r,13).value}→{n}?  [{lab(r)}]  탭={ls}')

    if mode != 'run':
        return
    bak = XP.replace('.xlsx', '_backup_인페이지탭전.xlsx')
    shutil.copy(XP, bak)
    for r, (n, ls) in main_hits.items():
        ws.cell(r, 13).value = n
    try:
        wb.save(XP); print(f'\n저장완료. {len(main_hits)}행 M 갱신. 백업 {os.path.basename(bak)}')
    except PermissionError:
        wb.save(XP.replace('.xlsx', '_LP.xlsx')); print('\n!! 잠김 → _LP')


if __name__ == '__main__':
    main()
