# -*- coding: utf-8 -*-
"""부여군 사전정보공개(정보목록공개) fiexd_tab1 scate=1~9 분야탭 전개.
- _tab_expand 의 일반 필터탭 제외 규칙(같은 경로·쿼리만 다름)에 걸려 누락된 케이스.
  사용자 지시로 9개 분야탭을 각각 별도 게시판 행으로 전개(보령시 사전정보공표 컨벤션).
- 각 분야 = 게시판 / M=목록 항목수(테이블 데이터행) / N=어문 / O=미부착.
- 평탄화→치환→재구성(D/E/F 재병합·K하이퍼링크·B순번)은 _tab_expand 재사용.
"""
import sys, shutil, warnings, re
from copy import copy
import requests, openpyxl
from bs4 import BeautifulSoup
from openpyxl.styles import Alignment, Font
from openpyxl.utils import get_column_letter

sys.path.insert(0, r'D:\01.프로젝트\DB수집\_스크립트')
from _tab_expand import load_flat, MAXCOL, CAT_COLS, HEADER_MERGES

warnings.filterwarnings('ignore')
H = {'User-Agent': 'Mozilla/5.0'}
XLSX = r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\충청남도\7.부여군\충청남도_부여군.xlsx'
BASE = 'https://www.buyeo.go.kr/_prog/service/index.php?scate='


def collect():
    """9개 scate 라벨+항목수 수집."""
    r = requests.get(BASE + '1', headers=H, timeout=15, verify=False)
    soup = BeautifulSoup(r.content, 'html.parser')
    labels = {}
    for li in soup.select('.fiexd_tab1 li'):
        a = li.find('a'); m = re.search(r'scate=(\d+)', a.get('href') or '')
        if m:
            labels[int(m.group(1))] = a.get_text(strip=True)
    out = []
    for sc in sorted(labels):
        rr = requests.get(BASE + str(sc), headers=H, timeout=15, verify=False)
        s = BeautifulSoup(rr.content, 'html.parser')
        t = s.find('table')
        cnt = sum(1 for tr in t.find_all('tr') if tr.find_all('td'))
        out.append((sc, labels[sc], cnt))
    return out


def main():
    write = '--write' in sys.argv
    scates = collect()
    print('=== scate 분야탭 ===')
    for sc, lab, cnt in scates:
        print(f'  scate={sc} | 항목={cnt} | {lab}')
    print(f'합계 항목 {sum(c for _,_,c in scates)} / 9행 전개\n')

    wb = openpyxl.load_workbook(XLSX)
    ws = wb.active
    rows = load_flat(ws)

    # 대상 행 식별: K가 scate=1
    tgt = None
    for row in rows:
        k = row['vals'].get(11)
        if isinstance(k, str) and 'service/index.php?scate=1' in k:
            tgt = row; break
    if tgt is None:
        print('!! 대상(scate=1) 행 없음'); return
    lc = 6  # leaf=F (사전정보공개)
    childc = lc + 1  # G
    print(f'대상 sheet행 {tgt["src"]} (F={tgt["vals"].get(6)}) → 자식 {get_column_letter(childc)} 에 9분야 전개')

    if not write:
        print('\n(계획만. --write 로 기입)')
        return

    backup = XLSX.replace('.xlsx', '_backup_scate전.xlsx')
    shutil.copy(XLSX, backup)
    print('백업:', backup)

    out_rows = []
    for row in rows:
        if row is tgt:
            for sc, lab, cnt in scates:
                nv = dict(tgt['vals'])
                for c in CAT_COLS:
                    if c > lc:
                        nv[c] = None
                nv[childc] = lab
                nv[11] = BASE + str(sc)
                nv[12] = '게시판'
                nv[13] = cnt
                nv[14] = '어문'
                nv[15] = '미부착'
                for c in (16, 17, 18):   # P,Q,R 비움
                    nv[c] = None
                # 신규 행(scate>1)은 비고~ 비움, scate=1은 기존 보존
                if sc != 1:
                    for c in range(19, MAXCOL + 1):
                        nv[c] = None
                out_rows.append({'vals': nv, 'style': tgt, 'url': nv[11]})
        else:
            out_rows.append({'vals': dict(row['vals']), 'style': row, 'url': row['vals'].get(11)})

    # 데이터 클리어
    for r in range(3, ws.max_row + 1):
        for c in range(1, MAXCOL + 1):
            ws.cell(r, c).value = None
            ws.cell(r, c).hyperlink = None

    START = 3
    for i, orow in enumerate(out_rows):
        r = START + i
        sty = orow['style']['styles']
        for c in range(1, MAXCOL + 1):
            cell = ws.cell(r, c)
            f, fl, bd, al, nf, pr = sty[c]
            cell.font = copy(f); cell.fill = copy(fl); cell.border = copy(bd)
            cell.alignment = copy(al); cell.number_format = nf; cell.protection = copy(pr)
        v = orow['vals']
        for c in range(1, MAXCOL + 1):
            ws.cell(r, c).value = v.get(c)
        ws.cell(r, 2).value = i + 1
    END = START + len(out_rows) - 1

    center = Alignment(horizontal='center', vertical='center', wrap_text=True)
    left = Alignment(horizontal='left', vertical='center', wrap_text=False)

    def merge_runs(col_letter, col_idx, group_cols=()):
        cur_val = ws.cell(START, col_idx).value
        cur_grp = tuple(ws.cell(START, g).value for g in group_cols)
        run_start = START; runs = []
        for r in range(START + 1, END + 1):
            val = ws.cell(r, col_idx).value
            grp = tuple(ws.cell(r, gg).value for gg in group_cols)
            if val == cur_val and grp == cur_grp:
                continue
            if cur_val not in (None, '') and r - 1 > run_start:
                runs.append((run_start, r - 1))
            cur_val, cur_grp, run_start = val, grp, r
        if cur_val not in (None, '') and END > run_start:
            runs.append((run_start, END))
        for s, e in runs:
            ws.merge_cells(f'{col_letter}{s}:{col_letter}{e}')
            ws.cell(s, col_idx).alignment = center

    merge_runs('F', 6, group_cols=(4, 5))
    merge_runs('E', 5, group_cols=(4,))
    merge_runs('D', 4)
    for r in range(START, END + 1):
        for c in (4, 5, 6, 7):
            if ws.cell(r, c).value is not None:
                ws.cell(r, c).alignment = center
    for r in range(1, END + 1):
        ws.row_dimensions[r].height = 15

    for r in range(START, END + 1):
        cell = ws.cell(r, 11)
        u = cell.value
        if isinstance(u, str) and u.startswith(('http://', 'https://')):
            cell.hyperlink = u
            old = cell.font
            cell.font = Font(name=old.name or '맑은 고딕', size=old.size or 11,
                             bold=old.bold, italic=old.italic, color='0000FF', underline='single')
            cell.alignment = left

    wb.save(XLSX)
    print(f'저장 완료: {XLSX} (총 {len(out_rows)}행)')


if __name__ == '__main__':
    main()
