#!/usr/bin/env python3
"""
Bootstrap Icons Subset Generator
Genera CSS y fuente optimizados solo con los iconos usados en roi-theme
"""

import re
import subprocess
import os

# Directorio base
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# Iconos usados en roi-theme (extraidos con grep)
USED_ICONS = [
    "bi-arrow-counterclockwise",
    "bi-arrow-down-circle",
    "bi-arrow-right",
    "bi-arrows-angle-expand",
    "bi-arrows-expand",
    "bi-arrows-fullscreen",
    "bi-arrows-move",
    "bi-arrows-vertical",
    "bi-arrow-up",
    "bi-aspect-ratio",
    "bi-badge-ad",
    "bi-bar-chart",
    "bi-bootstrap",
    "bi-bounding-box",
    "bi-box-arrow-up-right",
    "bi-calendar3",
    "bi-calendar-check",
    "bi-card-image",
    "bi-card-text",
    "bi-c-circle",
    "bi-chat-dots",
    "bi-chat-dots-fill",
    "bi-chat-quote",
    "bi-chat-text",
    "bi-check-circle",
    "bi-chevron-down",
    "bi-clock",
    "bi-code",
    "bi-code-slash",
    "bi-cursor",
    "bi-display",
    "bi-envelope",
    "bi-envelope-fill",
    "bi-envelope-paper",
    "bi-exclamation-octagon",
    "bi-exclamation-triangle",
    "bi-eye",
    "bi-facebook",
    "bi-file-earmark-text",
    "bi-file-text",
    "bi-filetype-css",
    "bi-filetype-js",
    "bi-folder-fill",
    "bi-fonts",
    "bi-gear",
    "bi-geo-alt-fill",
    "bi-globe",
    "bi-graph-up",
    "bi-grid",
    "bi-grid-3x3-gap",
    "bi-hand-index",
    "bi-hourglass",
    "bi-hourglass-split",
    "bi-image",
    "bi-info-circle",
    "bi-input-cursor",
    "bi-input-cursor-text",
    "bi-instagram",
    "bi-key",
    "bi-layout-sidebar",
    "bi-layout-text-window-reverse",
    "bi-lightning",
    "bi-lightning-charge-fill",
    "bi-link",
    "bi-link-45deg",
    "bi-linkedin",
    "bi-list",
    "bi-list-nested",
    "bi-list-ol",
    "bi-list-ul",
    "bi-magic",
    "bi-megaphone",
    "bi-megaphone-fill",
    "bi-menu-button-wide",
    "bi-mouse",
    "bi-palette",
    "bi-person",
    "bi-person-lines-fill",
    "bi-phone",
    "bi-pin",
    "bi-power",
    "bi-send-fill",
    "bi-share",
    "bi-shield-check",
    "bi-shield-lock",
    "bi-shield-x",
    "bi-slash-circle",
    "bi-sliders",
    "bi-square",
    "bi-star",
    "bi-star-fill",
    "bi-stars",
    "bi-tablet",
    "bi-tag",
    "bi-tags",
    "bi-telephone-fill",
    "bi-text-center",
    "bi-text-paragraph",
    "bi-three-dots",
    "bi-toggle-on",
    "bi-twitter-x",
    "bi-type",
    "bi-whatsapp",
    "bi-x-circle",
]

def read_original_css():
    """Lee el CSS original de Bootstrap Icons"""
    css_path = os.path.join(BASE_DIR, "bootstrap-icons.min.css")
    with open(css_path, "r", encoding="utf-8") as f:
        return f.read()

def extract_unicode_codes(css_content, icons):
    """Extrae los codigos unicode de los iconos usados"""
    codes = {}
    for icon in icons:
        # Buscar .bi-nombre::before{content:"\XXXX"}
        pattern = rf'\.{re.escape(icon)}::before\{{content:"\\([a-f0-9]+)"\}}'
        match = re.search(pattern, css_content, re.IGNORECASE)
        if match:
            codes[icon] = match.group(1)
        else:
            print(f"WARNING: No se encontro codigo para {icon}")
    return codes

def generate_subset_css(codes):
    """Genera el CSS subset con solo los iconos usados"""
    css_lines = []

    # Header
    css_lines.append("/*!")
    css_lines.append(" * Bootstrap Icons Subset - ROI Theme")
    css_lines.append(f" * {len(codes)} iconos de 2050 originales ({len(codes)/2050*100:.1f}%)")
    css_lines.append(" * Generado automaticamente - NO EDITAR")
    css_lines.append(" */")

    # @font-face con font-display: swap
    css_lines.append('@font-face{')
    css_lines.append('  font-display:swap;')
    css_lines.append('  font-family:bootstrap-icons;')
    css_lines.append('  src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),')
    css_lines.append('      url("fonts/bootstrap-icons-subset.woff") format("woff")')
    css_lines.append('}')

    # Estilos base para .bi
    css_lines.append('.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{')
    css_lines.append('  display:inline-block;')
    css_lines.append('  font-family:bootstrap-icons!important;')
    css_lines.append('  font-style:normal;')
    css_lines.append('  font-weight:400!important;')
    css_lines.append('  font-variant:normal;')
    css_lines.append('  text-transform:none;')
    css_lines.append('  line-height:1;')
    css_lines.append('  vertical-align:-.125em;')
    css_lines.append('  -webkit-font-smoothing:antialiased;')
    css_lines.append('  -moz-osx-font-smoothing:grayscale')
    css_lines.append('}')

    # Reglas para cada icono
    for icon, code in sorted(codes.items()):
        css_lines.append(f'.{icon}::before{{content:"\\{code}"}}')

    return '\n'.join(css_lines)

def generate_minified_css(codes):
    """Genera CSS minificado"""
    parts = []

    # @font-face
    parts.append('@font-face{font-display:swap;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),url("fonts/bootstrap-icons-subset.woff") format("woff")}')

    # Estilos base
    parts.append('.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}')

    # Iconos
    icon_rules = [f'.{icon}::before{{content:"\\{code}"}}' for icon, code in sorted(codes.items())]
    parts.append(''.join(icon_rules))

    return ''.join(parts)

def create_font_subset(codes):
    """Crea subset de la fuente usando pyftsubset"""
    # Crear archivo con unicodes
    unicodes = ','.join([f'U+{code}' for code in codes.values()])

    # Paths
    woff2_src = os.path.join(BASE_DIR, "fonts", "bootstrap-icons.woff2")
    woff2_dst = os.path.join(BASE_DIR, "fonts", "bootstrap-icons-subset.woff2")
    woff_src = os.path.join(BASE_DIR, "fonts", "bootstrap-icons.woff")
    woff_dst = os.path.join(BASE_DIR, "fonts", "bootstrap-icons-subset.woff")

    # Crear subset woff2
    print(f"Creando subset woff2 con {len(codes)} glyphs...")
    cmd_woff2 = [
        "pyftsubset",
        woff2_src,
        f"--unicodes={unicodes}",
        f"--output-file={woff2_dst}",
        "--flavor=woff2"
    ]
    subprocess.run(cmd_woff2, check=True)

    # Crear subset woff
    print(f"Creando subset woff con {len(codes)} glyphs...")
    cmd_woff = [
        "pyftsubset",
        woff_src,
        f"--unicodes={unicodes}",
        f"--output-file={woff_dst}",
        "--flavor=woff"
    ]
    subprocess.run(cmd_woff, check=True)

    # Mostrar tamanos
    orig_size = os.path.getsize(woff2_src) / 1024
    new_size = os.path.getsize(woff2_dst) / 1024
    print(f"woff2: {orig_size:.1f} KB -> {new_size:.1f} KB ({(1-new_size/orig_size)*100:.1f}% reduccion)")

def main():
    print("=== Bootstrap Icons Subset Generator ===\n")

    # 1. Leer CSS original
    print("1. Leyendo CSS original...")
    css_content = read_original_css()

    # 2. Extraer codigos unicode
    print(f"2. Extrayendo codigos de {len(USED_ICONS)} iconos...")
    codes = extract_unicode_codes(css_content, USED_ICONS)
    print(f"   Encontrados: {len(codes)} iconos")

    # 3. Generar CSS subset
    print("3. Generando CSS subset...")
    subset_css = generate_subset_css(codes)
    css_path = os.path.join(BASE_DIR, "bootstrap-icons-subset.css")
    with open(css_path, "w", encoding="utf-8") as f:
        f.write(subset_css)
    print(f"   Guardado: bootstrap-icons-subset.css")

    # 4. Generar CSS minificado
    print("4. Generando CSS minificado...")
    min_css = generate_minified_css(codes)
    min_path = os.path.join(BASE_DIR, "bootstrap-icons-subset.min.css")
    with open(min_path, "w", encoding="utf-8") as f:
        f.write(min_css)
    orig_css_size = os.path.getsize(os.path.join(BASE_DIR, "bootstrap-icons.min.css")) / 1024
    new_css_size = os.path.getsize(min_path) / 1024
    print(f"   CSS: {orig_css_size:.1f} KB -> {new_css_size:.1f} KB ({(1-new_css_size/orig_css_size)*100:.1f}% reduccion)")

    # 5. Crear font subset
    print("5. Creando font subset...")
    try:
        create_font_subset(codes)
    except Exception as e:
        print(f"   ERROR: {e}")
        print("   Intenta ejecutar: pip install fonttools brotli")
        return

    print("\n=== COMPLETADO ===")
    print("Archivos generados:")
    print("  - bootstrap-icons-subset.css (legible)")
    print("  - bootstrap-icons-subset.min.css (minificado)")
    print("  - fonts/bootstrap-icons-subset.woff2")
    print("  - fonts/bootstrap-icons-subset.woff")

if __name__ == "__main__":
    main()
