"""finviz_chart_items.json 의 305개 ticker 를 의미 기반 24개 그룹으로 재분류.

기존 finviz JSON 의 12 그룹은 "통화/채권" 안에 NVDA/META 같은 개별 종목이
잡탕으로 들어 있어서 평균 점수가 의미 없었음. 이 모듈은 caption 키워드 기반으로
재분류한 결과를 sector_taxonomy.json 에 저장. 결과는 _intraday_strength_cell 이 사용.

실행: python _classify_sectors.py
출력: sector_taxonomy.json + 분류 통계 stdout
"""
from __future__ import annotations

import json
import re
import sys
from collections import Counter, defaultdict
from pathlib import Path

CFG_PATH = Path(__file__).parent / "finviz_chart_items.json"
OUT_PATH = Path(__file__).parent / "sector_taxonomy.json"

# 우선순위 순서 (위에서부터 매칭, 첫 일치 채택)
RULES: list[tuple[str, str]] = [
    # ── 광역 인덱스 / 시장
    ("미국 광역 인덱스",
     r"S&P 500|러셀 2000|나스닥 100|다우 30|VTI|VOO|IVV|QQQ"),
    ("미국 사이즈/스타일/배당",
     r"배당|VIG|DVY|PEY|IWM|VBR|IWO|IWS|IWP|VTV|VUG|MGK|MGV|소형|중형|"
     r"대형(가치|성장)|대형주|모멘텀|로우볼|퀄리티 ETF|밸류 팩터|"
     r"성장주 ETF|가치주 ETF"),
    ("자산배분 / 팩터",
     r"리스크 패리티|60/40|자산배분"),
    # ── GICS 섹터 ETF
    ("미국 GICS 섹터 ETF",
     r"^XL[A-Z]|GICS|섹터 ETF$|^SPDR.*Sector"),
    # ── 반도체
    ("반도체",
     r"반도체|메모리|파운드리|팹리스|EUV|노광|EDA|HDD|NAND|DRAM|PCB|"
     r"증착|식각|검사·계측|검사장비|패키징|OSAT|후공정|HPC|모바일칩|"
     r"모뎀|스토리지/플래시|광학$|^SMH$|^SOXX$|반도체$|"
     r"테스트\(소켓|^FORM$"),
    # ── 빅테크
    ("빅테크 플랫폼",
     r"애플|마이크로소프트|구글|아마존$|메타|넷플릭스|디즈니|오라클|"
     r"^MSFT$|^GOOGL$|^AAPL$|^AMZN$|^META$|^NFLX$|^DIS$|^ORCL$|어도비|"
     r"세일즈포스|스트리밍|콘텐츠/스트리밍|소셜|메타버스|미디어 실험|"
     r"^VT$|^EZU$|전세계 주식|유로존"),
    # ── 사이버보안
    ("사이버보안",
     r"보안$|보안\(|크라우드|포티넷|지스케일러|팔로알토|클라우드플레어|"
     r"HACK|CIBR|네트워크 보안"),
    # ── AI / SW / 클라우드
    ("AI / 엔터프라이즈 SW",
     r"AI 소프트웨어|데이터·AI|NoSQL|팔란티어|C3\.ai|MSAI|MDB|PLTR|"
     r"스노우플레이크|소프트웨어$|^IGV$|^SKYY$|클라우드 컴퓨팅|"
     r"글로벌 소셜|분자모델링|의료AI|AI 신약|헬스케어 IT"),
    # ── 데이터센터·전력
    ("데이터센터·전력 인프라",
     r"데이터센터|냉각|UPS|스위치기어|전력기기|변압기|아리스타|버티브|"
     r"이튼|Powell Industries|EQIX|DLR|네트워킹|네트워크 장비|서버|"
     r"PC/AI 인프라|송배전|콴타|전력설비|GE Vernova|컨스텔레이션|"
     r"^CEG$|^GEV$|^PWR$|^SILC$|^ADTN$|IoT 플랫폼"),
    # ── 우주·위성
    ("우주 / 위성",
     r"우주|위성|^UFO$|^ROKT$|^LUNR$|^SATL$|달착륙|로켓 ETF"),
    # ── 방산
    ("방산 / 항공우주",
     r"방산|록히드|노스럽|RTX|L3해리스|보잉|^ITA$|^PPA$|^XAR$|^JETS$|"
     r"글로벌 항공|항공우주|항공엔진|에너지 설비"),
    # ── 헬스케어
    ("헬스케어 / 바이오",
     r"바이오|제약|항체|치료|일라이|머크|화이자|존슨|치과|정형외과|"
     r"인슐린|^XBI$|^IBB$|^XLV$|디바이스|의료유통|의료기기|GLP|비만|"
     r"당뇨|수술로봇|혈당|톡신|의료미용|뇌질환|진단|여성건강|건강관리|"
     r"^IXJ$|^ISRG$|^DXCM$|^HOLX$|파이프라인|자가면역|방사성의약품|"
     r"SC 제형|디지털 정신건강|^TALK$|홈케어|^AHCO$|랜티우스|"
     r"테라토|에스티팜|^GERN$|^LNTH$|^SDGR$|^RXRX$|^PHR$|^HALO$"),
    # ── 클린에너지
    ("클린·신재생 에너지",
     r"태양|풍력|수소|연료전지|클린|^ICLN$|^TAN$|^HYDR$|^NEE$|"
     r"블룸에너지|ESS$|배터리|^CHPT$|EV충전"),
    # ── 원자력
    ("원자력 / 우라늄",
     r"원자력|우라늄|SMR|농축|소형원자로|^URA$|^URNM$|^OKLO$|^LEU$|"
     r"센트러스|카메코"),
    # ── 자동차
    ("자동차 / 모빌리티",
     r"전기차|EV$|테슬라|리비안|루시드|니오|샤오펑|BYD|자율주행|전장|"
     r"앱티브|모빌리티|완성차|^F$|^GM$|^CARZ$|글로벌 자동차|자동차 부품"),
    # ── 에너지 / 석유 / 가스
    ("에너지 / 석유·가스",
     r"엑슨모빌|쉐브론|슐럼버져|베이커휴즈|^XLE$|^XOP$|^XOM$|^CVX$|"
     r"^SLB$|^BKR$|에너지/석유|오일서비스|석유|가스 ETF|^LNG$|^EQT$|"
     r"천연가스|LNG 수출|글로벌 에너지|^E$"),
    # ── 해운 / 운송
    ("해운 / 운송",
     r"해운|벌크|탱커|운반선|운반$|LPG 운반|^SBLK$|^STNG$|^LPG$|"
     r"^HAFN$|^IYT$|운송|^UPS$|FedEx|페덱스"),
    # ── 원자재 / 광물
    ("원자재 / 광물 / 금속",
     r"구리|니켈|리튬|희토류|원자재|귀금속|금 ETF|은 ETF|팔라듐|^GLD$|"
     r"^SLV$|^COPX$|^REMX$|^LIT$|^CPER$|광산|^GDX$|금광|알루미늄|^AA$|"
     r"^LPX$|건축 목재|^CAT$|중장비|촉매|화학|^ECVT$"),
    # ── 농업
    ("농업 / 식음료 원자재",
     r"농업|^ALCO$|^ANDE$|^DBA$"),
    # ── 소비재 / 리테일 / 음식
    ("소비재 / 리테일 / 음식",
     r"리테일|이커머스(?!.*AI)|코스트코|애슬레저|매트리스|색조|"
     r"스포츠웨어|렌터카|월마트|타깃|홈디포|로우|^XLY$|^XLP$|소비재|"
     r"^XRT$|미국 소매|^GAP$|의류|^EL$|뷰티|^GIS$|식음료|^DG$|디스카운트|"
     r"^PM$|담배|주방용품|^LCUT$|^TR$|식품|식품 유통|^IMKTA$|^VLGEA$|"
     r"^KODK$|이미지|유통$"),
    # ── 카지노 / 여가 / 리오프닝
    ("카지노 / 여가 / 여행",
     r"카지노|마카오|^WYNN$|^LVS$|극장|리오프닝|^AMC$|공연|^LYV$|여행|"
     r"^PEJ$|^AWAY$|관광|^PRSU$|크루즈"),
    # ── 금융 / 핀테크
    ("금융 / 핀테크",
     r"은행|보험|증권사|핀테크|페이팔|비자|마스터|^BAC$|^JPM$|^GS$|^MS$|"
     r"^XLF$|^KRE$|^KIE$|블록|^HOOD$|로빈훗|^VIRT$|트레이딩|"
     r"^금융$|Range Capital|^RANG$"),
    # ── 부동산
    ("부동산 / REIT",
     r"REIT|^XLRE$|부동산|^VNQ$|^IYR$|^CBL$|리츠"),
    # ── 채권
    ("채권 / 우선주",
     r"국채|TIPS|HY 채권|IG 채권|회사채|^TLT$|^HYG$|^LQD$|^AGG$|^BND$|"
     r"이머징.*채권|^EMB$|장기 국채|단기 국채|채권$|우선주|^XOMAO$|"
     r"^OXLCM$|^XRN-B$|^RCB$|^RANG$"),
    # ── 통화 / FX
    ("통화 / FX",
     r"달러 인덱스|엔 ETF|통화 바스켓|^UUP$|^FXE$|^FXY$|FX$"),
    # ── 해외 / 지역
    ("해외 / 지역 ETF",
     r"한국$|일본$|중국$|독일$|브라질$|인도$|영국$|유럽$|이머징$|^EWY$|"
     r"^EWJ$|^FXI$|^EWG$|^EWZ$|^INDA$|^EWU$|^VGK$|^EFA$|^VEA$|^VWO$|"
     r"^IEUR$|^DFE$|^EFV$|^EFG$|^AAXJ$|아시아|일본 제외|미국 제외|"
     r"^CQQQ$|^CHIQ$|중국 인터넷|중국 소비"),
    # ── 산업재 / 인프라
    ("산업재 / 인프라",
     r"산업재|^XLI$|건설|기계|항공기 부품|인프라|환경|^CLH$|"
     r"EMS$|^JBL$|^SANM$|^TOYO$|^NSYS$|전자$|^산업$"),
    # ── 통신 / 미디어
    ("통신 / 미디어",
     r"통신|^XTL$|^XLC$|버라이즌|AT&T|T-모바일|^TMUS$|^VZ$"),
    # ── 로봇 / 자동화
    ("로봇 / 자동화",
     r"^ROBO$|^ROBT$|^CGNX$|머신비전|로봇 ETF"),
    # ── 암호화폐 / 디지털자산
    ("암호화폐 / 디지털자산",
     r"비트코인|^HODL$|^MSTR$|^COIN$|코인베이스|BTC"),
    # ── 글로벌 테마 (3D/IPO/소셜/우주 외 잡테마)
    ("글로벌 테마",
     r"3D|^PRNT$|^IPOS$|^SOCL$|르네상스 IPO"),
    # ── IT 유통
    ("IT 유통 / 컨설팅",
     r"IT 유통|^SNX$|^FCN$|컨설팅"),
    # ── SPAC / 우선주 등 특수
    ("특수 / SPAC",
     r"SPAC$|^PONOU$|^PAAC$|^TDAC$"),
]


def classify(caption: str) -> str:
    for cat, pat in RULES:
        if re.search(pat, caption, re.IGNORECASE):
            return cat
    return "기타 / 미분류"


def build_taxonomy() -> dict:
    cfg = json.loads(CFG_PATH.read_text(encoding="utf-8"))
    items: dict[str, str] = {}  # ticker → caption
    for group_items in cfg.values():
        for it in group_items:
            items.setdefault(it["ticker"], it["caption"])
    mapping = {t: classify(cap) for t, cap in items.items()}
    return {
        "version": 2,
        "generated_at": __import__("datetime").datetime.now().isoformat(timespec="seconds"),
        "source": "finviz_chart_items.json",
        "ticker_to_group": mapping,
        "captions": items,
    }


def main(argv: list[str] | None = None) -> int:
    tx = build_taxonomy()
    OUT_PATH.write_text(json.dumps(tx, ensure_ascii=False, indent=2), encoding="utf-8")
    counts = Counter(tx["ticker_to_group"].values())
    print(f"=== sector_taxonomy v{tx['version']} 생성 ===")
    print(f"총 ticker: {len(tx['ticker_to_group'])}")
    print(f"카테고리 수: {len(counts)}")
    print("─" * 50)
    for cat, n in sorted(counts.items(), key=lambda x: -x[1]):
        bar = "█" * min(n, 30)
        print(f"  {cat:<28}  {n:>3}  {bar}")
    print(f"\n저장: {OUT_PATH}")
    print(f"미분류: {counts.get('기타 / 미분류', 0)}개")
    return 0


if __name__ == "__main__":
    sys.exit(main())
