"""Per-order chat between a customer and their assigned picker — so they can
coordinate on a specific delivery (e.g. exact drop-off spot). Scoped to one
order, not a general-purpose inbox.

Read tracking (pickker_message_reads) records the last message id each
participant has actually looked at, per order — used to badge unseen
messages in the nav and to decide whether a just-sent message should trigger
an email (no point emailing someone who's got the thread open right now)."""

from concurrent.futures import ThreadPoolExecutor

from accounts.supabase_client import get_client


def get_messages(order_id):
    return (
        get_client()
        .table('pickker_order_messages')
        .select('*')
        .eq('order_id', order_id)
        .order('created_at')
        .execute()
        .data
    )


def send_message(order_id, sender_id, message):
    message = (message or '').strip()
    if not message:
        return None
    resp = get_client().table('pickker_order_messages').insert({
        'order_id': order_id,
        'sender_id': sender_id,
        'message': message[:1000],
    }).execute()
    return resp.data[0] if resp.data else None


def mark_messages_seen(user_id, order_id):
    client = get_client()
    latest = (
        client.table('pickker_order_messages')
        .select('id')
        .eq('order_id', order_id)
        .order('id', desc=True)
        .limit(1)
        .execute()
        .data
    )
    if not latest:
        return
    last_id = latest[0]['id']
    existing = client.table('pickker_message_reads').select('id').eq('user_id', user_id).eq('order_id', order_id).execute()
    if existing.data:
        client.table('pickker_message_reads').update({'last_seen_message_id': last_id}).eq('id', existing.data[0]['id']).execute()
    else:
        client.table('pickker_message_reads').insert({
            'user_id': user_id, 'order_id': order_id, 'last_seen_message_id': last_id,
        }).execute()


def get_unseen_message_count(user_id, order_ids):
    """Total unread messages (sent by someone else) across the given orders.
    The reads and messages lookups don't depend on each other, so they're
    fired in parallel — this runs on every page load (nav badge), so the
    round-trip savings compound across the whole site."""
    order_ids = list(order_ids)
    if not order_ids:
        return 0
    client = get_client()

    def _fetch_reads():
        return (
            client.table('pickker_message_reads')
            .select('order_id, last_seen_message_id')
            .eq('user_id', user_id)
            .in_('order_id', order_ids)
            .execute()
            .data
        )

    def _fetch_messages():
        return (
            client.table('pickker_order_messages')
            .select('id, order_id, sender_id')
            .in_('order_id', order_ids)
            .neq('sender_id', user_id)
            .execute()
            .data
        )

    with ThreadPoolExecutor(max_workers=2) as executor:
        reads_future = executor.submit(_fetch_reads)
        messages_future = executor.submit(_fetch_messages)
        reads = reads_future.result()
        messages = messages_future.result()

    last_seen_by_order = {r['order_id']: r['last_seen_message_id'] for r in reads}
    count = 0
    for m in messages:
        last_seen = last_seen_by_order.get(m['order_id'])
        if last_seen is None or m['id'] > last_seen:
            count += 1
    return count
