#!/usr/bin/env python3
"""
Nudge Worker - Re-engagement campaign automation
Reads v_no_reply_candidates, sends templated nudge messages, logs to nudge_log.
"""
import os
import time as time_module
import random
from datetime import datetime, time
from zoneinfo import ZoneInfo
from typing import Optional, Dict, Any, List
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from utils.tools import get_client, log_message


def ok_to_reply(now=None) -> bool:
    """
    Check if replies are allowed (06:00–23:59:59 UK time).
    
    Args:
        now: Optional datetime to check (defaults to current UK time)
    
    Returns:
        True if within reply window, False otherwise
    """
    tz = ZoneInfo("Europe/London")
    now = now or datetime.now(tz)
    # Replies allowed 06:00–00:00 (midnight)
    return time(6, 0) <= now.time() <= time(23, 59, 59)


def get_customer_context(agreement_id: int) -> Optional[Dict[str, Any]]:
    """
    Fetch customer context for template rendering.
    
    Args:
        agreement_id: The agreement ID
    
    Returns:
        Dict with first_name, vehicle_model, agreement_number or None
    """
    client = get_client()
    
    # Join agreement -> customer, agreement -> vehicle
    result = client.table('agreement') \
        .select('agreement_number, customer(first_name), vehicle(model)') \
        .eq('id', agreement_id) \
        .execute()
    
    if not result.data or len(result.data) == 0:
        return None
    
    row = result.data[0]
    customer = row.get('customer') or {}
    vehicle = row.get('vehicle') or {}
    
    return {
        'agreement_number': row.get('agreement_number'),
        'first_name': customer.get('first_name', 'there'),
        'vehicle_model': vehicle.get('model', 'your vehicle')
    }


def fetch_templates(slugs: List[str]) -> Dict[str, Dict[str, Any]]:
    """
    Fetch reply templates by slug.
    
    Args:
        slugs: List of template slugs to fetch
    
    Returns:
        Dict mapping slug -> {body, max_len}
    """
    client = get_client()
    result = client.table('reply_template') \
        .select('slug, body, max_len') \
        .in_('slug', slugs) \
        .eq('active', True) \
        .execute()
    
    templates = {}
    for row in result.data:
        templates[row['slug']] = {
            'body': row['body'],
            'max_len': row.get('max_len')
        }
    
    return templates


def render_template(template_body: str, context: Dict[str, Any], max_len: Optional[int] = None) -> str:
    """
    Render template with context variables.
    
    Args:
        template_body: Template string with {{variable}} placeholders
        context: Dict of variables to substitute
        max_len: Optional max length to enforce
    
    Returns:
        Rendered message text
    """
    text = template_body
    for key, value in context.items():
        text = text.replace(f'{{{{{key}}}}}', str(value))
    
    # Enforce max_len if provided
    if max_len and len(text) > max_len:
        text = text[:max_len - 1] + '…'
    
    return text


def log_nudge(agreement_id: int, nudge_type: str) -> None:
    """
    Insert row into nudge_log table.
    
    Args:
        agreement_id: Agreement ID
        nudge_type: Type of nudge (nudge_48h, nudge_7d)
    """
    client = get_client()
    client.table('nudge_log').insert({
        'agreement_id': agreement_id,
        'nudge_type': nudge_type
    }).execute()


def run():
    """
    Main nudge worker loop:
    1. Check ok_to_reply() hours
    2. Fetch candidates from v_no_reply_candidates
    3. Load templates
    4. Process each candidate (FIFO by agreement_id)
    5. Log to contact_history and nudge_log
    6. Sleep randomly between messages
    """
    print("=" * 80)
    print("🔔 NUDGE WORKER - Re-engagement Campaign")
    print("=" * 80)
    
    # Check reply hours
    if not ok_to_reply():
        now = datetime.now(ZoneInfo("Europe/London"))
        print(f"⏰ Outside reply hours (current time: {now.strftime('%H:%M:%S')} UK)")
        print("   Reply window: 06:00–23:59:59 UK time")
        print("   Exiting gracefully (exit 0)")
        return
    
    print("✅ Within reply hours (06:00–23:59:59 UK)")
    
    # Connect to Supabase
    client = get_client()
    
    # Fetch candidates (FIFO by agreement_id)
    print("\n📋 Fetching nudge candidates...")
    candidates = client.table('v_no_reply_candidates') \
        .select('*') \
        .order('agreement_id', desc=False) \
        .execute()
    
    if not candidates.data or len(candidates.data) == 0:
        print("   ℹ️  No candidates found")
        print("=" * 80)
        return
    
    print(f"   Found {len(candidates.data)} candidate(s)")
    
    # Fetch templates
    print("\n📝 Loading nudge templates...")
    templates = fetch_templates(['nudge_48h', 'nudge_7d'])
    
    if not templates:
        print("   ❌ No active templates found for nudge_48h or nudge_7d")
        print("=" * 80)
        return
    
    print(f"   Loaded {len(templates)} template(s): {', '.join(templates.keys())}")
    
    # Process candidates
    sent_count = 0
    for candidate in candidates.data:
        agreement_id = candidate['agreement_id']
        nudge_type = candidate['nudge_type']
        
        print(f"\n🔍 Processing agreement_id={agreement_id}, nudge_type={nudge_type}")
        
        # Get customer context
        context = get_customer_context(agreement_id)
        if not context:
            print(f"   ⚠️  Could not fetch customer context, skipping")
            continue
        
        agreement_number = context['agreement_number']
        first_name = context['first_name']
        vehicle_model = context['vehicle_model']
        
        print(f"   Customer: {first_name}")
        print(f"   Vehicle: {vehicle_model}")
        print(f"   Agreement: {agreement_number}")
        
        # Get template
        template = templates.get(nudge_type)
        if not template:
            print(f"   ⚠️  No template found for {nudge_type}, skipping")
            continue
        
        # Render message
        message_text = render_template(
            template['body'],
            context,
            template.get('max_len')
        )
        
        print(f"   📤 Message ({len(message_text)} chars): {message_text[:60]}...")
        
        # Log to contact_history
        log_message(
            agreement_ref=agreement_number,
            channel='whatsapp',
            direction='outbound',
            message_text=message_text,
            intent_label=nudge_type,
            template_slug=nudge_type,
            source='ai',
            model=None
        )
        
        # Log to nudge_log
        log_nudge(agreement_id, nudge_type)
        
        sent_count += 1
        print(f"   ✅ Sent and logged")
        
        # Human-like delay (5-15 seconds)
        if sent_count < len(candidates.data):
            delay = random.randint(5, 15)
            print(f"   ⏳ Sleeping {delay}s...")
            time_module.sleep(delay)
    
    # Summary
    print("\n" + "=" * 80)
    print(f"✨ SUMMARY: Sent {sent_count} nudge message(s)")
    print("=" * 80)


if __name__ == '__main__':
    run()
