import json, sys, unicodedata
from collections import Counter, defaultdict

PATH = sys.argv[1]
MIN, MAX = -500, 499  # centered region bounds (tiles)

def category(ch):
    o = ord(ch)
    if ch.isspace() or o == 0xA0: return None
    if ("A" <= ch <= "Z") or ("a" <= ch <= "z"): return "latin_letter"
    if "0" <= ch <= "9": return "digit"
    if 0x20 <= o <= 0x7E: return "ascii_punct"
    if 0x2500 <= o <= 0x257F: return "box_drawing"
    if 0x2580 <= o <= 0x259F: return "block_shade"      # ░▒▓█ etc
    if 0x25A0 <= o <= 0x25FF: return "geometric"
    if 0x2600 <= o <= 0x27BF or o >= 0x1F000: return "emoji_symbol"
    if 0x0400 <= o <= 0x04FF: return "cyrillic"
    if 0x0370 <= o <= 0x03FF: return "greek"
    if 0x3000 <= o <= 0x9FFF or 0xAC00 <= o <= 0xD7A3: return "cjk"
    if unicodedata.category(ch).startswith("L"): return "other_letter"
    return "other"

def main():
    tiles = json.load(open(PATH, encoding="utf-8"))
    print(f"loaded {len(tiles)} non-empty tiles", file=sys.stderr)
    cats = Counter(); chars = Counter()
    cells_text = 0; colored = 0
    quad = Counter()
    band_ne = Counter()   # nonempty tiles per distance band
    BAND = 50
    for key, v in tiles.items():
        tx, ty = map(int, key.split(","))
        content = v.get("content", "")
        color = v.get("color")
        # tile-level: does it have any text?
        has = any(not (c.isspace() or ord(c) == 0xA0) for c in content)
        if has:
            d = max(abs(tx), abs(ty))
            band_ne[d // BAND] += 1
            qx = "E" if tx >= 0 else "W"; qy = "S" if ty >= 0 else "N"  # +y is down
            quad[qy + qx] += 1
        for i, c in enumerate(content):
            cat = category(c)
            if cat is None: continue
            cells_text += 1; cats[cat] += 1; chars[c] += 1
            if isinstance(color, list) and i < len(color) and color[i]:
                colored += 1

    # band totals within region (Chebyshev square-ring): (2*d1+1)^2 - (2*d0-1)^2
    def band_total(bidx):
        d0, d1 = bidx * BAND, bidx * BAND + BAND - 1
        outer = (2 * d1 + 1) ** 2
        inner = (2 * d0 - 1) ** 2 if d0 > 0 else 0
        return min(outer, 1000 * 1000) - inner

    ne_tiles = sum(band_ne.values())
    print("="*64)
    print(f"OWOT centered million archive — content profile")
    print("="*64)
    print(f"non-empty tiles (any text): {ne_tiles:,} / 1,000,000  ({ne_tiles/10000:.1f}%)")
    print(f"text cells (non-space chars): {cells_text:,}")
    print(f"colored text cells: {colored:,}  ({100*colored/max(cells_text,1):.1f}%)")
    print()
    print("Quadrant split (+y = down, OWOT reading direction):")
    names = {"SE":"SE (+x,+y  down-right)","SW":"SW (-x,+y  down-left)",
             "NE":"NE (+x,-y  up-right)","NW":"NW (-x,-y  up-left)"}
    for q,_ in quad.most_common():
        print(f"  {names.get(q,q):28} {quad[q]:>8,}  ({100*quad[q]/ne_tiles:.1f}%)")
    print()
    print("Character categories (by text cell):")
    for cat, n in cats.most_common():
        bar = "#" * int(60 * n / cats.most_common(1)[0][1])
        print(f"  {cat:14} {n:>10,}  {100*n/cells_text:5.1f}%  {bar}")
    print()
    print("Density vs distance from origin (Chebyshev tile bands):")
    print(f"  {'band(tiles)':>14}  {'nonempty':>9}  {'of band':>9}  density")
    for b in sorted(band_ne):
        tot = band_total(b)
        d0 = b*BAND; d1 = d0+BAND-1
        print(f"  {d0:>4}-{d1:<4}     {band_ne[b]:>9,}  {tot:>9,}  {100*band_ne[b]/max(tot,1):5.1f}%")
    print()
    print("Top 30 characters:")
    top = chars.most_common(30)
    line = "  " + "  ".join(f"{repr(c)[1:-1] or c}:{n:,}" for c,n in top)
    print(line[:1000])

if __name__ == "__main__":
    main()
