# core/email_utils.py
"""
Email notification utilities for SwiftPOS.

How images work in emails (why relative paths fail)
────────────────────────────────────────────────────
Email clients (Gmail, Outlook, Apple Mail) are sandboxed — they cannot fetch
resources from relative URLs like /static/logo.png.  Images must be either:
  (a) Absolute public URLs:  https://yourdomain.com/static/logo.png
  (b) CID-embedded (inline): attached to the MIME message and referenced as
      <img src="cid:logo"> — this is what we do here.

All emails in this file embed the SwiftPOS logo via CID so it always appears,
regardless of the email client or image-blocking settings.

Sender "profile picture" in Gmail / Outlook
────────────────────────────────────────────
The avatar shown next to the sender name is pulled from Gravatar using the
sending email address.  To set it:
  1. Create a free account at https://gravatar.com with the same email address
     that is set in EMAIL_HOST_USER / DEFAULT_FROM_EMAIL in your .env.
  2. Upload your SwiftPOS logo as the avatar.
  Gmail and most modern clients will automatically show it.
"""
import os
import threading
from email.mime.image import MIMEImage

from django.core.mail import EmailMultiAlternatives
from django.conf import settings
from django.utils import timezone


# ─────────────────────────────────────────────────────────────────
#  INTERNAL HELPERS
# ─────────────────────────────────────────────────────────────────

def _get_admin_emails():
    """Return list of admin email addresses from settings."""
    raw = getattr(settings, 'ADMIN_EMAIL', '')
    emails = [e.strip() for e in raw.split(',') if e.strip()]
    return emails or []


def _send_in_background(fn, *args, **kwargs):
    """Run email sending in a background thread.
    Must be non-daemon so WSGI workers don't kill the thread before
    the SMTP handshake completes (daemon threads die with the request).
    """
    t = threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False)
    t.start()


def _get_logo_path():
    """Return the absolute filesystem path to the SwiftPOS logo PNG."""
    base = settings.BASE_DIR
    candidates = [
        os.path.join(base, 'static', 'core', 'icons', 'icon-192.png'),
        os.path.join(base, 'staticfiles', 'core', 'icons', 'icon-192.png'),
        os.path.join(base, 'core', 'static', 'core', 'icons', 'icon-192.png'),
    ]
    for path in candidates:
        if os.path.isfile(path):
            return path
    return None


def _get_site_url():
    return getattr(settings, 'SITE_URL', '').rstrip('/')


def _attach_logo(msg):
    """
    Embed the SwiftPOS logo as an inline CID attachment.
    Returns the CID name to reference in HTML: <img src="cid:swiftpos_logo">
    """
    logo_path = _get_logo_path()
    if not logo_path:
        return None
    try:
        with open(logo_path, 'rb') as f:
            logo_data = f.read()
        logo_mime = MIMEImage(logo_data, 'png')
        logo_mime.add_header('Content-ID', '<swiftpos_logo>')
        logo_mime.add_header('Content-Disposition', 'inline', filename='logo.png')
        msg.attach(logo_mime)
        return 'swiftpos_logo'
    except Exception:
        return None


# ─────────────────────────────────────────────────────────────────
#  SHARED EMAIL TEMPLATE BUILDER
# ─────────────────────────────────────────────────────────────────

def _render_email_html(
    *,
    company_name: str,
    title: str,
    subtitle: str = '',
    header_color: str = '#4F46E5',
    body_html: str,
    footer_note: str = 'This is an automated notification from SwiftPOS. Do not reply to this email.',
    has_logo: bool = True,
) -> str:
    """
    Renders a full professional HTML email using table-based layout.
    Supports CID logo via cid:swiftpos_logo (injected separately by _attach_logo).
    All styles are inline for maximum email client compatibility.
    """
    site_url = _get_site_url()
    logo_html = ''
    if has_logo:
        logo_html = f'''
        <img src="cid:swiftpos_logo" alt="SwiftPOS"
             width="44" height="44"
             style="display:block;border-radius:10px;margin:0 auto 10px;
                    border:0;outline:none;text-decoration:none;"
             onerror="this.style.display='none'">
        '''

    return f"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title} — SwiftPOS</title>
</head>
<body style="margin:0;padding:0;background-color:#f1f5f9;font-family:'Segoe UI',Arial,Helvetica,sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;">

  <!-- Email Wrapper -->
  <table border="0" cellpadding="0" cellspacing="0" width="100%"
         style="background-color:#f1f5f9;padding:32px 16px;">
    <tr>
      <td align="center">
        <!-- Email Card -->
        <table border="0" cellpadding="0" cellspacing="0" width="560"
               style="max-width:560px;width:100%;background-color:#ffffff;
                      border-radius:16px;overflow:hidden;
                      box-shadow:0 4px 24px rgba(0,0,0,0.08);">

          <!-- ── HEADER ── -->
          <tr>
            <td align="center"
                style="background:{header_color};
                       background:linear-gradient(135deg,{header_color} 0%,#7C3AED 100%);
                       padding:32px 40px;text-align:center;">
              {logo_html}
              <h1 style="margin:0;color:#ffffff;font-size:22px;font-weight:700;
                          letter-spacing:-0.5px;font-family:'Segoe UI',Arial,sans-serif;">
                {title}
              </h1>
              {f'<p style="margin:8px 0 0;color:rgba(255,255,255,0.85);font-size:14px;">{subtitle}</p>' if subtitle else ''}
            </td>
          </tr>

          <!-- ── BODY ── -->
          <tr>
            <td style="padding:36px 40px;">
              {body_html}
            </td>
          </tr>

          <!-- ── DIVIDER ── -->
          <tr>
            <td style="padding:0 40px;">
              <div style="height:1px;background-color:#e2e8f0;"></div>
            </td>
          </tr>

          <!-- ── FOOTER ── -->
          <tr>
            <td style="padding:20px 40px;text-align:center;">
              <p style="margin:0 0 8px;font-size:12px;color:#94a3b8;">{footer_note}</p>
              <p style="margin:0;font-size:12px;color:#cbd5e1;">
                &copy; {timezone.now().year}
                <a href="{site_url}" style="color:#6366f1;text-decoration:none;">SwiftPOS</a>
                &bull; {company_name}
              </p>
            </td>
          </tr>

        </table>
        <!-- /Email Card -->

      </td>
    </tr>
  </table>

</body>
</html>"""


def _make_email(subject, text_body, html_body, recipients, attach_logo=True):
    """
    Build and return an EmailMultiAlternatives with optional CID logo embedded.
    Call .send() on the returned object.
    """
    msg = EmailMultiAlternatives(
        subject=subject,
        body=text_body,
        from_email=settings.DEFAULT_FROM_EMAIL,
        to=recipients if isinstance(recipients, list) else [recipients],
    )
    msg.mixed_subtype = 'related'  # allows CID references inside the HTML
    msg.attach_alternative(html_body, 'text/html')
    if attach_logo:
        _attach_logo(msg)
    return msg


# ─────────────────────────────────────────────
#  LOW STOCK ALERT
# ─────────────────────────────────────────────

def _do_send_low_stock(product):
    admins = _get_admin_emails()
    if not admins or not settings.EMAIL_HOST_USER:
        return

    subject = f"📦 Inventory Alert — Low Stock: {product.name}"

    body_html = f"""
    <p style="margin:0 0 16px;font-size:15px;color:#334155;">
        This is an automated low-stock alert from your SwiftPOS system.
    </p>
    <table border="0" cellpadding="0" cellspacing="0" width="100%"
           style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;
                  margin-bottom:24px;">
      <tr>
        <td style="padding:20px 24px;">
          <table border="0" cellpadding="0" cellspacing="0" width="100%">
            <tr>
              <td style="font-size:13px;color:#64748b;padding-bottom:12px;border-bottom:1px solid #e2e8f0;">PRODUCT DETAILS</td>
            </tr>
            <tr><td style="padding:10px 0;border-bottom:1px solid #f1f5f9;">
              <table width="100%"><tr>
                <td style="font-size:13px;color:#64748b;">Product Name</td>
                <td align="right" style="font-size:13px;font-weight:700;color:#1e293b;">{product.name}</td>
              </tr></table>
            </td></tr>
            <tr><td style="padding:10px 0;border-bottom:1px solid #f1f5f9;">
              <table width="100%"><tr>
                <td style="font-size:13px;color:#64748b;">SKU</td>
                <td align="right" style="font-size:13px;color:#1e293b;">{product.sku or '—'}</td>
              </tr></table>
            </td></tr>
            <tr><td style="padding:10px 0;border-bottom:1px solid #f1f5f9;">
              <table width="100%"><tr>
                <td style="font-size:13px;color:#64748b;">Current Stock</td>
                <td align="right" style="font-size:14px;font-weight:700;color:#ef4444;">
                  {product.stock_quantity} {product.unit_of_measure}
                </td>
              </tr></table>
            </td></tr>
            <tr><td style="padding:10px 0;">
              <table width="100%"><tr>
                <td style="font-size:13px;color:#64748b;">Minimum Level</td>
                <td align="right" style="font-size:13px;font-weight:700;color:#f59e0b;">
                  {product.minimum_stock} {product.unit_of_measure}
                </td>
              </tr></table>
            </td></tr>
          </table>
        </td>
      </tr>
    </table>
    <p style="margin:0;font-size:14px;color:#475569;text-align:center;">
      Please restock this item as soon as possible to avoid stockouts.
    </p>
    """

    text_body = (
        f"Low Stock Alert: {product.name}\n\n"
        f"SKU: {product.sku or '—'}\n"
        f"Current Stock: {product.stock_quantity} {product.unit_of_measure}\n"
        f"Minimum Level: {product.minimum_stock} {product.unit_of_measure}\n\n"
        f"Please restock this item immediately.\n\n— SwiftPOS"
    )

    company = getattr(product, 'company', None)
    company_name = getattr(company, 'name', 'SwiftPOS')

    html = _render_email_html(
        company_name=company_name,
        title="⚠️ Low Stock Alert",
        subtitle=f"{product.name} is running low",
        header_color='#dc2626',
        body_html=body_html,
    )

    try:
        msg = _make_email(subject, text_body, html, admins)
        msg.send(fail_silently=False)
    except Exception as e:
        import logging
        logging.getLogger(__name__).error(f"Failed to send low stock alert: {e}")


def send_low_stock_alert(product):
    """Send low-stock alert in background thread."""
    _send_in_background(_do_send_low_stock, product)


# ─────────────────────────────────────────────
#  CREDIT CUSTOMER ALERT
# ─────────────────────────────────────────────

def _do_send_credit_alert(customer_name, customer_phone, order_number, balance):
    admins = _get_admin_emails()
    if not admins or not settings.EMAIL_HOST_USER:
        return

    subject = f"💳 Credit Transaction — {customer_name}"

    body_html = f"""
    <p style="margin:0 0 20px;font-size:15px;color:#334155;">
        A new credit transaction has been recorded in SwiftPOS.
    </p>
    <table border="0" cellpadding="0" cellspacing="0" width="100%"
           style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;margin-bottom:24px;">
      <tr><td style="padding:20px 24px;">
        <table border="0" cellpadding="0" cellspacing="0" width="100%">
          <tr><td style="font-size:13px;color:#64748b;padding-bottom:12px;border-bottom:1px solid #e2e8f0;">TRANSACTION DETAILS</td></tr>
          <tr><td style="padding:10px 0;border-bottom:1px solid #f1f5f9;">
            <table width="100%"><tr>
              <td style="font-size:13px;color:#64748b;">Customer</td>
              <td align="right" style="font-size:13px;font-weight:700;color:#1e293b;">{customer_name}</td>
            </tr></table>
          </td></tr>
          <tr><td style="padding:10px 0;border-bottom:1px solid #f1f5f9;">
            <table width="100%"><tr>
              <td style="font-size:13px;color:#64748b;">Phone</td>
              <td align="right" style="font-size:13px;color:#1e293b;">{customer_phone or '—'}</td>
            </tr></table>
          </td></tr>
          <tr><td style="padding:10px 0;border-bottom:1px solid #f1f5f9;">
            <table width="100%"><tr>
              <td style="font-size:13px;color:#64748b;">Order Ref</td>
              <td align="right" style="font-size:13px;color:#1e293b;">{order_number}</td>
            </tr></table>
          </td></tr>
          <tr><td style="padding:10px 0;">
            <table width="100%"><tr>
              <td style="font-size:13px;color:#64748b;">Outstanding Balance</td>
              <td align="right" style="font-size:16px;font-weight:800;color:#ef4444;">{balance}</td>
            </tr></table>
          </td></tr>
        </table>
      </td></tr>
    </table>
    <p style="margin:0;font-size:14px;color:#475569;text-align:center;">
      Please follow up with the customer to collect payment.
    </p>
    """

    text_body = (
        f"Credit Alert: {customer_name}\n"
        f"Phone: {customer_phone or '—'}\n"
        f"Order: {order_number}\n"
        f"Balance: {balance}\n\n— SwiftPOS"
    )

    html = _render_email_html(
        company_name='SwiftPOS',
        title="Credit Transaction Recorded",
        subtitle=f"Balance outstanding for {customer_name}",
        header_color='#d97706',
        body_html=body_html,
    )

    try:
        msg = _make_email(subject, text_body, html, admins)
        msg.send(fail_silently=False)
    except Exception as e:
        import logging
        logging.getLogger(__name__).error(f"Failed to send credit alert: {e}")


def send_credit_customer_alert(customer_name, customer_phone, order_number, balance):
    """Send credit alert in background thread."""
    _send_in_background(_do_send_credit_alert, customer_name, customer_phone, order_number, balance)


# ─────────────────────────────────────────────

# NOTE: The daily business report is handled per-company by:
#   analytics/email_reports.py  →  send_daily_report(company)
# which sends to each company's business_email / admin user email.
# Do NOT use a platform-wide daily report here — it would go to ADMIN_EMAIL.



# ─────────────────────────────────────────────
#  TWO-FACTOR AUTHENTICATION OTP EMAIL
# ─────────────────────────────────────────────

def _do_send_2fa_otp(user_email, otp_code, company_name, username):
    """Send a 2FA OTP code to the user's email address."""
    if not settings.EMAIL_HOST_USER:
        return

    subject = f"Your {company_name} login verification code"

    body_html = f"""
    <p style="margin:0 0 16px;font-size:15px;color:#334155;">
      Hi <strong>{username}</strong>,
    </p>
    <p style="margin:0 0 24px;font-size:15px;color:#475569;line-height:1.6;">
      Someone is trying to sign in to your <strong>{company_name}</strong> SwiftPOS account.
      Use the code below to complete your login.
    </p>

    <!-- OTP Box -->
    <table border="0" cellpadding="0" cellspacing="0" width="100%"
           style="background:#f8fafc;border:2px dashed #c7d2fe;border-radius:14px;margin-bottom:24px;">
      <tr>
        <td align="center" style="padding:28px 20px;">
          <p style="margin:0 0 8px;font-size:11px;font-weight:700;color:#6366f1;
                     text-transform:uppercase;letter-spacing:2px;">
            Your One-Time Code
          </p>
          <p style="margin:0;font-size:44px;font-weight:800;letter-spacing:14px;
                     color:#1e1b4b;font-family:'Courier New',Courier,monospace;">
            {otp_code}
          </p>
          <p style="margin:12px 0 0;font-size:13px;color:#94a3b8;">
            &#x23F1; Expires in <strong>10 minutes</strong>
          </p>
        </td>
      </tr>
    </table>

    <p style="margin:0;font-size:13px;color:#94a3b8;text-align:center;">
      If you did not attempt to log in,
      <strong>ignore this email</strong> and consider changing your password.
    </p>
    """

    text_body = (
        f"Hi {username},\n\n"
        f"Your SwiftPOS login code for {company_name} is:\n\n"
        f"   {otp_code}\n\n"
        f"This code expires in 10 minutes. Do not share it.\n\n"
        f"— SwiftPOS Security"
    )

    html = _render_email_html(
        company_name=company_name,
        title="Verification Required",
        subtitle=f"{company_name} — Login Security",
        header_color='#4F46E5',
        body_html=body_html,
        footer_note='This is an automated security email from SwiftPOS. Do not reply.',
    )

    try:
        msg = _make_email(subject, text_body, html, [user_email], attach_logo=False)
        msg.send(fail_silently=False)
    except Exception as e:
        import logging
        logging.getLogger(__name__).error(f"Failed to send 2FA OTP email to {user_email}: {e}")


def send_2fa_otp_email(user_email, otp_code, company_name, username):
    """Send 2FA OTP email in a background thread so login is never blocked."""
    _send_in_background(_do_send_2fa_otp, user_email, otp_code, company_name, username)
