"""Compact, email-client-friendly weekly status reports for RVPs."""

from datetime import date, datetime
from email.message import EmailMessage
from html import escape
import os
import smtplib
import ssl
from zoneinfo import ZoneInfo


REPORT_TIMEZONE = ZoneInfo('America/New_York')


def report_date() -> date:
    return datetime.now(REPORT_TIMEZONE).date()


def recruit_stage(recruit: dict) -> str:
    """Mirror the dashboard's pipeline labels for a generated email."""
    if recruit['rvp_invoice_status'] == 'Invoiced':
        return 'RVP Invoiced'
    if recruit['reimbursement_status'] == 'Approved':
        return 'RVP Invoice Due'
    if recruit['reimbursement_submitted']:
        return 'Reimbursement'
    if recruit['license_app_submitted']:
        return 'Licensing'
    if recruit['prov_exam_status'] == 'Passed' or recruit['prov_exam_booked'] or recruit['qual_exam_status'] == 'Passed':
        return 'Prov Exam'
    if recruit['iba_status'] == 'Approved' and not recruit['whatsapp_invite_sent']:
        return 'WhatsApp Invite'
    if recruit['iba_status'] == 'Approved' and not recruit['pol_account_logged_in']:
        return 'App Login'
    if recruit['qual_exam_status'] == 'Failed' or all(recruit[f'{week}_{day}_attended'] for week in ('w1', 'w2') for day in ('sat', 'sun')):
        return 'Qual Exam'
    if recruit['llqp_class_date'] and recruit['llqp_class_date'] <= report_date().isoformat():
        return 'LLQP Class'
    if recruit['llqp_registered']:
        return 'LLQP Registered'
    return 'IBA Pending'


def render_weekly_email(rvp: str, recruits: list[dict], *, as_of: date | None = None) -> tuple[str, str, str]:
    """Return subject, plain text and a 600px HTML email with inline styles."""
    as_of = as_of or report_date()
    subject = f'Weekly recruit status · {as_of.isoformat()}'
    lines = [f'Weekly recruit status for {rvp}', f'Week of {as_of.isoformat()}', '', f'{len(recruits)} recruits', '']
    cards = []
    for recruit in recruits:
        name = f"{recruit['first_name']} {recruit['last_name']}"
        stage = recruit_stage(recruit)
        attendance = sum(bool(recruit[f'{week}_{day}_attended']) for week in ('w1', 'w2') for day in ('sat', 'sun'))
        details = [
            ('IBA', recruit['iba_status']),
            ('Class', f'{attendance}/4 days'),
            ('Qual exam', recruit['qual_exam_status']),
            ('Prov exam', recruit['prov_exam_status']),
            ('Life license', recruit['license_app_status']),
            ('Reimbursement', recruit['reimbursement_status'] if recruit['reimbursement_submitted'] else 'Not requested'),
        ]
        lines.append(f'{name} — {stage}')
        lines.append('  ' + ' · '.join(f'{label}: {value}' for label, value in details))
        lines.append('')
        detail_html = ''.join(
            f'<tr><td style="padding:5px 8px;color:#64748b;font-size:12px;width:42%;vertical-align:top">{escape(label)}</td>'
            f'<td style="padding:5px 8px;color:#1e293b;font-size:12px;font-weight:600;vertical-align:top">{escape(str(value))}</td></tr>'
            for label, value in details
        )
        cards.append(
            '<tr><td style="padding:0 0 12px">'
            '<table role="presentation" cellpadding="0" cellspacing="0" width="100%" '
            'style="width:100%;border-collapse:collapse;background:#ffffff">'
            '<tr><td style="padding:14px 16px;background:#eef2ff;border:1px solid #dbe3ee">'
            f'<span style="font-size:15px;font-weight:700;color:#1e293b">{escape(name)}</span><br>'
            f'<span style="font-size:11px;font-weight:700;color:#4338ca;text-transform:uppercase">{escape(stage)}</span>'
            '</td></tr><tr><td style="padding:10px 8px;border:1px solid #dbe3ee">'
            f'<table role="presentation" cellpadding="0" cellspacing="0" width="100%">{detail_html}</table>'
            '</td></tr></table></td></tr>'
        )
    if not cards:
        cards.append('<tr><td style="padding:18px;background:#ffffff;color:#475569;border:1px solid #dbe3ee">No recruits are currently assigned.</td></tr>')
    html = (
        '<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>'
        '<body style="margin:0;padding:0;background:#eef2f7;font-family:Arial,Helvetica,sans-serif">'
        '<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#eef2f7">'
        '<tr><td align="center" style="padding:20px 10px">'
        '<table role="presentation" cellpadding="0" cellspacing="0" width="100%" '
        'style="width:100%;max-width:600px;border-collapse:collapse;background:#f8fafc">'
        '<tr><td style="padding:22px;background:#312e81;color:#ffffff">'
        '<span style="font-size:11px;font-weight:700;letter-spacing:1px;color:#c7d2fe">PRIMERICA RECRUIT TRACKER</span>'
        '<h1 style="margin:8px 0 6px;font-size:22px;line-height:1.25;color:#ffffff">Weekly Recruit Status</h1>'
        f'<span style="font-size:13px;color:#e0e7ff">{escape(rvp)} · Week of {as_of.isoformat()}</span>'
        '</td></tr>'
        f'<tr><td style="padding:18px 20px 6px;font-size:14px;font-weight:700;color:#1e293b">{len(recruits)} recruit{"s" if len(recruits) != 1 else ""} in your pipeline</td></tr>'
        '<tr><td style="padding:10px 20px 20px">'
        '<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="border-collapse:collapse">'
        + ''.join(cards) +
        '</table></td></tr></table></td></tr></table></body></html>'
    )
    return subject, '\n'.join(lines), html


def send_weekly_email(recipient: str, subject: str, plain: str, html: str) -> None:
    """Send a multipart alternative message through the configured TLS mailbox."""
    host = os.environ.get('LIC_SMTP_HOST')
    username = os.environ.get('LIC_SMTP_USERNAME')
    password = os.environ.get('LIC_SMTP_PASSWORD')
    sender = os.environ.get('LIC_SMTP_FROM') or username
    if not all((host, username, password, sender)):
        raise RuntimeError('Email sending is not configured.')
    port = int(os.environ.get('LIC_SMTP_PORT', '465'))
    message = EmailMessage()
    message['From'] = sender
    message['To'] = recipient
    message['Subject'] = subject
    message.set_content(plain)
    message.add_alternative(html, subtype='html')
    with smtplib.SMTP_SSL(host, port, context=ssl.create_default_context(), timeout=15) as smtp:
        smtp.login(username, password)
        smtp.send_message(message)
