#wp_invoices_mail_app/cli.py
from email.utils import parseaddr

from .email_client import (
    fetch_unseen_messages,
    extract_invoice_attachments,
    send_processed_invoices_email,
    save_attachments,
    has_inline_images
)
from .config import MailConfig
from .processor import (
    process_attachments_with_wp_invoices,
    build_email_body_for_results,
)
from .renderers import (
    render_results_email_html,
    render_invalid_credentials_html,
    render_no_attachments_html
)
from .auth import is_authorized_from_message  # 👈 nuevo import


def run_once():
    if not MailConfig.ENABLED:
        print("[wp_invoices_mail_app] Mail bot desactivado (WP_INVOICES_MAIL_ENABLED=0). Saliendo.")
        return

    imap, messages = fetch_unseen_messages()
    if not imap:
        print("No se pudo conectar a IMAP.")
        return

    if not messages:
        imap.logout()
        return

    for msg_id, msg in messages:
        from_header = msg.get("From", "")
        _, from_email = parseaddr(from_header)
        subject = msg.get("Subject", "(sin asunto)")

        # 🔐 1) Verificar credenciales en el cuerpo del correo
        authorized, auth_msg = is_authorized_from_message(msg)
        if authorized == "INVALID_CREDENTIALS": #CREDENCIALES EN FORMATO CORRECTO PERO PROBABLEMENTE INCORRECTAS
            print(f"[AUTH] {auth_msg} Desde: {from_email}, asunto: {subject}")

            # 🆕 Enviar correo de respuesta avisando que las credenciales son inválidas
            if from_email:
                # Texto plano (fallback) en inglés
                text_lines = []
                text_lines.append("Hi,")
                text_lines.append("")
                text_lines.append(
                    "We could not process your email because there was "
                    "a problem with the login credentials in the message body."
                )
                if auth_msg:
                    text_lines.append(f"- Technical detail: {auth_msg}")
                text_lines.append("")
                text_lines.append(
                    "Please make sure you include a valid login using this format:"
                )
                text_lines.append("USER: your_username")
                text_lines.append("PASS: your_password")
                text_lines.append("")
                text_lines.append("This email was not processed.")
                text_lines.append("")
                text_lines.append("Regards,")
                text_lines.append("Invoice Bot – Absolutems")
                body_text = "\n".join(text_lines)

                try:
                    send_processed_invoices_email(
                        to_address=from_email,
                        original_subject=subject,
                        body_text=body_text,
                        pdf_paths=[],
                        body_html=body_html,
                    )
                except Exception as e:
                    print(f"[AUTH] Error enviando correo de credenciales inválidas: {e}")

            # Marcamos como visto y seguimos con el siguiente mensaje
            imap.store(msg_id, "+FLAGS", "\\Seen")
            continue
        
        if authorized == "NOT_CREDENTIALS": #EL BODY DEL MENSAJE NO CUMPLE EL STANDARD REQUERIDO, POSIBLE SPAMMER
            print(f"[##POSIBLE SPAMMER##][AUTH] {auth_msg} Desde: {from_email}, asunto: {subject}")
            continue
        
        
        if authorized == "AUTH": #PASO LA AUTHENTICACION
            print(f"[AUTH] {auth_msg} Desde: {from_email}, asunto: {subject}")

            attachments = extract_invoice_attachments(msg)

            if not attachments:
                print(f"Correo sin adjuntos válidos desde {from_email}, asunto: {subject}")

                inline_photos = has_inline_images(msg)

                # Texto plano (fallback)
                text_lines = []
                text_lines.append("Hi,")
                text_lines.append("")
                if inline_photos:
                    text_lines.append(
                        "We received your email but could not process any invoice "
                        "because we did not find a valid attachment."
                    )
                    text_lines.append("")
                    text_lines.append(
                        "It looks like you inserted a photo inside the email body. "
                        "Please attach the invoice as a file using the paper-clip icon "
                        "instead of pasting it into the message text."
                    )
                else:
                    text_lines.append(
                        "We received your email but could not process any invoice "
                        "because we did not find a valid attachment."
                    )
                    text_lines.append("")
                    text_lines.append(
                        "Please attach at least one invoice as a PDF or a clear image file "
                        "(JPG, PNG, etc.) so the bot can process it."
                    )

                text_lines.append("")
                text_lines.append("This email was not processed and no PDF was generated.")
                text_lines.append("")
                text_lines.append("Regards,")
                text_lines.append("Invoice Bot – Absolutems")
                body_text = "\n".join(text_lines)

                # HTML con branding
                body_html = render_no_attachments_html(inline_photos=inline_photos)

                send_processed_invoices_email(
                    to_address=from_email,
                    original_subject=subject,
                    body_text=body_text,
                    pdf_paths=[],
                    body_html=body_html,
                )

                imap.store(msg_id, "+FLAGS", "\\Seen")
                continue



            # 2) Guardar adjuntos crudos en inbox
            from .config import MailConfig as _MC
            saved_raw_paths = save_attachments(attachments, _MC.INBOX_DIR)
            print("Adjuntos crudos guardados en:")
            for p in saved_raw_paths:
                print("  -", p)

            # 3) Procesar adjuntos con wp_invoices
            results = process_attachments_with_wp_invoices(attachments)

            # ------------------------------------------------------------------
            # NUEVO: separar resultados OK de errores, sin romper compatibilidad
            # ------------------------------------------------------------------
            ok_results = []
            error_results = []

            for r in results or []:
                # Si el processor ya añade flags, úsalo; si no, mantenemos el comportamiento viejo
                has_error_flag = ("ok" in r) or ("error" in r) or ("traceback" in r)

                if has_error_flag and (r.get("ok") is False or r.get("error")):
                    error_results.append(r)
                else:
                    ok_results.append(r)

            # 4) Construir cuerpo base del correo (función existente)
            body = build_email_body_for_results(results) or ""

            body_html = render_results_email_html(results)

            # 5) Si hubo errores, extender el cuerpo con un resumen + detalles técnicos
            if error_results:
                extra_lines = []

                extra_lines.append("")
                extra_lines.append("⚠️ Algunas facturas no se pudieron procesar correctamente:")
                for er in error_results:
                    fname = (
                        er.get("filename")
                        or er.get("original_filename")
                        or "(sin nombre)"
                    )
                    err_text = er.get("error") or "Error desconocido"
                    extra_lines.append(f"  - {fname}: {err_text}")

                extra_lines.append("")
                extra_lines.append(
                    "Si quieres que investiguemos el problema, reenvía este correo a soporte "
                    "incluyendo el bloque de detalles técnicos que ves a continuación."
                )
                extra_lines.append("")
                extra_lines.append("──────── Detalles técnicos para soporte ────────")

                for er in error_results:
                    tb = (er.get("traceback") or "").strip()
                    if not tb:
                        continue
                    # recortamos por si el traceback es muy largo
                    if len(tb) > 2000:
                        tb = tb[-2000:]
                    fname = (
                        er.get("filename")
                        or er.get("original_filename")
                        or "(sin nombre)"
                    )
                    extra_lines.append(f"[{fname}]")
                    extra_lines.append(tb)
                    extra_lines.append("")

                # Unir cuerpo original + bloque extra
                body = (body + "\n" + "\n".join(extra_lines)).strip()

            # 6) Extraer rutas de PDFs de revisión
            #    - seguimos soportando la clave vieja "revision_pdf_path"
            #    - si en el futuro usamos "pdf_path", también se incluye
            pdf_paths = []
            for r in results or []:
                p = r.get("revision_pdf_path") or r.get("pdf_path")
                if p:
                    pdf_paths.append(p)

            print("PDFs de revisión a adjuntar:")
            for p in pdf_paths:
                print("  -", p)

            # 7) Enviar correo con resultados (éxitos + notas de fallos si los hubo)
            if from_email:
                send_processed_invoices_email(
                    to_address=from_email,
                    original_subject=subject,
                    body_text=body,
                    body_html=body_html,
                    pdf_paths=pdf_paths,
                )

            # 8) Marcar el correo como procesado
            imap.store(msg_id, "+FLAGS", "\\Seen")

    imap.close()
    imap.logout()



if __name__ == "__main__":
    run_once()
