# /home/Autopartes/pos/blueprints/whatsapp_bp.py
"""WhatsApp via Baileys Bridge.

Endpoints:
  GET  /pos/api/whatsapp/status    -- Connection status
  GET  /pos/api/whatsapp/qr        -- Get QR code
  POST /pos/api/whatsapp/connect   -- Start connection
  POST /pos/api/whatsapp/logout    -- Disconnect
  POST /pos/api/whatsapp/webhook   -- Receive messages (public)
  POST /pos/api/whatsapp/send      -- Send message
  GET  /pos/api/whatsapp/conversations -- List conversations
"""

from flask import Blueprint, request, jsonify, g
from middleware import require_auth
from tenant_db import get_tenant_conn, get_master_conn
from services import whatsapp_service
from config import WHATSAPP_BRIDGE_URL, WHATSAPP_BRIDGE_KEY
from datetime import datetime

whatsapp_bp = Blueprint('whatsapp', __name__, url_prefix='/pos/api/whatsapp')


def _get_whatsapp_config(conn):
    """Read WhatsApp bridge configuration from tenant_config.
    Falls back to global server config (config.py / env vars) when tenant
    has no explicit WhatsApp settings. This allows the shared bridge to work
    out of the box for all tenants.
    """
    cur = conn.cursor()
    cur.execute("SELECT key, value FROM tenant_config WHERE key LIKE 'whatsapp_%'")
    config = {row[0]: row[1] for row in cur.fetchall()}
    cur.close()

    bridge_url = config.get('whatsapp_bridge_url', '') or WHATSAPP_BRIDGE_URL or ''
    bridge_key = config.get('whatsapp_bridge_key', '') or WHATSAPP_BRIDGE_KEY or ''
    enabled_raw = config.get('whatsapp_enabled', '').lower()
    if enabled_raw == 'true':
        enabled = True
    elif enabled_raw == 'false':
        enabled = False
    else:
        # No explicit tenant setting: auto-enable if a bridge URL is configured
        enabled = bool(bridge_url)

    return {
        'bridge_url': bridge_url,
        'bridge_key': bridge_key,
        'enabled': enabled,
        'phone_number': config.get('whatsapp_phone_number', ''),
    }


def _get_branch_phone(tenant_conn, branch_id=None):
    """Obtener teléfono de la sucursal."""
    if not tenant_conn:
        return '(pendiente)'
    try:
        cur = tenant_conn.cursor()
        if branch_id:
            cur.execute("SELECT phone FROM branches WHERE id = %s", (branch_id,))
            row = cur.fetchone()
            if row and row[0]:
                cur.close()
                return row[0]
        cur.execute("SELECT value FROM tenant_config WHERE key = 'tenant_phone'")
        row = cur.fetchone()
        cur.close()
        return row[0] if row and row[0] else '(pendiente)'
    except Exception as e:
        print(f"[WA-SM] get_branch_phone error: {e}")
        return '(pendiente)'


def _resolve_mye_ids(vehicle, master_conn):
    """Return list of MYE ids matching vehicle brand/model/year text."""
    if not master_conn or not vehicle:
        return []
    brand = vehicle.get('brand', '').strip()
    model = vehicle.get('model', '').strip()
    year = str(vehicle.get('year', '')).strip()
    if not brand and not model:
        return []
    cur = master_conn.cursor()
    clauses = []
    params = []
    if brand:
        clauses.append("b.name_brand ILIKE %s")
        params.append(f'%{brand}%')
    if model:
        clauses.append("m.name_model ILIKE %s")
        params.append(f'%{model}%')
    if year and year.isdigit():
        clauses.append("y.year_car = %s")
        params.append(int(year))
    if not clauses:
        cur.close()
        return []
    cur.execute(f"""
        SELECT mye.id_mye
        FROM model_year_engine mye
        JOIN models m ON m.id_model = mye.model_id
        JOIN brands b ON b.id_brand = m.brand_id
        JOIN years y ON y.id_year = mye.year_id
        WHERE {' AND '.join(clauses)}
        LIMIT 50
    """, tuple(params))
    rows = cur.fetchall()
    cur.close()
    return [r[0] for r in rows]


def _get_conversation_history(phone, tenant_conn, limit=4):
    """Fetch recent messages for *phone* to give the AI conversation context.

    Includes both user and assistant messages, truncated to keep token count low.
    The most recent message (the one currently being processed) is excluded.
    """
    if not tenant_conn or not phone:
        return []
    try:
        cur = tenant_conn.cursor()
        cur.execute("""
            SELECT direction, message_text
            FROM whatsapp_messages
            WHERE phone = %s
            ORDER BY created_at DESC
            LIMIT %s OFFSET 1
        """, (phone, limit))
        rows = cur.fetchall()
        cur.close()
        # Reverse so oldest-first (chronological) for the LLM
        history = []
        for direction, text in reversed(rows):
            if not text:
                continue
            role = "assistant" if direction == "outgoing" else "user"
            # Truncate assistant replies more aggressively (they contain JSON/tables)
            max_len = 200 if role == "assistant" else 300
            truncated = text[:max_len] + ('...' if len(text) > max_len else '')
            history.append({"role": role, "content": truncated})
        return history
    except Exception as e:
        print(f"[WA-AI] Failed to load conversation history: {e}")
        return []


def _enrich_wa_reply_with_part(search_query, vehicle, tenant_conn, master_conn=None):
    """Search the refaccionaria's LOCAL inventory and build a WhatsApp reply.

    If *vehicle* is provided and we have a master_conn, we first look up the
    MYE ids for that vehicle and JOIN through inventory_vehicle_compat so we
    only show parts that are known to fit the user's car.

    Returns:
        (formatted_text, first_part_dict) — first_part_dict is used by the
        quotation system to know what to add when the user says "cotizar".
        first_part_dict has: inventory_id, part_number, name, brand, price, tax_rate
    """
    if not tenant_conn:
        return None, None

    try:
        from services.translations import PART_TRANSLATIONS

        # Split search_query by '|' into individual terms
        raw_terms = [t.strip() for t in (search_query or '').split('|') if t.strip()]
        if not raw_terms:
            raw_terms = [search_query] if search_query else []

        # Translate each term to Spanish if possible
        search_terms = set()
        for term in raw_terms:
            search_terms.add(term)
            # Check if any English translation matches
            for en, es in PART_TRANSLATIONS.items():
                if en.upper() == term.upper():
                    search_terms.add(es)
                    break
                # Also check if the term contains an English word
                if en.upper() in term.upper():
                    search_terms.add(term.upper().replace(en.upper(), es))

        search_terms = list(search_terms)
        if not search_terms:
            return None, None

        # Vehicle-aware filtering
        mye_ids = _resolve_mye_ids(vehicle, master_conn)

        def _do_search(use_compat=True):
            """Run inventory search. Returns list of rows."""
            conditions = []
            params = []
            for term in search_terms:
                conditions.append("(i.name ILIKE %s OR i.part_number ILIKE %s OR i.brand ILIKE %s)")
                like = f'%{term}%'
                params.extend([like, like, like])

            where_search = ' OR '.join(conditions)
            compat_clause = ""
            if use_compat and mye_ids:
                compat_clause = f"AND i.id IN (SELECT inventory_id FROM inventory_vehicle_compat WHERE model_year_engine_id IN ({','.join(['%s']*len(mye_ids))}))"
                params.extend(mye_ids)

            cur = tenant_conn.cursor()
            cur.execute(f"""
                SELECT i.id, i.part_number, i.name, i.brand, i.price_1, i.price_2, i.price_3,
                       COALESCE(s.stock, 0) AS stock,
                       i.unit, i.location
                FROM inventory i
                LEFT JOIN inventory_stock_summary s ON s.inventory_id = i.id
                WHERE i.is_active = TRUE
                  AND ({where_search})
                  {compat_clause}
                ORDER BY
                    COALESCE(s.stock, 0) > 0 DESC,
                    i.name
                LIMIT 10
            """, params)
            rows = cur.fetchall()
            cur.close()
            return rows

        # 1. Try with vehicle compatibility filter
        rows = _do_search(use_compat=True)
        compat_filter_applied = bool(mye_ids)

        # 2. If no results with compatibility, try WITHOUT filter
        fallback_rows = []
        if not rows and mye_ids:
            fallback_rows = _do_search(use_compat=False)

        if not rows and not fallback_rows:
            # Nothing found in local inventory — let the AI's original response stand.
            # The webhook will append a soft note instead of replacing the message.
            return None, None

        # Use fallback rows if primary search returned nothing
        using_fallback = False
        if not rows and fallback_rows:
            rows = fallback_rows
            using_fallback = True

        in_stock = [r for r in rows if r[7] > 0]
        out_stock = [r for r in rows if r[7] <= 0]

        best = in_stock[0] if in_stock else (out_stock[0] if out_stock else None)
        first_part = None
        if best:
            first_part = {
                'inventory_id': best[0],
                'part_number': best[1],
                'name': best[2],
                'brand': best[3] or '',
                'price': float(best[4]) if best[4] else 0,
                'tax_rate': 0.16,
                'stock': best[7],
                'unit': best[8] or 'PZA',
            }

        lines = []

        if using_fallback:
            lines.append("⚠️ *No encontré partes verificadas para tu vehículo, pero sí tengo estas opciones generales:*")
            lines.append("")

        if in_stock:
            lines.append('✅ *Tenemos en stock:*')
            lines.append('')
            for r in in_stock:
                inv_id, part_num, name, brand, p1, p2, p3, stock, unit, location = r
                brand_str = f'*{brand}*' if brand else ''
                price_str = f'${float(p1):,.2f}' if p1 else 'Consultar precio'
                lines.append(f'  • {brand_str} {name}')
                lines.append(f'    #{part_num} — {price_str} ({stock} {unit or "pzas"} disponibles)')
                lines.append('')
        elif out_stock:
            lines.append('⚠️ *Tenemos estas opciones pero sin stock actualmente:*')
            lines.append('')
            for r in out_stock[:5]:
                inv_id, part_num, name, brand, p1, p2, p3, stock, unit, location = r
                brand_str = f'*{brand}*' if brand else ''
                price_str = f'${float(p1):,.2f}' if p1 else ''
                lines.append(f'  • {brand_str} {name} #{part_num} {price_str}')
            lines.append('')
            lines.append('_Podemos pedirlo — consulta tiempo de entrega._')

        # Vehicle context
        if vehicle and vehicle.get('brand'):
            v_str = f"{vehicle.get('brand','')} {vehicle.get('model','')} {vehicle.get('year','')}"
            lines.append(f'🚗 Vehículo: {v_str.strip()}')

        lines.append('\n📞 _Escribe "cotizar" para agregar a tu cotización._')

        return '\n'.join(lines), first_part

    except Exception as e:
        print(f"[WA-AI] Enrichment error: {e}")
        import traceback
        traceback.print_exc()
        return None, None
        return None, None


@whatsapp_bp.route('/status', methods=['GET'])
@require_auth()
def status():
    conn = get_tenant_conn(g.tenant_id)
    cfg = _get_whatsapp_config(conn)
    conn.close()
    if not cfg['enabled'] or not cfg['bridge_url']:
        return jsonify({'state': 'disabled', 'message': 'WhatsApp not configured for this tenant'})
    return jsonify(whatsapp_service.get_status(bridge_url=cfg['bridge_url']))


@whatsapp_bp.route('/qr', methods=['GET'])
@require_auth()
def qr():
    conn = get_tenant_conn(g.tenant_id)
    cfg = _get_whatsapp_config(conn)
    conn.close()
    if not cfg['enabled'] or not cfg['bridge_url']:
        return jsonify({'state': 'disabled', 'message': 'WhatsApp not configured for this tenant'})
    return jsonify(whatsapp_service.get_qr(bridge_url=cfg['bridge_url']))


@whatsapp_bp.route('/connect', methods=['POST'])
@require_auth()
def connect():
    conn = get_tenant_conn(g.tenant_id)
    cfg = _get_whatsapp_config(conn)
    conn.close()
    if not cfg['enabled'] or not cfg['bridge_url']:
        return jsonify({'state': 'error', 'error': 'WhatsApp not configured for this tenant'}), 400
    return jsonify(whatsapp_service.connect(bridge_url=cfg['bridge_url']))


@whatsapp_bp.route('/logout', methods=['POST'])
@require_auth()
def logout():
    conn = get_tenant_conn(g.tenant_id)
    cfg = _get_whatsapp_config(conn)
    conn.close()
    if not cfg['enabled'] or not cfg['bridge_url']:
        return jsonify({'state': 'error', 'error': 'WhatsApp not configured for this tenant'}), 400
    return jsonify(whatsapp_service.logout(bridge_url=cfg['bridge_url']))


@whatsapp_bp.route('/webhook', methods=['POST'])
def webhook():
    """Receive messages from Baileys bridge (public, no auth).

    Nuevo flujo: máquina de estados estructurada.
    """
    data = request.get_json(force=True, silent=True) or {}

    if data.get('event') != 'messages.upsert':
        return jsonify({'ok': True})

    msg = whatsapp_service.process_incoming(data)
    if not msg.get('phone') or msg.get('from_me'):
        return jsonify({'ok': True})

    phone = msg['phone']
    reply_to = msg.get('sender_pn') or msg.get('jid') or phone
    text = msg.get('text', '')
    media_kind = msg.get('media_kind', 'text')

    # Audio transcription (voice notes)
    if media_kind == 'audio' and msg.get('media_base64'):
        try:
            from services.whisper_local import transcribe_audio_base64
            transcript = transcribe_audio_base64(
                msg['media_base64'],
                mimetype=msg.get('media_mimetype') or 'audio/ogg',
            )
            if transcript:
                text = transcript
                print(f"[WA-SM] Voice note transcribed: {transcript[:100]}")
        except ImportError:
            pass
        except Exception as e:
            print(f"[WA-SM] Whisper transcription failed: {e}")

    # Location message: if current state expects it, store coordinates
    if media_kind == 'location' and msg.get('latitude') is not None:
        text = f"Ubicación: {msg['latitude']},{msg['longitude']}"

    # Image without caption: provide a default text so the state machine can handle it
    if media_kind == 'image' and not text:
        text = "(imagen)"


    # Resolve tenant
    tenant_id = request.args.get('tenant_id', type=int)
    if not tenant_id:
        try:
            mconn = get_master_conn()
            mcur = mconn.cursor()
            mcur.execute("""
                SELECT id, db_name FROM tenants
                WHERE is_active = true
                ORDER BY id
            """)
            tenants = mcur.fetchall()
            mcur.close()
            mconn.close()
            # Find first tenant with whatsapp_enabled in their config
            for tid, db_name in tenants:
                try:
                    from tenant_db import get_tenant_conn_by_dbname
                    tconn = get_tenant_conn_by_dbname(db_name)
                    tcur = tconn.cursor()
                    tcur.execute(
                        "SELECT value FROM tenant_config WHERE key = 'whatsapp_enabled'"
                    )
                    row = tcur.fetchone()
                    tcur.close()
                    tconn.close()
                    if row and row[0].lower() == 'true':
                        tenant_id = tid
                        break
                except Exception:
                    continue
        except Exception:
            tenant_id = None

    tenant_conn = None
    master_conn = None

    try:
        tenant_conn = get_tenant_conn(tenant_id)
        master_conn = get_master_conn()
        wa_config = _get_whatsapp_config(tenant_conn)

        # Deduplicate by wa_message_id
        wa_message_id = msg.get('message_id')
        if wa_message_id:
            cur = tenant_conn.cursor()
            cur.execute("SELECT 1 FROM whatsapp_messages WHERE wa_message_id = %s LIMIT 1", (wa_message_id,))
            if cur.fetchone():
                cur.close()
                return jsonify({'ok': True})
            cur.close()

        # 1. Log incoming message
        cur = tenant_conn.cursor()
        cur.execute("""
            INSERT INTO whatsapp_messages (phone, direction, message_text, wa_message_id, push_name)
            VALUES (%s, 'incoming', %s, %s, %s)
            ON CONFLICT DO NOTHING
        """, (phone, text, wa_message_id, msg.get('push_name')))
        tenant_conn.commit()
        cur.close()

        # 2. Load session state
        from services.wa_state_machine import get_session, save_session, process_message, StateContext
        session = get_session(tenant_conn, phone)

        # 3. Check session expiry (30 minutes)
        current_state = session.get('state', 'idle')
        state_data = session.get('state_data', {})
        last_updated = session.get('updated_at')

        if last_updated and hasattr(last_updated, 'strftime'):
            # PostgreSQL returns datetime objects (often timezone-aware)
            from datetime import timezone
            now = datetime.now(timezone.utc)
            if last_updated.tzinfo is None:
                now = now.replace(tzinfo=None)
            elapsed = (now - last_updated).total_seconds()
            if elapsed > 1800:
                current_state = 'idle'
                state_data = {'customer_id': state_data.get('customer_id')}
        elif last_updated and isinstance(last_updated, str):
            from datetime import datetime as dt
            try:
                parsed = dt.fromisoformat(last_updated.replace('Z', '+00:00'))
                elapsed = (dt.now(dt.now().astimezone().tzinfo) - parsed).total_seconds()
                if elapsed > 1800:
                    current_state = 'idle'
                    state_data = {'customer_id': state_data.get('customer_id')}
            except Exception:
                pass

        # Global reset commands work from any state
        if text and text.strip().lower() in ('limpiar chat', 'nuevo chat', 'borrar conversacion', 'borrar conversación', 'reset', 'reiniciar', 'menu', 'menú'):
            current_state = 'idle'
            state_data = {'customer_id': state_data.get('customer_id')}

        # Abandoned quotation follow-up
        try:
            from services.part_kits import should_send_followup
            followup = should_send_followup(phone, tenant_conn)
            if followup:
                whatsapp_service.send_message(reply_to, followup, bridge_url=wa_config.get('bridge_url'))
                cur_fu = tenant_conn.cursor()
                cur_fu.execute(
                    "INSERT INTO whatsapp_messages (phone, direction, message_text) VALUES (%s, 'outgoing', %s)",
                    (phone, followup)
                )
                tenant_conn.commit()
                cur_fu.close()
        except Exception as fu_err:
            print(f"[WA-SM] Follow-up send failed: {fu_err}")

        # 4. Build context
        context = StateContext(
            tenant_conn=tenant_conn,
            master_conn=master_conn,
            wa_config=wa_config,
            tenant_id=tenant_id,
            phone=phone,
            media_kind=media_kind,
            media_base64=msg.get('media_base64'),
            push_name=msg.get('push_name'),
        )

        # 5. Process through state machine
        reply, next_state, next_state_data = process_message(
            phone=phone,
            text=text,
            current_state=current_state,
            state_data=state_data,
            context=context,
        )

        # 5b. Si el estado transicionó sin mensaje, procesar el siguiente inmediatamente
        # (algunos estados solo hacen transiciones y delegan el mensaje al siguiente estado)
        loop_guard = 0
        while reply is None and loop_guard < 5:
            loop_guard += 1
            reply, next_state, next_state_data = process_message(
                phone=phone,
                text=text,
                current_state=next_state,
                state_data=next_state_data,
                context=context,
            )

        # 6. Save new state
        save_session(tenant_conn, phone, next_state, next_state_data)

        # 7. Send reply
        if reply:
            result = whatsapp_service.send_message(reply_to, reply, bridge_url=wa_config.get('bridge_url'))
            print(f"[WA-SM] Replied to {phone}: {reply[:80]}... result={result}")

            # Log outgoing
            cur = tenant_conn.cursor()
            cur.execute("""
                INSERT INTO whatsapp_messages (phone, direction, message_text)
                VALUES (%s, 'outgoing', %s)
            """, (phone, reply))
            tenant_conn.commit()
            cur.close()

    except Exception as e:
        print(f"[WA-SM] Webhook error: {e}")
        import traceback
        traceback.print_exc()
        # Fallback: enviar mensaje de error genérico
        try:
            if tenant_conn:
                phone_branch = _get_branch_phone(tenant_conn, None)
                fallback = (
                    "Estoy teniendo problemas técnicos en este momento. 😕\n\n"
                    f"Por favor llámanos directamente al {phone_branch}."
                )
                whatsapp_service.send_message(reply_to, fallback, bridge_url=wa_config.get('bridge_url'))
        except Exception:
            pass

    finally:
        if tenant_conn:
            try:
                tenant_conn.close()
            except Exception:
                pass
        if master_conn:
            try:
                master_conn.close()
            except Exception:
                pass

    return jsonify({'ok': True})


@whatsapp_bp.route('/send', methods=['POST'])
@require_auth()
def send():
    data = request.get_json() or {}
    phone = data.get('phone', '')
    message = data.get('message', '')
    if not phone or not message:
        return jsonify({'error': 'phone and message required'}), 400

    # Load tenant WhatsApp config
    conn = get_tenant_conn(g.tenant_id)
    cfg = _get_whatsapp_config(conn)
    if not cfg['enabled'] or not cfg['bridge_url']:
        conn.close()
        return jsonify({'error': 'WhatsApp not configured for this tenant'}), 400

    result = whatsapp_service.send_message(phone, message, bridge_url=cfg['bridge_url'])

    # Save outgoing message
    try:
        cur = conn.cursor()
        cur.execute("""
            INSERT INTO whatsapp_messages (phone, direction, message_text)
            VALUES (%s, 'outgoing', %s)
        """, (phone, message))
        conn.commit()
        cur.close()
    except Exception:
        pass
    finally:
        conn.close()

    return jsonify(result)


@whatsapp_bp.route('/conversations', methods=['GET'])
@require_auth()
def conversations():
    try:
        conn = get_tenant_conn(g.tenant_id)
        cur = conn.cursor()
        # Clean up phone format: strip @lid and @s.whatsapp.net suffixes
        # so all variants of the same number are grouped together.
        cur.execute("""
            WITH cleaned AS (
                SELECT
                    REPLACE(REPLACE(phone, '@s.whatsapp.net', ''), '@lid', '') AS clean_phone,
                    message_text,
                    direction,
                    created_at,
                    push_name
                FROM whatsapp_messages
            )
            SELECT clean_phone,
                   (ARRAY_AGG(message_text ORDER BY created_at DESC))[1] AS last_message,
                   (ARRAY_AGG(direction ORDER BY created_at DESC))[1] AS last_direction,
                   MAX(created_at) AS last_at,
                   COUNT(*) AS msg_count,
                   (ARRAY_AGG(push_name ORDER BY created_at DESC) FILTER (WHERE push_name IS NOT NULL AND push_name != ''))[1] AS contact_name
            FROM cleaned
            GROUP BY clean_phone
            ORDER BY MAX(created_at) DESC
            LIMIT 50
        """)
        convos = [{
            'phone': r[0],
            'last_message': r[1] or '',
            'last_direction': r[2] or 'incoming',
            'last_at': str(r[3]),
            'count': r[4],
            'contact_name': r[5] or '',
        } for r in cur.fetchall()]
        cur.close()
        conn.close()
        return jsonify({'conversations': convos})
    except Exception as e:
        return jsonify({'conversations': [], 'error': str(e)})


@whatsapp_bp.route('/conversations/<path:phone>', methods=['GET'])
@require_auth()
def conversation_messages(phone):
    # Strip @lid or @s.whatsapp.net suffix for DB lookup
    clean_phone = phone.replace('@s.whatsapp.net', '').replace('@lid', '')
    try:
        conn = get_tenant_conn(g.tenant_id)
        cur = conn.cursor()
        # Match all variants of this phone number
        cur.execute("""
            SELECT id, direction, message_text, created_at
            FROM whatsapp_messages
            WHERE REPLACE(REPLACE(phone, '@s.whatsapp.net', ''), '@lid', '') = %s
            ORDER BY created_at
            LIMIT 100
        """, (clean_phone,))
        msgs = [{
            'id': r[0],
            'direction': r[1],
            'message_text': r[2] or '',
            'created_at': str(r[3]),
        } for r in cur.fetchall()]
        cur.close()
        conn.close()
        return jsonify({'messages': msgs})
    except Exception as e:
        return jsonify({'messages': [], 'error': str(e)})


@whatsapp_bp.route('/conversations/<path:phone>', methods=['DELETE'])
@require_auth()
def delete_conversation(phone):
    """Delete all messages for a phone number."""
    clean_phone = phone.replace('@s.whatsapp.net', '').replace('@lid', '')
    try:
        conn = get_tenant_conn(g.tenant_id)
        cur = conn.cursor()
        cur.execute("""
            DELETE FROM whatsapp_messages
            WHERE REPLACE(REPLACE(phone, '@s.whatsapp.net', ''), '@lid', '') = %s
        """, (clean_phone,))
        deleted = cur.rowcount
        conn.commit()
        cur.close()
        conn.close()
        return jsonify({'ok': True, 'deleted': deleted})
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@whatsapp_bp.route('/conversations', methods=['DELETE'])
@require_auth()
def delete_all_conversations():
    """Delete ALL whatsapp messages."""
    try:
        conn = get_tenant_conn(g.tenant_id)
        cur = conn.cursor()
        cur.execute("DELETE FROM whatsapp_messages")
        deleted = cur.rowcount
        conn.commit()
        cur.close()
        conn.close()
        return jsonify({'ok': True, 'deleted': deleted})
    except Exception as e:
        return jsonify({'error': str(e)}), 500
