# -*- coding: utf-8 -*-
import openpyxl, io, os, glob
from collections import defaultdict
ROOT=r"D:\01.프로젝트\DB수집"
out=io.open(r"D:\01.프로젝트\DB수집\작업파일\_dupname_sweep_out.txt","w",encoding="utf-8")
def w(*a): out.write(" ".join(str(x) for x in a)+"\n")

SKIP_DIR=("_backup","backup","_temp","제출폴더","_스크립트","_nshots","_naudit","_shots",".git")
SKIP_NAME=("backup","conflicted","_작업현황","작업현황","_취합_예시","자료_취합","예시","~$")

def is_target(p):
    pl=p.replace("/","\\")
    for s in SKIP_DIR:
        if "\\"+s in pl or "\\"+s+"\\" in pl: return False
    base=os.path.basename(p)
    for s in SKIP_NAME:
        if s in base: return False
    return base.endswith(".xlsx")

files=[]
for dp,dn,fn in os.walk(ROOT):
    # prune skip dirs
    dn[:]=[d for d in dn if d not in SKIP_DIR and "backup" not in d.lower()]
    for f in fn:
        p=os.path.join(dp,f)
        if is_target(p): files.append(p)

w("scanned candidate files:",len(files));w("")

def eff_leaf_dups(ws):
    eff={}
    for r in range(3,ws.max_row+1):
        for c in range(4,11):
            eff[(r,c)]=ws.cell(r,c).value
    for mr in ws.merged_cells.ranges:
        if mr.min_col>=4 and mr.max_col<=10:
            v=ws.cell(mr.min_row,mr.min_col).value
            for r in range(mr.min_row,mr.max_row+1):
                for c in range(mr.min_col,mr.max_col+1):
                    eff[(r,c)]=v
    byleaf=defaultdict(list)
    for r in range(3,ws.max_row+1):
        # skip empty rows
        path=[str(eff[(r,c)]).strip() for c in range(4,11) if eff[(r,c)] not in (None,"")]
        if not path: continue
        byleaf[path[-1]].append(r)
    return {k:v for k,v in byleaf.items() if len(v)>1}

summary=[]
for p in sorted(files):
    try:
        wb=openpyxl.load_workbook(p,read_only=False,data_only=True)
    except Exception as e:
        w("LOADERR",p,e); continue
    ws=wb.active
    if ws.max_row<3: 
        wb.close(); continue
    dups=eff_leaf_dups(ws)
    rel=os.path.relpath(p,ROOT)
    ngroups=len(dups); nduprows=sum(len(v) for v in dups.values())
    summary.append((ngroups,nduprows,rel,dups,ws.max_row))
    wb.close()

summary.sort(reverse=True)
w("=== FILES WITH DUPLICATE MENU NAMES (sorted by #groups) ===")
for ng,nr,rel,dups,mx in summary:
    if ng==0: continue
    w(f"\n[{ng} groups / {nr} rows] {rel}  (max_row={mx})")
    for nm,rs in sorted(dups.items(), key=lambda x:-len(x[1])):
        w(f"    '{nm}'  x{len(rs)}  rows={rs}")
clean=[s for s in summary if s[0]==0]
w("\n=== FILES WITH NO DUPLICATE MENU NAMES ===",len(clean))
for ng,nr,rel,dups,mx in clean:
    w("  OK",rel)
out.close()
print("done; files:",len(files),"with dups:",sum(1 for s in summary if s[0]>0))
