# -*- coding: utf-8 -*-
"""_작업현황.md → 작업현황.xlsx 대시보드.
컬럼: 광역 | 번호 | 기관 | 담당자 | 상태 | 검수 | 행수 | 비고
- 담당자: 충남/충북=프리랜서1, 전북=프리랜서2, 제주=(미지정)  ← 드롭다운
- 상태: 작업상태(수집완료 등)  ← 드롭다운+조건부서식(색)
- 검수: 완료/미검수 (md의 ☑️검수완료 → 완료)  ← 드롭다운+조건부서식
- 행수: 데이터바
- 요약 시트: 광역별·담당자별 집계(수식 COUNTIFS/SUMIF)
md를 원장으로 두고 여기서 자동생성.
"""
import re
import sys
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
from openpyxl.formatting.rule import FormulaRule, DataBarRule
from openpyxl.worksheet.datavalidation import DataValidation

MD = '_작업현황.md'
OUT = sys.argv[1] if len(sys.argv) > 1 else '작업현황.xlsx'
REGIONS = ['충청남도', '충청북도', '전북특별자치도', '제주특별자치도']
ASSIGNEE = {'충청남도': '프리랜서1', '충청북도': '프리랜서1',
            '전북특별자치도': '프리랜서2', '제주특별자치도': '프리랜서2'}
STATUS_OPTIONS = ['⬜ 미착수', '🔄 수집 중', '✅ 수집완료', '⚠️ 보류·이슈']
INSPECT_OPTIONS = ['완료', '미검수']
ASSIGNEE_OPTIONS = ['프리랜서1', '프리랜서2']
SUBMIT_OPTIONS = ['완료', '미완료']
def parse_submissions():
    """## 📤 제출 이력 표에서 {기관: 제출일} 추출 (제출 컬럼 원장).
    제출분이 늘어도 md 제출 이력 표만 갱신하면 자동 반영됨(하드코딩 금지)."""
    s = open(MD, encoding='utf-8').read()
    i = s.find('## 📤 제출 이력')
    if i < 0:
        return {}
    j = s.find('\n## ', i + 5)
    sec = s[i:j if j > 0 else i + 3000]
    out = {}
    for ln in sec.splitlines():
        m = re.match(r'\|\s*(2026-\d{2}-\d{2})\s*\|(.+?)\|', ln)
        if not m:
            continue
        date, insts = m.group(1), m.group(2)
        for nm in re.findall(r'([가-힣]+[시군])\(', insts):
            out[nm] = date
    return out


SUBMITTED = parse_submissions()   # {기관: 제출일}


def parse():
    lines = open(MD, encoding='utf-8').read().splitlines()
    rows, cur = [], None
    for ln in lines:
        m = re.match(r'^##\s+(충청남도|충청북도|전북특별자치도|제주특별자치도)', ln)
        if m:
            cur = m.group(1); continue
        if cur and ln.startswith('|'):
            cells = [c.strip() for c in ln.strip().strip('|').split('|')]
            if len(cells) < 5 or not cells[0].isdigit():
                continue
            gm = re.search(r'\[([^\]]+)\]', cells[1])
            inst = gm.group(1) if gm else cells[1]
            st = cells[2]
            cntm = re.search(r'(\d[\d,]*)', cells[3])
            cnt = int(cntm.group(1).replace(',', '')) if cntm else None
            # md 상태 → (작업상태, 검수)
            if '검수완료' in st:
                work, insp = '✅ 수집완료', '완료'
            elif '수집완료' in st:
                work, insp = '✅ 수집완료', '미검수'
            elif '보류' in st or '⚠' in st:
                work, insp = '⚠️ 보류·이슈', '미검수'
            elif '수집' in st and '중' in st:
                work, insp = '🔄 수집 중', '미검수'
            else:
                work, insp = '⬜ 미착수', '미검수'
            bigo = cells[4]
            # 비고 앞 [검수 YYYY-MM-DD] 마커 → 검수완료일 컬럼으로 추출하고 비고에서 제거
            dm = re.search(r'\[검수\s*(\d{4}-\d{2}-\d{2})\]', bigo)
            idate = dm.group(1) if dm else ''
            bigo = re.sub(r'\[검수\s*\d{4}-\d{2}-\d{2}\]\s*·?\s*', '', bigo).strip()
            # 제출: 제출 이력 표(SUBMITTED 원장)에 있으면 제출완료(제출일=표의 날짜)
            if inst in SUBMITTED:
                submit, sdate = '완료', SUBMITTED[inst]
            else:
                submit, sdate = '미완료', ''
            rows.append({'region': cur, 'num': int(cells[0]), 'inst': inst,
                         'assignee': ASSIGNEE.get(cur, ''), 'work': work,
                         'inspect': insp, 'idate': idate, 'count': cnt,
                         'submit': submit, 'sdate': sdate, 'bigo': bigo})
    return rows


def main():
    rows = parse()
    wb = openpyxl.Workbook(); ws = wb.active; ws.title = '현황'
    thin = Side(style='thin', color='BFBFBF')
    border = Border(left=thin, right=thin, top=thin, bottom=thin)
    hf = PatternFill('solid', fgColor='4472C4'); hfont = Font(bold=True, color='FFFFFF')
    headers = ['광역', '번호', '기관', '담당자', '상태', '검수', '행수', '검수완료일', '제출완료', '제출일', '비고']
    widths = [15, 6, 12, 11, 12, 9, 10, 13, 10, 12, 100]
    for c, (h, w) in enumerate(zip(headers, widths), 1):
        cell = ws.cell(1, c, h)
        cell.fill = hf; cell.font = hfont; cell.border = border
        cell.alignment = Alignment(horizontal='center', vertical='center')
        ws.column_dimensions[get_column_letter(c)].width = w
    ws.freeze_panes = 'A2'
    r = 2
    for row in rows:
        ws.cell(r, 1, row['region']); ws.cell(r, 2, row['num']); ws.cell(r, 3, row['inst'])
        ws.cell(r, 4, row['assignee']); ws.cell(r, 5, row['work']); ws.cell(r, 6, row['inspect'])
        ws.cell(r, 7, row['count']); ws.cell(r, 8, row['idate'])
        ws.cell(r, 9, row['submit']); ws.cell(r, 10, row['sdate']); ws.cell(r, 11, row['bigo'])
        for c in range(1, 12):
            cell = ws.cell(r, c); cell.border = border
            cell.alignment = Alignment(horizontal='left' if c == 11 else 'center',
                                       vertical='center', wrap_text=(c == 11))
        ws.cell(r, 7).number_format = '#,##0'
        ws.row_dimensions[r].height = 30
        r += 1
    last = r - 1
    ws.auto_filter.ref = f'A1:K{last}'

    # 드롭다운(셀렉트박스)
    def add_dv(col, options, title):
        dv = DataValidation(type='list', formula1='"' + ','.join(options) + '"',
                            allow_blank=True, showDropDown=False)
        dv.promptTitle = title; dv.prompt = f'{title} 선택'
        ws.add_data_validation(dv); dv.add(f'{col}2:{col}{last}')
    add_dv('D', ASSIGNEE_OPTIONS, '담당자')
    add_dv('E', STATUS_OPTIONS, '작업상태')
    add_dv('F', INSPECT_OPTIONS, '검수')
    add_dv('I', SUBMIT_OPTIONS, '제출완료')

    # 조건부서식 (값 바뀌면 색 자동). priority 낮을수록 우선.
    _pri = [0]

    def cf(rng, kw, fill, font, formula=None):
        _pri[0] += 1
        rule = FormulaRule(
            formula=[formula or f'ISNUMBER(SEARCH("{kw}",{rng.split(":")[0]}))'],
            # ★ CF 채우기는 Excel이 bgColor로 렌더 → fg/bg 둘 다 지정해야 색이 보임
            fill=PatternFill('solid', fgColor=fill, bgColor=fill),
            font=(Font(bold=True, color=font) if font else None), stopIfTrue=False)
        rule.priority = _pri[0]
        ws.conditional_formatting.add(rng, rule)

    # ★ 검수완료 & 제출미완료 → 행 전체 노랑 (초록보다 우선: 먼저 등록해 priority↑)
    cf(f'A2:K{last}', None, 'FFEB9C', None, formula=f'AND($F2="완료",$I2="미완료")')
    # ★ 검수=완료 → 행 전체 초록
    cf(f'A2:K{last}', None, 'C6EFCE', None, formula=f'$F2="완료"')
    # 제출완료: 완료=파랑 / 미완료=회색
    cf(f'I2:I{last}', '완료', 'BDD7EE', '1F4E78', formula=f'$I2="완료"')
    cf(f'I2:I{last}', '미완료', 'F2F2F2', '808080', formula=f'$I2="미완료"')
    # 담당자
    cf(f'D2:D{last}', '프리랜서1', 'DDEBF7', '1F4E78')
    cf(f'D2:D{last}', '프리랜서2', 'FCE4D6', '974706')
    # 상태
    cf(f'E2:E{last}', '수집완료', 'E2EFDA', '375623')
    cf(f'E2:E{last}', '보류', 'FFEB9C', '9C5700')
    cf(f'E2:E{last}', '수집 중', 'FFF2CC', '7F6000')
    cf(f'E2:E{last}', '미착수', 'F2F2F2', '808080')
    # 검수 (미검수만 — 완료는 행 규칙이 처리)
    cf(f'F2:F{last}', '미검수', 'F2F2F2', '808080')
    # 행수 데이터바 (초록 행 위에도 막대 표시됨)
    db = DataBarRule(start_type='min', end_type='max', color='8EAADB', showValue=True)
    _pri[0] += 1; db.priority = _pri[0]
    ws.conditional_formatting.add(f'G2:G{last}', db)

    # ===== 요약 시트 =====
    s = wb.create_sheet('요약')
    A = f'현황!$A$2:$A${last}'; DD = f'현황!$D$2:$D${last}'
    FF = f'현황!$F$2:$F${last}'; GG = f'현황!$G$2:$G${last}'
    II = f'현황!$I$2:$I${last}'   # 제출완료

    def hdr(rowi, titles, fill='4472C4'):
        for c, t in enumerate(titles, 1):
            cell = s.cell(rowi, c, t)
            cell.fill = PatternFill('solid', fgColor=fill)
            cell.font = Font(bold=True, color='FFFFFF')
            cell.border = border
            cell.alignment = Alignment(horizontal='center', vertical='center')
    for c, w in enumerate([16, 9, 11, 11, 11, 11], 1):
        s.column_dimensions[get_column_letter(c)].width = w

    # 광역별
    s.cell(1, 1, '◆ 광역별').font = Font(bold=True, size=12)
    hdr(2, ['광역', '기관수', '검수완료', '미검수', '제출완료', '총 행수'])
    rr = 3
    for region in REGIONS:
        a = f'A{rr}'
        s.cell(rr, 1, region)
        s.cell(rr, 2, f'=COUNTIF({A},{a})')
        s.cell(rr, 3, f'=COUNTIFS({A},{a},{FF},"완료")')
        s.cell(rr, 4, f'=COUNTIFS({A},{a},{FF},"미검수")')
        s.cell(rr, 5, f'=COUNTIFS({A},{a},{II},"완료")')
        s.cell(rr, 6, f'=SUMIF({A},{a},{GG})')
        for c in range(1, 7):
            s.cell(rr, c).border = border
            s.cell(rr, c).alignment = Alignment(horizontal='center' if c > 1 else 'left', vertical='center')
        s.cell(rr, 6).number_format = '#,##0'
        rr += 1
    s.cell(rr, 1, '합계').font = Font(bold=True)
    for c in range(2, 7):
        col = get_column_letter(c)
        cc = s.cell(rr, c, f'=SUM({col}3:{col}{rr-1})'); cc.font = Font(bold=True)
        cc.border = border; cc.alignment = Alignment(horizontal='center', vertical='center')
        cc.fill = PatternFill('solid', fgColor='FCE4D6')
        if c == 6:
            cc.number_format = '#,##0'
    s.cell(rr, 1).fill = PatternFill('solid', fgColor='FCE4D6'); s.cell(rr, 1).border = border

    # 담당자별
    base = rr + 2
    s.cell(base - 1, 1, '◆ 담당자별').font = Font(bold=True, size=12)
    hdr(base, ['담당자', '기관수', '검수완료', '미검수', '제출완료', '총 행수'], fill='ED7D31')
    rr2 = base + 1
    for who in ['프리랜서1', '프리랜서2']:
        a = f'A{rr2}'
        s.cell(rr2, 1, who)
        s.cell(rr2, 2, f'=COUNTIF({DD},{a})')
        s.cell(rr2, 3, f'=COUNTIFS({DD},{a},{FF},"완료")')
        s.cell(rr2, 4, f'=COUNTIFS({DD},{a},{FF},"미검수")')
        s.cell(rr2, 5, f'=COUNTIFS({DD},{a},{II},"완료")')
        s.cell(rr2, 6, f'=SUMIFS({GG},{DD},{a})')
        for c in range(1, 7):
            s.cell(rr2, c).border = border
            s.cell(rr2, c).alignment = Alignment(horizontal='center' if c > 1 else 'left', vertical='center')
        s.cell(rr2, 6).number_format = '#,##0'
        rr2 += 1
    s.freeze_panes = 'A3'

    wb.save(OUT)
    print(f'생성: {OUT} | 현황 {len(rows)}기관 (담당자/상태/검수 분리, 드롭다운·조건부서식·수식)')


if __name__ == '__main__':
    main()
