"""Order-related email notifications — customer gets emailed on every status
change to their order, the picker gets emailed when an order actually
reaches them (payment confirmed), and admin gets emailed on every order
placed and every status change, so nothing happens silently."""

from django.conf import settings
from django.urls import reverse

from accounts.supabase_client import get_client
from .emailer import notify_admin, send_email
from .order_status import get_status_label
from .sms import send_sms, sms_lang as _sms_lang, sms_text as _sms_text
from .translations import get_translations

# Emails are English-only regardless of the customer's chosen site language
# (an established convention — see every other transactional email here).
# SMS is deliberately on its own independent setting (sms_language column) —
# it defaults to Swahili regardless of what the web UI's own language is set
# to (that one defaults to English), and only switches to English for a user
# who has actually set their SMS language to English in their profile.
_EN = get_translations('en')
_SW = get_translations('sw')


def _status_label_for_sms(lang, status):
    return get_status_label(_EN if lang == 'en' else _SW, status)


def _user_contact(user_id):
    if not user_id:
        return None, None, None, 'sw'
    resp = get_client().table('pickker_users').select('email, phone_number, first_name, sms_language').eq('id', user_id).execute()
    if not resp.data:
        return None, None, None, 'sw'
    row = resp.data[0]
    return row['email'], row['phone_number'], row['first_name'], _sms_lang(row.get('sms_language'))


def _order_link(order_id, role):
    """Absolute link to the order's own detail page — for the customer this
    is also the live-tracking view once the order reaches in_transit, so the
    exact same link doubles as the tracking link, no separate URL needed."""
    path = reverse('accounts:picker_order_detail' if role == 'picker' else 'market:order_detail', args=[order_id])
    return settings.SITE_BASE_URL.rstrip('/') + path


def notify_order_placed(order):
    from .payment_methods import build_whatsapp_proof_link, get_active_payment_methods

    customer_email, customer_phone, customer_name, customer_lang = _user_contact(order['customer_id'])
    link = _order_link(order['id'], 'customer')

    # Same Lipa Namba + WhatsApp-proof-link flow shown on the order page
    # itself — repeated here so the payment step doesn't require opening the
    # app at all, straight from the SMS.
    whatsapp_link = build_whatsapp_proof_link(
        order['id'], order['total_amount'], customer_name or '', customer_phone or '', customer_email or '',
    )
    payment_methods = get_active_payment_methods()
    primary_method = payment_methods[0] if payment_methods else None
    if primary_method:
        provider_bit = primary_method['provider_label']
        if primary_method.get('account_name'):
            provider_bit += f", {primary_method['account_name']}"
        payment_line_en = (
            f"Please pay TSh {order['total_amount']} to Lipa Namba {primary_method['lipa_number']} "
            f"({provider_bit}), then send your payment screenshot via the link below: {whatsapp_link}"
        )
        payment_line_sw = (
            f"Tafadhali lipia TSh {order['total_amount']} katika Lipa Namba {primary_method['lipa_number']} "
            f"({provider_bit}) kisha tuma picha katika link iliyopo hapa chini: {whatsapp_link}"
        )
    else:
        payment_line_en = f"Send your payment screenshot via the link below: {whatsapp_link}"
        payment_line_sw = f"Tuma picha ya malipo katika link iliyopo hapa chini: {whatsapp_link}"

    send_email(
        customer_email,
        f"Order #{order['id']} received — PickkerMarket",
        f"Hi {customer_name or ''},\n\n"
        f"We've received your order #{order['id']} for TSh {order['total_amount']}, "
        f"scheduled for delivery on {order['delivery_date']} ({order['delivery_time_slot']}).\n\n"
        f"{payment_line_en}\n\n"
        f"View your order:\n{link}\n\n"
        "— The PickkerMarket Team",
    )
    # Short on purpose — full Lipa Namba + WhatsApp-proof instructions are in
    # the email above and on the order page itself (the same link below), so
    # the SMS doesn't need to repeat them and stays to one segment.
    send_sms(customer_phone, _sms_text(
        customer_lang,
        f"PickkerMarket: Order #{order['id']} received, TSh {order['total_amount']}. Pay & view: {link}",
        f"PickkerMarket: Oda #{order['id']} imepokelewa, TSh {order['total_amount']}. Lipa na maelezo: {link}",
    ))
    notify_admin(
        f"New order #{order['id']} placed",
        f"Customer: {customer_name} ({customer_email})\n"
        f"Total: TSh {order['total_amount']}\n"
        f"Delivery: {order['delivery_date']} ({order['delivery_time_slot']})\n"
        f"Address: {order['delivery_address']}\n"
        "Status: Awaiting payment confirmation.",
    )


def notify_order_status_changed(order, new_status, changed_by_role='admin'):
    customer_email, customer_phone, customer_name, customer_lang = _user_contact(order['customer_id'])
    label = get_status_label(_EN, new_status)
    customer_link = _order_link(order['id'], 'customer')

    # in_transit is the picker actually being on the way — the same order
    # link already shows the live tracking map at that status, so this is
    # just the "track your picker" callout on top of the normal update.
    if new_status == 'in_transit':
        customer_email_body = (
            f"Hi {customer_name or ''},\n\n"
            f"Your picker is now on the way with order #{order['id']}!\n\n"
            f"Track your picker live:\n{customer_link}\n\n"
            "— The PickkerMarket Team"
        )
    else:
        customer_email_body = (
            f"Hi {customer_name or ''},\n\n"
            f"Your order #{order['id']} is now: {label}.\n\n"
            f"View your order:\n{customer_link}\n\n"
            "— The PickkerMarket Team"
        )
    send_email(customer_email, f"Order #{order['id']} update: {label} — PickkerMarket", customer_email_body)

    customer_label = _status_label_for_sms(customer_lang, new_status)
    if new_status == 'in_transit':
        customer_sms = _sms_text(
            customer_lang,
            f"PickkerMarket: Your picker is on the way with Order #{order['id']}! Track live: {customer_link}",
            f"PickkerMarket: Mchukuzi wako yupo njiani na Oda #{order['id']}! Fuatilia moja kwa moja: {customer_link}",
        )
    else:
        customer_sms = _sms_text(
            customer_lang,
            f"PickkerMarket: Order #{order['id']} is now {customer_label}. {customer_link}",
            f"PickkerMarket: Oda #{order['id']} sasa ni {customer_label}. {customer_link}",
        )
    send_sms(customer_phone, customer_sms)

    if new_status == 'confirmed' and order.get('picker_id'):
        picker_email, picker_phone, picker_name, picker_lang = _user_contact(order['picker_id'])
        picker_link = _order_link(order['id'], 'picker')

        # Any instructions the customer left at checkout were saved silently
        # (no picker notification at the time, since the order wasn't
        # confirmed yet) — this is the first the picker hears of them,
        # bundled into the same "new delivery" notification rather than a
        # separate message that would've landed before they could act on it.
        instructions_text = None
        try:
            from .messaging import get_messages
            customer_notes = [m['message'] for m in get_messages(order['id']) if m['sender_id'] == order['customer_id']]
            if customer_notes:
                instructions_text = ' / '.join(customer_notes)
        except Exception:
            instructions_text = None

        instructions_email_line = f"Customer instructions: {instructions_text}\n" if instructions_text else ''

        send_email(
            picker_email,
            f"New delivery assigned — Order #{order['id']}",
            f"Hi {picker_name or ''},\n\n"
            f"Order #{order['id']} has been confirmed and assigned to you.\n\n"
            f"Customer: {customer_name or ''} ({customer_phone or 'no phone on file'})\n"
            f"Deliver to: {order['delivery_address']}\n"
            f"Scheduled: {order['delivery_date']} ({order['delivery_time_slot']})\n"
            f"Delivery fee: TSh {order['delivery_fee']}\n"
            f"Picking fee: TSh {order.get('picking_fee') or 0}\n"
            f"Package fee: TSh {order.get('package_fee') or 0}\n"
            f"{instructions_email_line}\n"
            f"Open the order:\n{picker_link}\n\n"
            "— The PickkerMarket Team",
        )
        # Short on purpose — customer phone/address/instructions are all in
        # the email above and on the order page itself; the SMS is just the
        # "you've got a delivery, go look" ping, one segment.
        send_sms(picker_phone, _sms_text(
            picker_lang,
            f"PickkerMarket: New delivery — Order #{order['id']} for {customer_name or 'a customer'}, "
            f"{order['delivery_date']}. Details: {picker_link}",
            f"PickkerMarket: Oda mpya — Oda #{order['id']} ya {customer_name or 'mteja'}, "
            f"{order['delivery_date']}. Maelezo: {picker_link}",
        ))
    elif order.get('picker_id') and new_status in ('picking', 'in_transit', 'delivered', 'cancelled'):
        picker_email, picker_phone, picker_name, picker_lang = _user_contact(order['picker_id'])
        picker_link = _order_link(order['id'], 'picker')
        send_email(
            picker_email,
            f"Order #{order['id']} update: {label}",
            f"Hi {picker_name or ''},\n\nOrder #{order['id']} is now: {label}.\n\n"
            f"Open the order:\n{picker_link}\n\n— The PickkerMarket Team",
        )
        picker_label = _status_label_for_sms(picker_lang, new_status)
        send_sms(picker_phone, _sms_text(
            picker_lang,
            f"PickkerMarket: Order #{order['id']} is now {picker_label}. {picker_link}",
            f"PickkerMarket: Oda #{order['id']} sasa ni {picker_label}. {picker_link}",
        ))

    notify_admin(
        f"Order #{order['id']} status changed to {label}",
        f"Customer: {customer_name} ({customer_email})\n"
        f"New status: {label}\n"
        f"Changed via: {changed_by_role}",
    )


def get_b2b_invoice_data(order, order_items_rows, truck_type):
    """Shared business-name/line-item resolution for the B2B invoice — used
    by both send_b2b_invoice (the automatic plain-text email) and
    market/views.py::order_invoice (the in-app invoice page a B2B customer
    can revisit any time), so the two can't drift on what "the invoice"
    actually shows."""
    business_name = None
    profile_resp = get_client().table('pickker_customer_profiles').select('business_name').eq('user_id', order['customer_id']).execute()
    if profile_resp.data:
        business_name = profile_resp.data[0].get('business_name')

    items = [
        {
            'product_name': item['product_name'],
            'qty_label': f"{item['quantity']} {item.get('measure_label') or ''}".strip(),
            'unit_price': item['unit_price'],
            'line_total': item['line_total'],
        }
        for item in order_items_rows
    ]
    return business_name, items


def send_b2b_invoice(order, order_items_rows, truck_type):
    """Itemized invoice emailed to a B2B customer right after order
    placement — a plain formatted email, not a PDF, matching the rest of
    this app's transactional emails."""
    customer_email, customer_phone, customer_name, customer_lang = _user_contact(order['customer_id'])
    if not customer_email:
        return

    business_name, items = get_b2b_invoice_data(order, order_items_rows, truck_type)

    lines = []
    for item in items:
        lines.append(
            f"  {item['product_name']:<30} {item['qty_label']:<14} "
            f"TSh {item['unit_price']:>10}   TSh {item['line_total']:>10}"
        )
    items_block = '\n'.join(lines)

    truck_line = ''
    if truck_type:
        truck_line = f"Truck: {truck_type['name']} ({truck_type.get('capacity_label', '')})\n"

    body = (
        f"Invoice for Order #{order['id']}\n"
        f"{'-' * 50}\n"
        f"Bill To: {business_name or customer_name or ''}\n"
        f"Date: {order['delivery_date']} ({order['delivery_time_slot']})\n"
        f"{truck_line}\n"
        f"{'Item':<31}{'Qty':<14}{'Unit Price':>13}{'Total':>13}\n"
        f"{items_block}\n\n"
        f"Subtotal:                                          TSh {order['items_subtotal']}\n"
        f"Delivery fee:                                       TSh {order['delivery_fee']}\n"
        f"Picking fee:                                        TSh {order['picking_fee']}\n"
        f"Package fee:                                        TSh {order.get('package_fee') or 0}\n"
        f"TOTAL:                                               TSh {order['total_amount']}\n\n"
        "Thank you for your business.\n\n"
        "— The PickkerMarket Team"
    )
    send_email(customer_email, f"Invoice for Order #{order['id']} — PickkerMarket", body)
    link = _order_link(order['id'], 'customer')
    send_sms(customer_phone, _sms_text(
        customer_lang,
        f"PickkerMarket: Invoice for Order #{order['id']} — Total TSh {order['total_amount']}. Full breakdown in your email. {link}",
        f"PickkerMarket: Ankara ya Oda #{order['id']} — Jumla TSh {order['total_amount']}. Maelezo kamili kwenye barua pepe yako. {link}",
    ))


def notify_payment_released(order):
    """Tells the picker/company (order.picker_id -- the same field either
    way, see market/fleet.py::assign_driver_to_order) that the platform has
    released the held payment for this order, once admin confirms it via
    accounts/views.py::admin_release_payment. No email/SMS is sent to the
    customer here -- this is purely a fulfiller-side notification."""
    picker_id = order.get('picker_id')
    if not picker_id:
        return
    picker_email, picker_phone, picker_name, picker_lang = _user_contact(picker_id)
    link = _order_link(order['id'], 'picker')
    send_email(
        picker_email,
        f"Payment released for Order #{order['id']} — PickkerMarket",
        f"Hi {picker_name or ''},\n\n"
        f"The held payment for Order #{order['id']} has been released.\n\n"
        f"View the order:\n{link}\n\n"
        "— The PickkerMarket Team",
    )
    send_sms(picker_phone, _sms_text(
        picker_lang,
        f"PickkerMarket: Payment released for Order #{order['id']}. {link}",
        f"PickkerMarket: Malipo yametolewa kwa Oda #{order['id']}. {link}",
    ))


def notify_new_message(order, sender_role, message_text):
    """Emails the OTHER party in an order's chat when a new message comes
    in. There's no inbound-email parsing in this app, so the email is
    explicit that replying means opening the order page in PickkerMarket —
    not replying to the email itself."""
    if sender_role == 'customer':
        recipient_id = order.get('picker_id')
        recipient_role = 'picker'
    else:
        recipient_id = order.get('customer_id')
        recipient_role = 'customer'

    if not recipient_id:
        return
    recipient_email, recipient_phone, recipient_name, recipient_lang = _user_contact(recipient_id)
    if not recipient_email and not recipient_phone:
        return

    order_url = _order_link(order['id'], recipient_role)

    send_email(
        recipient_email,
        f"New message about Order #{order['id']} — PickkerMarket",
        f"Hi {recipient_name or ''},\n\n"
        f"You have a new message about Order #{order['id']}:\n\n"
        f"\"{message_text}\"\n\n"
        "This inbox doesn't accept replies by email — to reply, open the order in "
        f"PickkerMarket:\n{order_url}\n\n"
        "— The PickkerMarket Team",
    )
    # Short on purpose — the message text itself is in the email above, not
    # repeated here.
    send_sms(recipient_phone, _sms_text(
        recipient_lang,
        f"PickkerMarket: New message about Order #{order['id']} — reply in the app: {order_url}",
        f"PickkerMarket: Ujumbe mpya kuhusu Oda #{order['id']} — jibu kwenye programu: {order_url}",
    ))
