#!/usr/bin/env python3
"""Inventario compacto de una carpeta de material (PDFs, audio, video).

Saca un arbol con tamanos y un histograma de extensiones por carpeta,
mas la lista de nombres de PDF. Con eso se puede triar sin abrir nada.

    python inventario.py "RUTA" > inventario.txt
"""
import argparse
import os
from collections import Counter

AUDIO = {".mp3", ".wav", ".m4a", ".ogg", ".wma", ".aac", ".flac"}
VIDEO = {".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv"}
DOC = {".pdf", ".doc", ".docx", ".ppt", ".pptx", ".xls", ".xlsx"}


def human(n):
    for unit in ("B", "KB", "MB", "GB", "TB"):
        if n < 1024:
            return f"{n:.0f}{unit}" if unit == "B" else f"{n:.1f}{unit}"
        n /= 1024
    return f"{n:.1f}PB"


def scan(root):
    """Devuelve {dir: (size, Counter(ext), [nombres pdf])} solo de archivos directos."""
    data = {}
    for dirpath, _dirnames, filenames in os.walk(root):
        size = 0
        exts = Counter()
        pdfs = []
        for fn in filenames:
            ext = os.path.splitext(fn)[1].lower()
            try:
                size += os.path.getsize(os.path.join(dirpath, fn))
            except OSError:
                pass
            exts[ext] += 1
            if ext == ".pdf":
                pdfs.append(fn)
        data[dirpath] = (size, exts, sorted(pdfs))
    return data


def totals(data, dirpath):
    """Suma recursiva de tamano y numero de archivos bajo dirpath."""
    size = files = 0
    prefix = dirpath + os.sep
    for d, (s, e, _) in data.items():
        if d == dirpath or d.startswith(prefix):
            size += s
            files += sum(e.values())
    return size, files


def kind_summary(exts):
    audio = sum(n for e, n in exts.items() if e in AUDIO)
    video = sum(n for e, n in exts.items() if e in VIDEO)
    pdf = exts.get(".pdf", 0)
    doc = sum(n for e, n in exts.items() if e in DOC and e != ".pdf")
    otros = sum(exts.values()) - audio - video - pdf - doc
    partes = []
    for etiqueta, n in (("pdf", pdf), ("audio", audio), ("video", video),
                        ("doc", doc), ("otros", otros)):
        if n:
            partes.append(f"{n} {etiqueta}")
    return ", ".join(partes)


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("root")
    ap.add_argument("--max-depth", type=int, default=4)
    ap.add_argument("--no-pdf-names", action="store_true")
    args = ap.parse_args()

    root = os.path.abspath(args.root)
    data = scan(root)
    base_depth = root.count(os.sep)

    size, files = totals(data, root)
    print(f"RAIZ: {root}")
    print(f"TOTAL: {human(size)}, {files} archivos, {len(data)} carpetas\n")

    print("=== ARBOL ===")
    for d in sorted(data):
        depth = d.count(os.sep) - base_depth
        if depth > args.max_depth:
            continue
        s, files_here = totals(data, d)
        nombre = os.path.basename(d) or root
        resumen = kind_summary(data[d][1])
        linea = f"{'  ' * depth}{nombre}/  [{human(s)}, {files_here} arch.]"
        if resumen:
            linea += f"  -> aqui: {resumen}"
        print(linea)

    if not args.no_pdf_names:
        print("\n=== PDFs POR CARPETA ===")
        for d in sorted(data):
            pdfs = data[d][2]
            if not pdfs:
                continue
            print(f"\n{os.path.relpath(d, root)}")
            for fn in pdfs:
                print(f"  - {fn}")


if __name__ == "__main__":
    main()
