import streamlit as st
import streamlit.components.v1 as components
import time
import urllib.request
import urllib.error
import os
import re
import io
import base64
import tempfile
import shutil
from html.parser import HTMLParser
from urllib.parse import quote

from reportlab.lib.pagesizes import letter
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image as RLImage, PageBreak
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors


# --- CONFIGURACIÓN BASE ---
BASE_URL = "https://iglam.cl/all"
MAX_PAGINAS = 15
TIMEOUT = 10
INTENTOS = 3
RUTA_LOGO_DEFECTO = "logo.png"


# --- CONFIGURACIÓN DE PÁGINA ---
st.set_page_config(
    page_title="Generador de Catálogo",
    page_icon="🛍️",
    layout="wide",
    initial_sidebar_state="expanded",
)


# --- CSS ---
st.markdown("""
<style>
    .stApp { background-color: #F5EFE7; font-family: 'Segoe UI', 'Helvetica Neue', -apple-system, sans-serif; }
    .block-container { padding: 1.5rem 2.5rem !important; max-width: 1150px !important; }
    [data-testid="stAppViewContainer"], [data-testid="stHeader"], section.main, .main { background-color: #F5EFE7 !important; }
    h1, h2, h3 { color: #4A3428 !important; font-family: 'Georgia', serif !important; }
    h1 { font-weight: 700 !important; font-size: clamp(1.6rem, 3vw, 2.4rem) !important; line-height: 1.15 !important; margin: 0 !important; }
    h2 { font-weight: 600 !important; font-size: clamp(1rem, 1.8vw, 1.15rem) !important; margin: 0.3rem 0 !important; }
    h3 { font-weight: 600 !important; font-size: clamp(0.9rem, 1.5vw, 1rem) !important; margin: 0.4rem 0 0.3rem 0 !important; padding-bottom: 0.2rem !important; border-bottom: 1px solid #E8DFD3 !important; }
    p, label, .stMarkdown, .stText, span { color: #4A3428 !important; font-size: clamp(0.78rem, 1.1vw, 0.88rem) !important; line-height: 1.4 !important; }
    .hero-container { display: flex; align-items: center; gap: 2rem; padding: 1rem 0 1.5rem 0; border-bottom: 2px solid #E8DFD3; margin-bottom: 1.5rem; }
    .hero-logo { flex-shrink: 0; width: 140px; height: 140px; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 14px rgba(74, 52, 40, 0.15); background-color: #FFFFFF; display: flex; align-items: center; justify-content: center; }
    .hero-logo img { width: 100%; height: 100%; object-fit: contain; }
    .hero-text { flex: 1; min-width: 0; }
    .hero-title { font-family: 'Georgia', serif; font-weight: 700; font-size: 2.6rem; line-height: 1.1; color: #4A3428; margin: 0 0 0.4rem 0; letter-spacing: -0.5px; }
    .hero-subtitle { font-family: 'Segoe UI', sans-serif; font-size: 0.95rem; color: #8A7868; margin: 0; font-weight: 400; }
    .hero-accent { display: inline-block; width: 45px; height: 3px; background-color: #8B6F47; margin-bottom: 0.6rem; border-radius: 2px; }
    [data-testid="stSidebar"] { background-color: #FFFFFF !important; border-right: 1px solid #E8DFD3 !important; padding-top: 0 !important; }
    [data-testid="stSidebar"] > div:first-child { padding: 0.5rem 1.2rem 1rem 1.2rem !important; }
    [data-testid="stSidebar"] [data-testid="stSidebarContent"] { padding-top: 0 !important; }
    [data-testid="stSidebar"] [data-testid="stSidebarUserContent"] { padding-top: 0 !important; }
    [data-testid="stSidebar"] [data-testid="stSidebarHeader"] { padding: 0.3rem 0.5rem !important; height: auto !important; min-height: 0 !important; }
    [data-testid="stSidebar"] .stElementContainer, [data-testid="stSidebar"] .element-container { margin-bottom: 0.6rem !important; }
    [data-testid="stSidebar"] h3 { font-family: 'Georgia', serif !important; font-size: 1.05rem !important; color: #4A3428 !important; border-bottom: 2px solid #E8DFD3 !important; padding: 0 0 0.5rem 0 !important; margin: 0 0 0.8rem 0 !important; font-weight: 700 !important; }
    [data-testid="stSidebar"] h4 { font-family: 'Segoe UI', sans-serif !important; font-size: 0.88rem !important; color: #8B6F47 !important; margin: 0.8rem 0 0.4rem 0 !important; font-weight: 700 !important; }
    .stTextInput > label { color: #4A3428 !important; font-weight: 600 !important; font-size: 0.78rem !important; margin-bottom: 0.25rem !important; }
    .stTextInput div[data-baseweb="input"], .stTextInput div[data-baseweb="base-input"] { background-color: #FFFFFF !important; border: 1px solid #E0D4C2 !important; border-radius: 8px !important; overflow: hidden !important; height: 42px !important; box-sizing: border-box !important; box-shadow: none !important; }
    .stTextInput div[data-baseweb="input"]:focus-within { border-color: #8B6F47 !important; box-shadow: 0 0 0 3px rgba(139, 111, 71, 0.15) !important; }
    .stTextInput div[data-baseweb="input"] input { background-color: transparent !important; border: none !important; color: #4A3428 !important; font-size: 0.88rem !important; padding: 0 14px !important; }
    [data-testid="stSidebar"] .stTextInput input[disabled] { background-color: #FAF6F1 !important; color: #8B6F47 !important; font-weight: 700 !important; text-align: center !important; cursor: default !important; opacity: 1 !important; -webkit-text-fill-color: #8B6F47 !important; font-size: 0.88rem !important; padding: 0 4px !important; }
    [data-testid="stSidebar"] [data-testid="stHorizontalBlock"] { align-items: flex-start !important; gap: 0.4rem !important; margin: 0 !important; }
    [data-testid="stSidebar"] [data-testid="stHorizontalBlock"] [data-testid="column"] { padding: 0 !important; }
    .stButton > button { background-color: #8B6F47 !important; color: #FFFFFF !important; border: none !important; border-radius: 8px !important; font-weight: 600 !important; font-size: 0.85rem !important; padding: 8px 16px !important; min-height: 40px !important; transition: all 0.15s ease !important; }
    .stButton > button:hover { background-color: #6F5738 !important; transform: translateY(-1px) !important; }
    .stButton > button[kind="primary"] { background-color: #8B6F47 !important; color: #FFFFFF !important; font-size: 0.9rem !important; padding: 10px 22px !important; font-weight: 700 !important; min-height: 44px !important; border-radius: 10px !important; }
    .stDownloadButton > button { background-color: #5E7B42 !important; color: #FFFFFF !important; border: none !important; border-radius: 10px !important; font-weight: 700 !important; font-size: 0.9rem !important; padding: 10px 22px !important; min-height: 46px !important; width: 100% !important; }
    .stDownloadButton > button:hover { background-color: #4A6433 !important; }
    .stRadio > label { font-size: 0.78rem !important; font-weight: 600 !important; color: #4A3428 !important; margin-bottom: 0.25rem !important; }
    .stRadio [role="radiogroup"] label { font-size: 0.85rem !important; padding: 0.25rem 0 !important; color: #4A3428 !important; }
    .stAlert { border-radius: 8px !important; padding: 0.5rem 0.7rem !important; font-size: 0.82rem !important; }
    .stProgress > div > div > div { background-color: #8B6F47 !important; }
    .stCaption, small { color: #8A7868 !important; font-size: 0.75rem !important; display: block !important; }
    .contador-ok { color: #2E7D32 !important; font-weight: 600 !important; font-size: 0.78rem !important; }
    .contador-error { color: #C62828 !important; font-weight: 600 !important; font-size: 0.78rem !important; }
    @keyframes pulso-alerta { 0%, 100% { background-color: #FFF3CD; border-color: #FFB800; box-shadow: 0 0 0 0 rgba(255, 184, 0, 0.7); } 50% { background-color: #FFE69C; border-color: #D97706; box-shadow: 0 0 18px 5px rgba(255, 184, 0, 0.55); } }
    @keyframes icono-salta { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
    .alerta-whatsapp { display: flex; align-items: center; gap: 12px; background-color: #FFF3CD; border: 2px solid #FFB800; border-radius: 12px; padding: 16px 20px; color: #7A4E1B; font-weight: 600; font-size: 0.95rem; margin: 15px 0; animation: pulso-alerta 1.5s ease-in-out infinite; }
    .alerta-whatsapp .icono { font-size: 1.8rem; display: inline-block; animation: icono-salta 1s ease-in-out infinite; }
    .alerta-whatsapp strong { color: #C2410C; font-weight: 800; }
    .stat-box { background-color: #FAF6F1; border-left: 4px solid #8B6F47; border-radius: 8px; padding: 12px 18px; color: #4A3428; margin: 10px 0; font-size: 0.88rem; }
    .stat-box b { color: #8B6F47; font-size: 1.05rem; }
    .paso-titulo { display: flex; align-items: center; gap: 0.8rem; margin: 1.8rem 0 0.9rem 0; padding-bottom: 0.6rem; border-bottom: 1px solid #E8DFD3; }
    .paso-numero { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; background-color: #8B6F47; color: #FFFFFF; font-weight: 700; font-size: 1rem; border-radius: 50%; flex-shrink: 0; }
    .paso-texto { font-family: 'Georgia', serif; font-weight: 700; font-size: 1.2rem; color: #4A3428; }
    @media screen and (max-width: 767px) {
        .hero-container { flex-direction: column; text-align: center; gap: 1rem; }
        .hero-logo { width: 110px; height: 110px; }
        .hero-title { font-size: 1.6rem; text-align: center; }
    }
</style>
""", unsafe_allow_html=True)


# --- PARSER ---
class ProductoListParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.productos = []
        self.producto = None
        self.captura = None
        self.texto = []

    def handle_starttag(self, tag, attrs):
        atributos = dict(attrs)
        clases = atributos.get("class", "").split()
        if tag == "article" and "product-block" in clases:
            self.producto = {"Producto": "Sin titulo", "Marca": "N/A", "Precio": "", "Imagen": ""}
        elif self.producto and tag == "a" and "product-block__name" in clases:
            self.captura = (tag, "Producto")
            self.texto = []
        elif self.producto and tag == "span" and "product-block__brand" in clases:
            self.captura = (tag, "Marca")
            self.texto = []
        elif self.producto and tag == "div" and "product-block__price" in clases:
            self.captura = (tag, "Precio")
            self.texto = []
        elif self.producto and tag == "img":
            img_url = atributos.get("src") or atributos.get("data-src") or ""
            if img_url:
                if img_url.startswith("//"):
                    img_url = "https:" + img_url
                if "icon" not in img_url and not self.producto["Imagen"]:
                    self.producto["Imagen"] = img_url

    def handle_data(self, data):
        if self.captura:
            self.texto.append(data)

    def handle_endtag(self, tag):
        if self.captura and self.captura[0] == tag:
            texto_capturado = " ".join("".join(self.texto).split())
            if self.captura[1] == "Precio":
                self.producto["Precio"] += " " + texto_capturado
            else:
                self.producto[self.captura[1]] = texto_capturado
            if self.captura[1] != "Precio" or tag == "div":
                self.captura = None
                self.texto = []
        elif tag == "article" and self.producto:
            if not self.producto.get("Precio"):
                self.producto["Precio"] = "0"
            self.productos.append(self.producto)
            self.producto = None


# --- FUNCIONES AUXILIARES ---
def analizar_genero_y_notas(titulo_prod, marca_prod):
    texto_total = f"{titulo_prod} {marca_prod}".lower()
    if any(t in texto_total for t in ["homme", "man", "men", "caballero", "for men", "pour homme", "invictus", "sauvage", "le male"]):
        genero = "Hombre"
    elif any(t in texto_total for t in ["femme", "woman", "women", "dama", "for women", "pour femme", "good girl", "la vie est belle"]):
        genero = "Mujer"
    elif "unisex" in texto_total or "genderless" in texto_total:
        genero = "Unisex"
    else:
        genero = "Unisex / Versatil"

    if any(t in texto_total for t in ["intense", "parfum", "elixir", "oud"]):
        notas = "Amaderada / Especiada / Intensa"
    elif any(t in texto_total for t in ["sport", "fresh", "aqua", "water", "blue"]):
        notas = "Citrica / Acuatica / Fresca"
    elif any(t in texto_total for t in ["floral", "rose", "blossom", "flor"]):
        notas = "Floral / Dulce / Luminosa"
    elif any(t in texto_total for t in ["sweet", "vanilla", "honey", "caramel"]):
        notas = "Oriental / Dulce / Avainillada"
    else:
        notas = "Aromatica / Acorde equilibrado"
    return genero, notas


def obtener_productos(url):
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
    req = urllib.request.Request(url, headers=headers)
    for intento in range(1, INTENTOS + 1):
        try:
            with urllib.request.urlopen(req, timeout=TIMEOUT) as response:
                html = response.read().decode("utf-8", errors="replace")
            parser = ProductoListParser()
            parser.feed(html)
            return parser.productos
        except (urllib.error.URLError, TimeoutError) as err:
            if intento == INTENTOS:
                raise err
            time.sleep(1)
    return []


def normalizar_titulo(titulo):
    if not titulo:
        return ""
    t = titulo.lower()
    t = re.sub(r'\s+', ' ', t).strip()
    t = re.sub(r'[\.\,\;\:\-\_\|\/\(\)\[\]]+', ' ', t)
    t = re.sub(r'\s+', ' ', t).strip()
    return t


def eliminar_duplicados(todos_los_productos):
    unicos = {}
    duplicados = 0
    for prod in todos_los_productos:
        clave = normalizar_titulo(prod["Producto"])
        if clave in unicos:
            duplicados += 1
            existente = unicos[clave]
            if prod["Precio Costo"] < existente["Precio Costo"]:
                unicos[clave] = prod
        else:
            unicos[clave] = prod
    return list(unicos.values()), duplicados


def descargar_imagen_temp(img_url, carpeta_temp, nombre_archivo):
    if not img_url:
        return None
    try:
        if "?" in img_url:
            img_url = img_url.split("?")[0]
        ruta = os.path.join(carpeta_temp, nombre_archivo)
        req = urllib.request.Request(img_url, headers={"User-Agent": "Mozilla/5.0"})
        with urllib.request.urlopen(req, timeout=8) as resp, open(ruta, "wb") as f:
            f.write(resp.read())
        if os.path.getsize(ruta) < 200:
            return None
        return ruta
    except Exception:
        return None


def ordenar_productos(productos, criterio):
    if criterio == "Alfabético (A-Z)":
        return sorted(productos, key=lambda p: p["Producto"].lower())
    elif criterio == "Precio: menor a mayor":
        return sorted(productos, key=lambda p: p["Precio Costo"])
    elif criterio == "Precio: mayor a menor":
        return sorted(productos, key=lambda p: -p["Precio Costo"])
    elif criterio == "Ofertas primero":
        return sorted(productos, key=lambda p: (0 if p["En Oferta"].upper() in ("SI", "SÍ") else 1, p["Producto"].lower()))
    return productos


def agrupar_productos(productos, criterio):
    if criterio == "Sin agrupar":
        return [("", productos)]
    grupos = {}
    for p in productos:
        if criterio == "Por marca":
            clave = p["Categoria"] or "Sin Marca"
        elif criterio == "Por género":
            clave = p["Genero"] or "Sin Género"
        elif criterio == "Por rango de precio":
            precio = p["Precio Costo"]
            if precio < 20000:
                clave = "Económicos (menos de $20.000)"
            elif precio < 50000:
                clave = "Medios ($20.000 - $50.000)"
            else:
                clave = "Premium (más de $50.000)"
        else:
            clave = ""
        grupos.setdefault(clave, []).append(p)
    if criterio == "Por rango de precio":
        orden = ["Económicos (menos de $20.000)", "Medios ($20.000 - $50.000)", "Premium (más de $50.000)"]
        return [(n, grupos.get(n, [])) for n in orden if n in grupos]
    return sorted(grupos.items(), key=lambda x: x[0].lower())


# --- PDF ---
def dibujar_fondo(canvas_obj, doc_obj):
    if doc_obj.page == 1:
        return
    canvas_obj.saveState()
    ancho, alto = letter
    pasos = 50
    c_ini = colors.HexColor('#E8DDD0')
    c_fin = colors.HexColor('#F5EEE5')
    for i in range(pasos):
        y = (alto / pasos) * i
        h = alto / pasos + 1
        r = c_ini.red + (c_fin.red - c_ini.red) * (i / pasos)
        g = c_ini.green + (c_fin.green - c_ini.green) * (i / pasos)
        b = c_ini.blue + (c_fin.blue - c_ini.blue) * (i / pasos)
        canvas_obj.setFillColor(colors.Color(r, g, b))
        canvas_obj.rect(0, y, ancho, h, fill=1, stroke=0)
    canvas_obj.setStrokeColor(colors.HexColor('#8B6F47'))
    canvas_obj.setLineWidth(1.5)
    canvas_obj.rect(20, 20, ancho - 40, alto - 40)
    canvas_obj.setStrokeColor(colors.HexColor('#C5A059'))
    canvas_obj.setLineWidth(0.5)
    canvas_obj.rect(24, 24, ancho - 48, alto - 48)
    canvas_obj.setFont("Helvetica", 8)
    canvas_obj.setFillColor(colors.HexColor('#6B4F3A'))
    canvas_obj.drawRightString(ancho - 35, 32, f"Pagina {canvas_obj._pageNumber}")
    canvas_obj.drawString(35, 32, "Coleccion Exclusiva de Perfumeria Fina")
    canvas_obj.restoreState()


def dibujar_portada(canvas_obj, doc_obj):
    canvas_obj.saveState()
    ancho, alto = letter
    canvas_obj.setFillColor(colors.HexColor('#4A3428'))
    canvas_obj.rect(0, 0, ancho, alto, fill=1, stroke=0)
    canvas_obj.setStrokeColor(colors.HexColor('#D4AF37'))
    canvas_obj.setLineWidth(2)
    canvas_obj.rect(30, 30, ancho - 60, alto - 60)
    canvas_obj.setLineWidth(0.5)
    canvas_obj.rect(36, 36, ancho - 72, alto - 72)
    canvas_obj.restoreState()


def generar_pdf(todos_los_productos, nombre_vendedor, telefono_whatsapp, ruta_logo=None,
                agrupacion="Sin agrupar", ordenamiento="Alfabético (A-Z)"):
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=letter, rightMargin=35, leftMargin=35, topMargin=40, bottomMargin=45)
    styles = getSampleStyleSheet()

    estilo_titulo = ParagraphStyle('T', parent=styles['Normal'], fontName='Helvetica-Bold', fontSize=22, leading=26, textColor=colors.HexColor('#FFFFFF'), alignment=1, spaceAfter=4)
    estilo_sub = ParagraphStyle('S', parent=styles['Normal'], fontName='Helvetica', fontSize=9.5, leading=13, textColor=colors.HexColor('#D4AF37'), alignment=1)
    estilo_prod_nombre = ParagraphStyle('PN', parent=styles['Normal'], fontName='Helvetica-Bold', fontSize=9.5, leading=13, textColor=colors.HexColor('#4A3428'), alignment=1)
    estilo_prod_info = ParagraphStyle('PI', parent=styles['Normal'], fontName='Helvetica', fontSize=7, leading=9, textColor=colors.HexColor('#6B4F3A'), alignment=1)
    estilo_prod_precio = ParagraphStyle('PP', parent=styles['Normal'], fontName='Helvetica-Bold', fontSize=10, leading=13, textColor=colors.HexColor('#8B6F47'), alignment=1)
    estilo_oferta = ParagraphStyle('O', parent=styles['Normal'], fontName='Helvetica-Bold', fontSize=8.5, leading=11, textColor=colors.HexColor('#D9534F'), alignment=1)
    estilo_boton = ParagraphStyle('B', parent=styles['Normal'], fontName='Helvetica-Bold', fontSize=8, leading=10, textColor=colors.HexColor('#25D366'), alignment=1)
    estilo_portada_titulo = ParagraphStyle('PT', fontName='Helvetica-Bold', fontSize=24, leading=30, textColor=colors.HexColor('#D4AF37'), alignment=1)
    estilo_portada_sub = ParagraphStyle('PS', fontName='Helvetica', fontSize=12, leading=16, textColor=colors.HexColor('#F5EEE5'), alignment=1)
    estilo_seccion = ParagraphStyle('SEC', fontName='Helvetica-Bold', fontSize=14, leading=18, textColor=colors.HexColor('#FFFFFF'), alignment=0)
    estilo_bienv_titulo = ParagraphStyle('BT', fontName='Helvetica-Bold', fontSize=22, leading=26, textColor=colors.HexColor('#8B6F47'), alignment=1, spaceAfter=8)
    estilo_bienv_sub = ParagraphStyle('BS', fontName='Helvetica-Oblique', fontSize=11, leading=15, textColor=colors.HexColor('#4A3428'), alignment=1, spaceAfter=10)
    estilo_bienv_texto = ParagraphStyle('BTX', fontName='Helvetica', fontSize=10, leading=14, textColor=colors.HexColor('#4A3428'), alignment=0, spaceAfter=6)
    # CORREGIDO: el título del paso ahora es café oscuro para que se vea sobre fondo claro
    estilo_paso_titulo = ParagraphStyle('PT2', fontName='Helvetica-Bold', fontSize=11.5, leading=15, textColor=colors.HexColor('#4A3428'), alignment=0)
    estilo_paso_texto = ParagraphStyle('PTX', fontName='Helvetica', fontSize=9.5, leading=13, textColor=colors.HexColor('#4A3428'), alignment=0)
    estilo_cta_titulo = ParagraphStyle('CT', fontName='Helvetica-Bold', fontSize=15, leading=20, textColor=colors.HexColor('#FFFFFF'), alignment=1)

    elementos = []

    # PORTADA
    portada_elementos = [Spacer(1, 60)]
    if ruta_logo and os.path.exists(ruta_logo):
        try:
            logo_img = RLImage(ruta_logo, width=140, height=140)
            logo_img.hAlign = 'CENTER'
            portada_elementos.append(logo_img)
            portada_elementos.append(Spacer(1, 25))
        except Exception:
            pass
    portada_elementos.extend([
        Paragraph("COLECCION EXCLUSIVA", estilo_portada_sub),
        Spacer(1, 15),
        Paragraph("CATALOGO DE PERFUMERIA FINA", estilo_portada_titulo),
        Spacer(1, 10),
        Paragraph("Esencias a medida - Maxima Duracion y Elegancia", estilo_sub),
        Spacer(1, 130),
        Paragraph("Edicion 2026", estilo_portada_titulo),
    ])
    tabla_portada = Table([[portada_elementos]], colWidths=[540])
    tabla_portada.setStyle(TableStyle([('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE')]))
    elementos.append(tabla_portada)
    elementos.append(PageBreak())

    # BIENVENIDA
    elementos.append(Spacer(1, 5))
    elementos.append(Paragraph("¡DESCUBRE TU PROXIMA FRAGANCIA FAVORITA!", estilo_bienv_titulo))
    elementos.append(Spacer(1, 4))
    elementos.append(Paragraph("Un gran perfume no es solo un aroma: es tu marca personal, esa estela inolvidable que dejas al pasar.", estilo_bienv_sub))
    elementos.append(Spacer(1, 8))

    intro = [[Paragraph("En este catalogo se ha reunido una cuidadosa seleccion inspirada en las fragancias de alta gama mas iconicas del mundo.", estilo_bienv_texto)]]
    tabla_intro = Table(intro, colWidths=[500])
    tabla_intro.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#FFFFFF')), ('BOX', (0, 0), (-1, -1), 1, colors.HexColor('#E0D4C2')), ('PADDING', (0, 0), (-1, -1), 12)]))
    elementos.append(tabla_intro)
    elementos.append(Spacer(1, 15))

    cta_data = [[Paragraph("¿COMO HACER TU PEDIDO?", estilo_cta_titulo)]]
    tabla_cta = Table(cta_data, colWidths=[500])
    tabla_cta.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#8B6F47')), ('PADDING', (0, 0), (-1, -1), 12), ('ALIGN', (0, 0), (-1, -1), 'CENTER')]))
    elementos.append(tabla_cta)
    elementos.append(Spacer(1, 12))

    pasos = [
        ["1", "Encuentra tu fragancia", "Recorre el catalogo y encuentra los perfumes que te gusten."],
        ["2", "Pide un producto", "Haz clic en [ Pedir por WhatsApp ] del producto que quieras."],
        ["3", "Pide varios a la vez", "Anota los productos que te interesan y envia la lista por WhatsApp."],
        ["4", "Confirma tu pedido", "El vendedor te confirmara disponibilidad, total y los datos de pago."],
    ]
    for num, titulo_p, texto_p in pasos:
        num_para = Paragraph(f"<font color='#FFFFFF' size='14'><b>{num}</b></font>", ParagraphStyle('N', fontName='Helvetica-Bold', fontSize=14, leading=18, alignment=1, textColor=colors.HexColor('#FFFFFF')))
        cont_paso = Table([[Paragraph(titulo_p, estilo_paso_titulo)], [Paragraph(texto_p, estilo_paso_texto)]], colWidths=[440])
        cont_paso.setStyle(TableStyle([('LEFTPADDING', (0, 0), (-1, -1), 0), ('RIGHTPADDING', (0, 0), (-1, -1), 0), ('TOPPADDING', (0, 0), (0, 0), 0), ('BOTTOMPADDING', (0, 0), (0, 0), 3), ('TOPPADDING', (0, 1), (0, 1), 0), ('BOTTOMPADDING', (0, 1), (0, 1), 0)]))
        fila = Table([[num_para, cont_paso]], colWidths=[50, 450])
        fila.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (0, 0), colors.HexColor('#8B6F47')),
            ('BACKGROUND', (1, 0), (1, 0), colors.HexColor('#FAF6F1')),
            ('VALIGN', (0, 0), (0, 0), 'MIDDLE'),
            ('VALIGN', (1, 0), (1, 0), 'TOP'),
            ('ALIGN', (0, 0), (0, 0), 'CENTER'),
            ('LEFTPADDING', (1, 0), (1, 0), 14),
            ('RIGHTPADDING', (1, 0), (1, 0), 14),
            ('TOPPADDING', (0, 0), (-1, -1), 10),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 10),
            ('BOX', (0, 0), (-1, -1), 0.5, colors.HexColor('#E0D4C2')),
        ]))
        elementos.append(fila)
        elementos.append(Spacer(1, 8))

    elementos.append(PageBreak())

    header_data = [[Paragraph("CATALOGO DE PERFUMERIA", estilo_titulo)], [Paragraph("ESENCIAS A PEDIDO - ALTA CALIDAD Y DURACION", estilo_sub)]]
    header_table = Table(header_data, colWidths=[540])
    header_table.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#4A3428')), ('BOTTOMPADDING', (0, 0), (-1, -1), 14), ('TOPPADDING', (0, 0), (-1, -1), 16), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('BOTTOMBORDER', (0, 1), (-1, 1), 3, colors.HexColor('#D4AF37'))]))
    elementos.append(header_table)
    elementos.append(Spacer(1, 15))

    prods_ord = ordenar_productos(todos_los_productos, ordenamiento)
    grupos = agrupar_productos(prods_ord, agrupacion)

    def crear_card(prod):
        precio_fmt = f"${int(prod['Precio Costo']):,}".replace(",", ".")
        img_celda = Paragraph("<i>Sin Imagen</i>", estilo_prod_info)
        r = prod.get("ImagenRuta")
        if r and os.path.exists(r):
            try:
                img_celda = RLImage(r, width=60, height=60)
                img_celda.hAlign = 'CENTER'
            except Exception:
                img_celda = Paragraph("<i>Sin Imagen</i>", estilo_prod_info)
        mensaje = (f"Hola {nombre_vendedor}, me interesa:\n- {prod['Producto']}\nPrecio: {precio_fmt} CLP.\nConfirmas disponibilidad?")
        url_wsp = f"https://wa.me/{telefono_whatsapp}?text={quote(mensaje)}"
        contenido = [
            Spacer(1, 3), img_celda, Spacer(1, 4),
            Paragraph(prod["Producto"], estilo_prod_nombre), Spacer(1, 1),
            Paragraph(f"<b>Cat:</b> {prod['Categoria']} | <b>Genero:</b> {prod['Genero']}", estilo_prod_info), Spacer(1, 1),
            Paragraph(f"<b>Notas:</b> {prod['Notas Aroma']}", estilo_prod_info),
        ]
        if prod["En Oferta"].upper() in ("SI", "SÍ"):
            contenido.extend([Spacer(1, 2), Paragraph("OFERTA!", estilo_oferta)])
        contenido.extend([Spacer(1, 3), Paragraph(f"{precio_fmt} CLP", estilo_prod_precio), Spacer(1, 4), Paragraph(f'<a href="{url_wsp}"><b>[ Pedir por WhatsApp ]</b></a>', estilo_boton), Spacer(1, 3)])
        card = Table([[contenido]], colWidths=[172])
        card.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#FFFFFF')), ('BOX', (0, 0), (-1, -1), 1, colors.HexColor('#D4C4B0')), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('TOPPADDING', (0, 0), (-1, -1), 4), ('BOTTOMPADDING', (0, 0), (-1, -1), 4)]))
        return card

    for nombre_grupo, lista in grupos:
        if nombre_grupo:
            elementos.append(Spacer(1, 10))
            enc = Table([[Paragraph(f"◆ {nombre_grupo.upper()}", estilo_seccion)]], colWidths=[540])
            enc.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#8B6F47')), ('PADDING', (0, 0), (-1, -1), 10), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE')]))
            elementos.append(enc)
            elementos.append(Spacer(1, 10))
        filas, fila_act = [], []
        for prod in lista:
            fila_act.append(crear_card(prod))
            if len(fila_act) == 3:
                filas.append(fila_act)
                fila_act = []
        if fila_act:
            while len(fila_act) < 3:
                fila_act.append(Paragraph("", styles['Normal']))
            filas.append(fila_act)
        if filas:
            grilla = Table(filas, colWidths=[180, 180, 180])
            grilla.setStyle(TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('BOTTOMPADDING', (0, 0), (-1, -1), 6), ('TOPPADDING', (0, 0), (-1, -1), 6)]))
            elementos.append(grilla)
            elementos.append(Spacer(1, 10))

    # PÁGINA FINAL
    elementos.append(PageBreak())
    final_titulo = Table([[Paragraph("¿QUIERES PEDIR VARIOS PRODUCTOS?", estilo_cta_titulo)]], colWidths=[500])
    final_titulo.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#8B6F47')), ('PADDING', (0, 0), (-1, -1), 14), ('ALIGN', (0, 0), (-1, -1), 'CENTER')]))
    elementos.append(final_titulo)
    elementos.append(Spacer(1, 15))

    instrucciones = [
        [Paragraph("Sigue estos pasos:", ParagraphStyle('IF1', fontName='Helvetica-Bold', fontSize=11, leading=15, textColor=colors.HexColor('#4A3428'), alignment=0, spaceAfter=6))],
        [Paragraph("<b>1.</b> Anota en un papel o en tu telefono los nombres de los productos que te interesan (con el precio).", ParagraphStyle('IF2', fontName='Helvetica', fontSize=10, leading=14, textColor=colors.HexColor('#4A3428'), alignment=0, spaceAfter=5))],
        [Paragraph(f"<b>2.</b> Envia la lista por WhatsApp al numero <b>+{telefono_whatsapp}</b> con tu nombre y los productos.", ParagraphStyle('IF3', fontName='Helvetica', fontSize=10, leading=14, textColor=colors.HexColor('#4A3428'), alignment=0, spaceAfter=5))],
        [Paragraph("<b>3.</b> El vendedor te confirmara disponibilidad, el total y los datos para la transferencia.", ParagraphStyle('IF4', fontName='Helvetica', fontSize=10, leading=14, textColor=colors.HexColor('#4A3428'), alignment=0, spaceAfter=5))],
    ]
    tabla_instrucciones = Table(instrucciones, colWidths=[500])
    tabla_instrucciones.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#FFFFFF')),
        ('BOX', (0, 0), (-1, -1), 1, colors.HexColor('#E0D4C2')),
        ('PADDING', (0, 0), (-1, -1), 14),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elementos.append(tabla_instrucciones)
    elementos.append(Spacer(1, 20))

    mensaje_varios = (
        f"Hola {nombre_vendedor}, quiero hacer el siguiente pedido:\n\n"
        f"1. (Nombre del producto) - $ (precio)\n"
        f"2. (Nombre del producto) - $ (precio)\n"
        f"3. (Nombre del producto) - $ (precio)\n\n"
        f"¿Me confirmas disponibilidad y los datos para la transferencia?"
    )
    mensaje_varios_encoded = quote(mensaje_varios)
    url_varios = f"https://wa.me/{telefono_whatsapp}?text={mensaje_varios_encoded}"

    boton_varios_data = [[Paragraph(
        f'<a href="{url_varios}"><b>[ PEDIR VARIOS PRODUCTOS POR WHATSAPP ]</b></a>',
        ParagraphStyle('BotonVarios', fontName='Helvetica-Bold', fontSize=13, leading=18, textColor=colors.HexColor('#25D366'), alignment=1)
    )]]
    tabla_boton_varios = Table(boton_varios_data, colWidths=[500])
    tabla_boton_varios.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#FFFFFF')),
        ('BOX', (0, 0), (-1, -1), 2, colors.HexColor('#25D366')),
        ('PADDING', (0, 0), (-1, -1), 16),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ]))
    elementos.append(tabla_boton_varios)

    elementos.append(Spacer(1, 15))
    elementos.append(Paragraph(
        "¡Gracias por preferirnos! Estamos aqui para ayudarte a encontrar la fragancia perfecta.",
        ParagraphStyle('G', fontName='Helvetica-Oblique', fontSize=10, leading=14, textColor=colors.HexColor('#8B6F47'), alignment=1)
    ))

    doc.build(elementos, onFirstPage=dibujar_portada, onLaterPages=dibujar_fondo)
    buffer.seek(0)
    return buffer


# --- FUNCIÓN PRINCIPAL ---
def main():
    with st.sidebar:
        st.markdown("### ⚙️ Configuración")
        st.markdown("#### 👤 Vendedor")
        nombre_vendedor = st.text_input("Nombre", value="Roberto")
        st.markdown("#### 📱 WhatsApp")

        col_prefijo, col_numero = st.columns([1, 2], gap="small")
        with col_prefijo:
            st.text_input("Prefijo", value="+569", disabled=True, label_visibility="collapsed", key="prefijo_display")
        with col_numero:
            numero_local = st.text_input("Número", value="", max_chars=8, placeholder="88438256", label_visibility="collapsed", key="numero_input")

        solo_digitos = re.sub(r'\D', '', numero_local)
        if solo_digitos.startswith("569"):
            solo_digitos = solo_digitos[3:]
        cantidad_digitos = len(solo_digitos)
        telefono_valido = cantidad_digitos == 8
        telefono_whatsapp = "569" + solo_digitos
        telefono_display = "+569 " + solo_digitos if solo_digitos else "+569"

        if cantidad_digitos == 0:
            st.caption("✏️ Ingresa 8 dígitos")
        elif cantidad_digitos < 8:
            st.markdown(f'<span class="contador-error">⚠️ Faltan {8 - cantidad_digitos} dígitos</span>', unsafe_allow_html=True)
        else:
            st.markdown(f'<span class="contador-ok">✅ {telefono_display}</span>', unsafe_allow_html=True)

        productos = st.session_state.get("productos_cargados")
        if productos:
            st.markdown("---")
            st.markdown("#### 📄 Organización")
            agrupacion = st.radio("Agrupar por", options=["Sin agrupar", "Por marca", "Por género", "Por rango de precio"], index=0)
            ordenamiento = st.radio("Ordenar", options=["Alfabético (A-Z)", "Precio: menor a mayor", "Precio: mayor a menor", "Ofertas primero"], index=0)
        else:
            agrupacion = "Sin agrupar"
            ordenamiento = "Alfabético (A-Z)"

        st.markdown("---")
        if st.button("✅ Cerrar configuración", use_container_width=True):
            components.html("""
            <script>
            const parent = window.parent.document;
            const collapseBtn = parent.querySelector('[data-testid="stSidebarCollapseButton"] button');
            if (collapseBtn) { collapseBtn.click(); }
            </script>
            """, height=0)

    logo_b64 = None
    if os.path.exists(RUTA_LOGO_DEFECTO):
        try:
            with open(RUTA_LOGO_DEFECTO, "rb") as f:
                logo_b64 = base64.b64encode(f.read()).decode()
        except Exception:
            logo_b64 = None

    if logo_b64:
        st.markdown(f"""
        <div class="hero-container">
            <div class="hero-logo"><img src="data:image/png;base64,{logo_b64}" alt="Logo"></div>
            <div class="hero-text">
                <div class="hero-accent"></div>
                <div class="hero-title">Generador de Catálogo</div>
                <p class="hero-subtitle">Perfumería fina • Catálogo profesional en PDF listo para compartir con tus clientes</p>
            </div>
        </div>
        """, unsafe_allow_html=True)
    else:
        st.markdown("""
        <div class="hero-container">
            <div class="hero-text">
                <div class="hero-accent"></div>
                <div class="hero-title">🛍️ Generador de Catálogo</div>
                <p class="hero-subtitle">Perfumería fina • Catálogo profesional en PDF listo para compartir con tus clientes</p>
            </div>
        </div>
        """, unsafe_allow_html=True)

    productos = st.session_state.get("productos_cargados")

    st.markdown("""
    <div class="paso-titulo">
        <div class="paso-numero">1</div>
        <div class="paso-texto">Cargar productos del sitio</div>
    </div>
    """, unsafe_allow_html=True)
    st.caption("Extrae los productos de la tienda. Tarda 3-5 minutos y solo necesitas hacerlo una vez por sesión.")

    col_b1, col_b2 = st.columns([1, 3])
    with col_b1:
        if st.button("📥 Cargar productos", type="primary", use_container_width=True):
            progreso = st.progress(0)
            estado = st.empty()
            estado.info("Iniciando extracción de productos...")
            todos_los_productos = []
            pagina = 1
            carpeta_temp = tempfile.mkdtemp(prefix="catalogo_imgs_")
            try:
                while pagina <= MAX_PAGINAS:
                    url = f"{BASE_URL}?page={pagina}"
                    estado.write(f"📄 Descargando página {pagina} de {MAX_PAGINAS}...")
                    try:
                        prods = obtener_productos(url)
                        if not prods:
                            estado.info("No se encontraron más productos.")
                            break
                        for idx, producto in enumerate(prods):
                            titulo = producto.get("Producto", "Sin titulo")
                            marca = producto.get("Marca", "N/A")
                            genero_detectado, notas_detectadas = analizar_genero_y_notas(titulo, marca)
                            precio_raw = producto.get("Precio", "0")
                            precios_encontrados = re.findall(r'[\d\.]+', precio_raw.replace("$", ""))
                            valores_numericos = []
                            for p_str in precios_encontrados:
                                p_limpio = p_str.replace(".", "").strip()
                                try:
                                    val = float(p_limpio)
                                    if val > 100:
                                        valores_numericos.append(val)
                                except Exception:
                                    pass
                            if valores_numericos:
                                precio_costo = min(valores_numericos)
                                tiene_oferta = len(set(valores_numericos)) > 1 or (max(valores_numericos) > precio_costo)
                            else:
                                precio_costo = 0.0
                                tiene_oferta = False
                            img_url = producto.get("Imagen", "")
                            nombre_limpio = "".join(c for c in titulo if c.isalnum() or c in (' ', '_', '-')).strip()[:40] or f"prod_{pagina}_{idx}"
                            ruta_imagen = None
                            if img_url:
                                ruta_imagen = descargar_imagen_temp(img_url, carpeta_temp, f"{nombre_limpio}.jpg")
                            todos_los_productos.append({
                                "Producto": titulo,
                                "Precio Costo": precio_costo,
                                "Categoria": marca,
                                "Genero": genero_detectado,
                                "Notas Aroma": notas_detectadas,
                                "En Oferta": "SI" if tiene_oferta else "NO",
                                "ImagenRuta": ruta_imagen,
                            })
                        pagina += 1
                        progreso.progress(min(pagina / MAX_PAGINAS, 0.9))
                    except Exception as err:
                        st.error(f"Error en página {pagina}: {err}")
                        break
                if not todos_los_productos:
                    st.warning("No se pudieron extraer productos.")
                    return
                todos_los_productos, duplicados = eliminar_duplicados(todos_los_productos)
                st.session_state.productos_cargados = todos_los_productos
                imagenes_descargadas = sum(1 for p in todos_los_productos if p.get("ImagenRuta"))
                progreso.progress(1.0)
                estado.success(f"✅ {len(todos_los_productos)} productos cargados ({imagenes_descargadas} con imagen).")
                if duplicados > 0:
                    st.info(f"🧹 Se eliminaron **{duplicados}** duplicados.")
                st.rerun()
            except Exception as e:
                st.error(f"Error general: {e}")

    with col_b2:
        if productos:
            st.markdown(
                f'<div class="stat-box">✅ <b>{len(productos)}</b> productos cargados. '
                f'Configura la agrupación y orden en la barra lateral, luego genera tu PDF.</div>',
                unsafe_allow_html=True,
            )
        else:
            st.caption("⬅️ Presiona el botón para comenzar.")

    if productos:
        st.markdown("""
        <div class="paso-titulo">
            <div class="paso-numero">2</div>
            <div class="paso-texto">Generar tu catálogo PDF</div>
        </div>
        """, unsafe_allow_html=True)
        st.caption(f"Agrupación: **{agrupacion}** | Orden: **{ordenamiento}**")

        if not telefono_valido:
            st.markdown(
                '<div class="alerta-whatsapp">'
                '<span class="icono">⚠️</span>'
                '<span class="texto">'
                'Ingresa tu <strong>número de WhatsApp</strong> de 8 dígitos en la barra lateral para poder generar el catálogo.'
                '</span>'
                '</div>',
                unsafe_allow_html=True,
            )
        else:
            col_gen1, col_gen2 = st.columns([1, 3])
            with col_gen1:
                if st.button("📄 Generar PDF", type="primary", use_container_width=True):
                    ruta_logo = None
                    if os.path.exists(RUTA_LOGO_DEFECTO):
                        ruta_logo = RUTA_LOGO_DEFECTO
                    with st.spinner("Generando PDF..."):
                        pdf_buffer = generar_pdf(
                            productos,
                            nombre_vendedor=nombre_vendedor,
                            telefono_whatsapp=telefono_whatsapp,
                            ruta_logo=ruta_logo,
                            agrupacion=agrupacion,
                            ordenamiento=ordenamiento,
                        )
                    st.session_state.pdf_bytes = pdf_buffer.getvalue()
                    st.success("🎉 ¡Catálogo generado!")

            if "pdf_bytes" in st.session_state and st.session_state.pdf_bytes:
                st.download_button(
                    label="⬇️ Descargar PDF",
                    data=st.session_state.pdf_bytes,
                    file_name="catalogo_perfumeria.pdf",
                    mime="application/pdf",
                    use_container_width=True,
                )

        st.markdown("---")
        col_clean1, col_clean2 = st.columns([1, 4])
        with col_clean1:
            if st.button("🔄 Limpiar y empezar de nuevo", use_container_width=True):
                st.session_state.productos_cargados = None
                st.session_state.pdf_bytes = None
                st.rerun()


if __name__ == "__main__":
    main()
