# core/whatsapp_utils.py
"""
WhatsApp & SMS notification engine for SwiftPOS.

All sends are executed in daemon threads (never block HTTP requests).
ACTIVATION GATES:
  1. Global toggle: SiteConfiguration.enable_whatsapp  (superadmin must enable)
  2. Company toggle: CompanySettings.send_receipt_via_whatsapp / send_credit_via_whatsapp, etc.
  3. Company credentials: CompanySettings.whatsapp_api_url + whatsapp_api_key must be set,
     OR the global WHATSAPP_API_URL / WHATSAPP_API_KEY from settings.py is used.

If either gate is closed, the function silently no-ops — no error is raised.
"""

import threading
import logging
import requests as http_requests
from django.conf import settings

logger = logging.getLogger(__name__)


# ─────────────────────────────────────────────────────────────
# GATE: Global superadmin toggle
# ─────────────────────────────────────────────────────────────

def _is_whatsapp_globally_enabled():
    """Check if superadmin has globally activated WhatsApp/SMS features."""
    try:
        from core.models import SiteConfiguration
        cfg = SiteConfiguration.get_solo()
        return cfg.enable_whatsapp
    except Exception:
        return False


def _get_company_settings(company):
    """Safely retrieve CompanySettings for a company."""
    return getattr(company, 'settings', None)


# ─────────────────────────────────────────────────────────────
# BACKGROUND THREAD HELPERS
# ─────────────────────────────────────────────────────────────

def _run_in_background(fn, *args, **kwargs):
    t = threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True)
    t.start()


# ─────────────────────────────────────────────────────────────
# LOW-LEVEL SEND FUNCTIONS
# ─────────────────────────────────────────────────────────────

def _resolve_credentials(company_settings):
    """
    Returns (api_url, api_key) — company-level credentials take priority,
    falling back to global settings.py values.
    """
    api_url = (
        getattr(company_settings, 'whatsapp_api_url', '') or
        getattr(settings, 'WHATSAPP_API_URL', '')
    )
    api_key = (
        getattr(company_settings, 'whatsapp_api_key', '') or
        getattr(settings, 'WHATSAPP_API_KEY', '')
    )
    return api_url.strip(), api_key.strip()


def _do_send_whatsapp(phone, message, company_settings):
    """
    Sends a message via the configured WhatsApp HTTP API (Hellosend / Termii / 360dialog).
    Expected API: POST {url} with JSON body {"phone": ..., "message": ..., "api_key": ...}
    Adjust the payload structure to match your chosen provider.
    """
    api_url, api_key = _resolve_credentials(company_settings)
    if not api_url or not api_key:
        logger.warning("WhatsApp send skipped: no API URL or key configured.")
        return

    # Normalise phone: ensure leading +234 for Nigeria
    phone = str(phone).strip().lstrip('0')
    if not phone.startswith('+'):
        phone = '+234' + phone

    payload = {
        "api_key": api_key,
        "message_type": "TEXT",
        "to": phone,
        "from": getattr(company_settings, 'sms_sender_id', None) or getattr(settings, 'SMS_SENDER_ID', 'SwiftPOS'),
        "channel": "whatsapp",
        "text": message,
    }
    try:
        resp = http_requests.post(api_url, json=payload, timeout=10)
        if resp.status_code not in (200, 201):
            logger.warning(f"WhatsApp API returned {resp.status_code}: {resp.text[:200]}")
    except Exception as e:
        logger.error(f"WhatsApp send error: {e}")


def _do_send_sms(phone, message, company_settings):
    """
    Sends an SMS via Termii (https://api.ng.termii.com/api/sms/send).
    Falls back to the same endpoint as WhatsApp if no dedicated SMS URL is configured.
    """
    api_key = (
        getattr(company_settings, 'sms_api_key', '') or
        getattr(settings, 'SMS_API_KEY', '')
    )
    if not api_key:
        logger.warning("SMS send skipped: no API key configured.")
        return

    phone = str(phone).strip().lstrip('0')
    if not phone.startswith('+'):
        phone = '+234' + phone

    payload = {
        "api_key": api_key,
        "message_type": "TEXT",
        "to": phone,
        "from": getattr(company_settings, 'sms_sender_id', None) or 'SwiftPOS',
        "channel": "generic",
        "sms": message,
    }
    try:
        resp = http_requests.post(
            "https://api.ng.termii.com/api/sms/send",
            json=payload, timeout=10
        )
        if resp.status_code not in (200, 201):
            logger.warning(f"SMS API returned {resp.status_code}: {resp.text[:200]}")
    except Exception as e:
        logger.error(f"SMS send error: {e}")


# ─────────────────────────────────────────────────────────────
# PUBLIC API — RECEIPT
# ─────────────────────────────────────────────────────────────

def _do_send_receipt(order):
    """Formats a receipt as WhatsApp text and sends to the customer."""
    if not _is_whatsapp_globally_enabled():
        return

    company_settings = _get_company_settings(order.company)
    if not company_settings or not company_settings.send_receipt_via_whatsapp:
        return

    phone = order.customer_phone or (order.customer.phone if order.customer else '')
    if not phone:
        return

    biz_name = getattr(company_settings, 'business_name', None) or order.company.name
    currency  = getattr(company_settings, 'currency_symbol', '₦')

    # Build items list
    items_text = ''
    for item in order.items.select_related('product').all():
        name = getattr(item, 'product_name', None) or (item.product.name if item.product else 'Item')
        items_text += f"  • {name} × {item.quantity} — {currency}{item.total_price:,.2f}\n"

    msg = (
        f"🧾 *{biz_name} — Receipt*\n"
        f"{'—' * 30}\n"
        f"Order: #{order.order_number}\n\n"
        f"{items_text}"
        f"{'—' * 30}\n"
        f"Subtotal : {currency}{order.total_amount:,.2f}\n"
    )
    if order.discount_amount:
        msg += f"Discount : -{currency}{order.discount_amount:,.2f}\n"
    if order.tax_amount:
        msg += f"Tax      : {currency}{order.tax_amount:,.2f}\n"
    msg += (
        f"*Total   : {currency}{order.final_amount:,.2f}*\n"
        f"Paid     : {currency}{order.amount_paid:,.2f}\n"
    )
    if order.balance_amount and order.balance_amount > 0:
        msg += f"⚠️ Balance: {currency}{order.balance_amount:,.2f}\n"
    msg += f"\nPayment: {order.get_payment_method_display()}\n"
    msg += f"Thank you for shopping with us! 🙏"

    _do_send_whatsapp(phone, msg, company_settings)


def send_receipt_whatsapp(order):
    """Public: send order receipt to customer via WhatsApp (background thread)."""
    _run_in_background(_do_send_receipt, order)


# ─────────────────────────────────────────────────────────────
# PUBLIC API — CREDIT REMINDER
# ─────────────────────────────────────────────────────────────

def _do_send_credit_reminder(order):
    if not _is_whatsapp_globally_enabled():
        return

    company_settings = _get_company_settings(order.company)
    if not company_settings or not company_settings.send_credit_via_whatsapp:
        return

    phone = order.customer_phone or (order.customer.phone if order.customer else '')
    if not phone:
        return

    biz_name  = getattr(company_settings, 'business_name', None) or order.company.name
    currency  = getattr(company_settings, 'currency_symbol', '₦')
    msg = (
        f"👋 Hello {order.customer_name or 'Customer'},\n\n"
        f"This is a friendly reminder from *{biz_name}*.\n\n"
        f"You have an outstanding balance of *{currency}{order.balance_amount:,.2f}* "
        f"for Order #{order.order_number}.\n\n"
        f"Kindly settle at your earliest convenience. Thank you! 🙏"
    )
    _do_send_whatsapp(phone, msg, company_settings)


def send_credit_reminder_whatsapp(order):
    """Public: send credit balance reminder to customer (background thread)."""
    _run_in_background(_do_send_credit_reminder, order)


# ─────────────────────────────────────────────────────────────
# PUBLIC API — LOW STOCK ALERT TO ADMIN
# ─────────────────────────────────────────────────────────────

def _do_send_low_stock_alert(product):
    if not _is_whatsapp_globally_enabled():
        return

    company_settings = _get_company_settings(product.company)
    if not company_settings or not company_settings.send_lowstock_via_whatsapp:
        return

    # Use business WhatsApp number (admin's number from settings)
    admin_phone = getattr(settings, 'ADMIN_WHATSAPP_NUMBER', '') or getattr(settings, 'WHATSAPP_NUMBER', '')
    if not admin_phone:
        return

    biz_name = getattr(company_settings, 'business_name', None) or product.company.name
    msg = (
        f"⚠️ *{biz_name} — Low Stock Alert*\n\n"
        f"Product : {product.name}\n"
        f"SKU     : {product.sku}\n"
        f"Current : {product.stock_quantity} {product.unit_of_measure}\n"
        f"Minimum : {product.minimum_stock} {product.unit_of_measure}\n\n"
        f"Please restock immediately to avoid stockouts."
    )
    _do_send_whatsapp(admin_phone, msg, company_settings)


def send_low_stock_whatsapp(product):
    """Public: alert admin of low stock via WhatsApp (background thread)."""
    _run_in_background(_do_send_low_stock_alert, product)
