"""Batch reply-generation support + send scheduling for lead campaigns.

Pure helpers (no Flask imports) so they're trivially testable; app.py does the
DB row extraction and passes plain dicts/values in.
"""
import random
from datetime import timedelta

# Standing policies published on the site's warranty page (7-day / 1,000 km
# inspection period, Ontario safety certification included). Flip here if the
# published policy changes.
INSPECTION_PERIOD_ACTIVE = True
ONTARIO_SAFETY_INCLUDED = True


def availability_from_status(status):
    s = (status or "").strip().lower()
    if s.startswith("avail"):
        return "available"
    if s.startswith("unavail") or s.startswith("sold"):
        return "unavailable"
    return "unknown"


def _first_name(full_name):
    parts = (full_name or "").strip().split()
    return parts[0] if parts else ""


def _format_price(price):
    try:
        return f"{int(float(str(price or '').replace(',', '').replace('$', ''))):,}"
    except (ValueError, TypeError):
        return ""


def build_input_data(lead, vehicle, tracking_url, *, availability_status="unknown",
                     carfax_on_listing=False, carfax_url="", inspection_report_url="",
                     free_delivery_active=False):
    """The INPUT DATA object the 46_CARS master prompt defines. Anything we cannot
    verify is left empty/false/'unknown' so the AI hedges instead of inventing."""
    name = (lead.get("name") or "").strip()
    phone = (lead.get("phone") or "").strip()
    vehicle_name = " ".join(p for p in (
        str(vehicle.get("year") or ""), str(vehicle.get("make") or ""),
        str(vehicle.get("model") or ""), str(vehicle.get("trim") or ""),
    ) if p).strip()
    return {
        "channel": "email",
        "conversation_type": "first_reply",
        "customer_first_name": _first_name(name),
        "customer_full_name": name,
        "customer_message": (lead.get("message") or "").strip(),
        "customer_language": "",
        "phone_number": phone,
        "phone_already_available": bool(phone),
        "vehicle_name": vehicle_name,
        "advertised_price": _format_price(vehicle.get("price")),
        "vehicle_url": tracking_url or "",
        "availability_status": availability_status,
        "vehicle_location": "",
        "distance_from_office": "",
        "vehicle_source": "",
        "carfax_available": bool(carfax_on_listing),
        "carfax_on_listing": bool(carfax_on_listing),
        "carfax_url": carfax_url or "",
        "accident_history": "",
        "title_status": "",
        "service_records_available": False,
        "service_record_details": "",
        "third_party_inspection_completed": bool(inspection_report_url),
        "inspection_report_on_listing": bool(inspection_report_url),
        "inspection_report_url": inspection_report_url or "",
        "outside_ppi_allowed": False,
        "ontario_safety_included": ONTARIO_SAFETY_INCLUDED,
        "free_delivery_active": bool(free_delivery_active),
        "inspection_period_active": INSPECTION_PERIOD_ACTIVE,
        "buyer_city": "",
        "buyer_province": "",
        "alberta_tax_estimate_allowed": False,
        "offer_amount": "",
        "offer_status": "not applicable",
        "estimated_total": "",
        "additional_verified_facts": "",
    }


SMS_STYLE_HINTS = [
    "direct and friendly, answer first",
    "casual and short",
    "photos first, then price",
    "helpful advisor tone",
    "brief question back at the end",
    "straight to the point with the link early",
    "warm but minimal words",
    "availability first, then the link",
]


def sms_style_hint(link_id):
    """Deterministic per-lead style rotation so batch texts never share a template."""
    try:
        return SMS_STYLE_HINTS[int(link_id) % len(SMS_STYLE_HINTS)]
    except (TypeError, ValueError):
        return SMS_STYLE_HINTS[0]


def staggered_schedule_times(count, base_dt, rng=None):
    """First send exactly at base_dt; each subsequent +60..180s (cumulative)."""
    rng = rng or random
    times, current = [], base_dt
    for _ in range(max(0, int(count))):
        if times:
            current = current + timedelta(seconds=rng.randint(60, 180))
        times.append(current)
    return times


def due_scheduled_links(db, now_iso):
    return db.execute(
        "SELECT cl.* FROM campaign_links cl "
        "WHERE cl.reply_status = 'scheduled' AND cl.scheduled_at IS NOT NULL AND cl.scheduled_at <= ? "
        "ORDER BY cl.scheduled_at, cl.id",
        (now_iso,),
    ).fetchall()
