#!/usr/bin/env python3
"""
TextMagic SMS/MMS Sender for Swing Shift Golf Club.

Sends promotional texts, booking confirmations, and win-back messages
via the TextMagic API. Supports MMS (photos + links + long messages up to 1600 chars).

Usage:
  # Dry run — preview what would be sent
  python3 sms_sender.py --template slow_day --csv contacts.csv

  # Send for real
  python3 sms_sender.py --template slow_day --csv contacts.csv --send

  # Single message
  python3 sms_sender.py --to 6025551234 --message "Hey! Open bay at 3pm" --send

  # MMS with photo
  python3 sms_sender.py --to 6025551234 --message "Check this out" \\
      --media-url "https://theswingshift.golf/images/bay.jpg" --send

Environment:
  TEXTMAGIC_USERNAME — your TextMagic username
  TEXTMAGIC_API_KEY  — your TextMagic API key (v2)
"""

import argparse
import csv
import json
import os
import sys
import urllib.request
import urllib.parse
from datetime import datetime
from pathlib import Path

# --- Config ---
PROJECT_DIR = Path(__file__).parent.parent
APPROVAL_DIR = PROJECT_DIR / "ops" / "approvals" / "pending"
SENT_LOG = PROJECT_DIR / "12_Output" / "sms_sent_log.csv"

API_BASE = "https://rest.textmagic.com/api/v2"

# Load env
for env_file in [
    PROJECT_DIR / "automation" / "n8n" / ".env.local",
    PROJECT_DIR / "automation" / "n8n" / ".env",
]:
    if env_file.exists():
        for line in env_file.read_text().splitlines():
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                k, v = line.split("=", 1)
                os.environ.setdefault(k.strip(), v.strip())

TEXTMAGIC_USERNAME = os.environ.get("TEXTMAGIC_USERNAME", "")
TEXTMAGIC_API_KEY = os.environ.get("TEXTMAGIC_API_KEY", "")
BOOKING_URL = "https://theswingshift.golf/book"


# --- Templates ---
TEMPLATES = {
    "slow_day": {
        "subject": "Open Bay Today",
        "body": (
            "Hey {first_name}! Swing Shift has open bays today. "
            "Book now and save {discount}% with code {promo_code}.\n\n"
            "{booking_link}\n\n"
            "See you on the sim! 🏌️"
        ),
        "media_url": None,
    },
    "win_back": {
        "subject": "We Miss You",
        "body": (
            "Hey {first_name}, it's been a while! "
            "Come back to Swing Shift and get {discount}% off your next hour.\n\n"
            "Use code {promo_code}: {booking_link}\n\n"
            "Your bay is waiting. 🏌️"
        ),
        "media_url": None,
    },
    "booking_confirm": {
        "subject": "Booking Confirmed",
        "body": (
            "You're booked at Swing Shift!\n\n"
            "📅 {date} at {time}\n"
            "⏱ {duration} hour(s)\n"
            "👥 {party_size} player(s)\n\n"
            "Address: 10300 N Scottsdale Rd, Paradise Valley\n"
            "Questions? Reply to this text or call (602) 622-8192"
        ),
        "media_url": None,
    },
    "membership_promo": {
        "subject": "Membership Deal",
        "body": (
            "Hey {first_name}! You've been playing a lot at Swing Shift. "
            "Members save up to 50% per hour.\n\n"
            "Plans start at $129/mo with unlimited morning golf.\n\n"
            "Check it out: https://theswingshift.golf/memberships\n\n"
            "Questions? Just reply here."
        ),
        "media_url": None,
    },
    "welcome": {
        "subject": "Welcome to Swing Shift",
        "body": (
            "Welcome to Swing Shift Golf Club, {first_name}! 🎉\n\n"
            "Thanks for booking with us. Here's what to know:\n"
            "📍 10300 N Scottsdale Rd, Paradise Valley\n"
            "🕐 Open 6 AM - 11 PM daily\n"
            "🅿️ Free parking\n\n"
            "Book your next session: {booking_link}\n\n"
            "See you soon!"
        ),
        "media_url": None,
    },
}


def api_request(endpoint, data=None, method="POST"):
    """Make TextMagic API request."""
    url = f"{API_BASE}{endpoint}"
    headers = {
        "X-TM-Username": TEXTMAGIC_USERNAME,
        "X-TM-Key": TEXTMAGIC_API_KEY,
        "Content-Type": "application/json",
    }
    body = json.dumps(data).encode() if data else None
    req = urllib.request.Request(url, data=body, method=method)
    for k, v in headers.items():
        req.add_header(k, v)
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        error_body = e.read().decode() if e.fp else ""
        print(f"  API error {e.code}: {error_body}", file=sys.stderr)
        return {"error": e.code, "detail": error_body}
    except Exception as e:
        print(f"  Request error: {e}", file=sys.stderr)
        return {"error": str(e)}


def send_sms(to, message, media_url=None):
    """Send a single SMS or MMS via SimpleTexting."""
    # Normalize phone number
    phone = "".join(c for c in to if c.isdigit())
    if len(phone) == 10:
        phone = "1" + phone
    if not phone.startswith("1") or len(phone) != 11:
        return {"error": f"Invalid phone: {to}"}

    payload = {
        "phones": phone,
        "text": message,
    }
    # TextMagic MMS: use /sessions endpoint for media
    if media_url:
        # For MMS with media, use the messages endpoint with imageUrl
        payload["imageUrl"] = media_url

    return api_request("/messages", data=payload)


def render_template(template_name, fields):
    """Render a message template with field substitution."""
    tmpl = TEMPLATES.get(template_name)
    if not tmpl:
        raise ValueError(f"Unknown template: {template_name}")

    # Default field values
    defaults = {
        "first_name": "there",
        "discount": "20",
        "promo_code": "SWING20",
        "booking_link": BOOKING_URL,
        "date": "",
        "time": "",
        "duration": "1",
        "party_size": "1",
    }
    merged = {**defaults, **fields}

    # Build booking link with promo if applicable
    if merged.get("promo_code") and merged.get("discount"):
        merged["booking_link"] = (
            f"{BOOKING_URL}?promo={merged['promo_code']}"
            f"&discount={merged['discount']}"
        )

    body = tmpl["body"].format(**merged)
    return body, tmpl.get("media_url")


def log_sent(to, template, message, result):
    """Log sent message to CSV."""
    SENT_LOG.parent.mkdir(parents=True, exist_ok=True)
    is_new = not SENT_LOG.exists()
    with open(SENT_LOG, "a", newline="") as f:
        writer = csv.writer(f)
        if is_new:
            writer.writerow(["timestamp", "to", "template", "message_preview", "status"])
        status = "sent" if "error" not in result else f"error: {result.get('error')}"
        writer.writerow([
            datetime.now().isoformat(),
            to,
            template,
            message[:80],
            status,
        ])


def queue_for_approval(to, template, message, media_url=None):
    """Write message to approval queue instead of sending."""
    APPROVAL_DIR.mkdir(parents=True, exist_ok=True)
    ts = datetime.now().strftime("%Y%m%d_%H%M%S")
    phone_clean = "".join(c for c in to if c.isdigit())[-4:]
    filename = APPROVAL_DIR / f"sms_{template}_{phone_clean}_{ts}.json"
    data = {
        "type": "sms",
        "to": to,
        "template": template,
        "message": message,
        "media_url": media_url,
        "created": datetime.now().isoformat(),
        "status": "pending_approval",
    }
    filename.write_text(json.dumps(data, indent=2))
    return str(filename)


def main():
    parser = argparse.ArgumentParser(description="Swing Shift SMS/MMS Sender")
    parser.add_argument("--template", choices=list(TEMPLATES.keys()),
                        help="Message template to use")
    parser.add_argument("--to", help="Single phone number to send to")
    parser.add_argument("--csv", help="CSV file with contacts (needs 'phone' column)")
    parser.add_argument("--message", help="Custom message (overrides template)")
    parser.add_argument("--media-url", help="MMS image URL")
    parser.add_argument("--promo-code", default="", help="Promo code to include")
    parser.add_argument("--discount", default="", help="Discount percentage")
    parser.add_argument("--send", action="store_true",
                        help="Actually send (default: dry run / approval queue)")
    parser.add_argument("--force", action="store_true",
                        help="Skip approval queue, send immediately")
    args = parser.parse_args()

    if not args.to and not args.csv:
        parser.error("Need --to or --csv")

    if (not TEXTMAGIC_USERNAME or not TEXTMAGIC_API_KEY) and args.send:
        print("ERROR: TEXTMAGIC_USERNAME and TEXTMAGIC_API_KEY not set", file=sys.stderr)
        print("Add them to automation/n8n/.env.local", file=sys.stderr)
        sys.exit(1)

    # Build contact list
    contacts = []
    if args.to:
        contacts.append({"phone": args.to, "first_name": "there"})
    elif args.csv:
        with open(args.csv, "r") as f:
            reader = csv.DictReader(f)
            for row in reader:
                phone = row.get("phone") or row.get("Phone") or row.get("mobile") or ""
                if phone:
                    contacts.append({
                        "phone": phone,
                        "first_name": row.get("first_name") or row.get("First Name") or "there",
                        "email": row.get("email") or row.get("Email") or "",
                    })

    print(f"Contacts: {len(contacts)}")
    print(f"Template: {args.template or 'custom'}")
    print(f"Mode: {'SEND' if args.send else 'DRY RUN / APPROVAL QUEUE'}")
    print()

    sent = 0
    queued = 0
    errors = 0

    for contact in contacts:
        # Render message
        if args.message:
            message = args.message
            media_url = args.media_url
        elif args.template:
            fields = {
                "first_name": contact.get("first_name", "there"),
                "promo_code": args.promo_code,
                "discount": args.discount,
            }
            message, media_url = render_template(args.template, fields)
            if args.media_url:
                media_url = args.media_url
        else:
            print("ERROR: need --template or --message", file=sys.stderr)
            sys.exit(1)

        phone = contact["phone"]

        if not args.send:
            # Dry run — just print
            print(f"  → {phone}: {message[:100]}...")
            if not args.force:
                path = queue_for_approval(phone, args.template or "custom", message, media_url)
                queued += 1
        else:
            # Send for real
            result = send_sms(phone, message, media_url)
            log_sent(phone, args.template or "custom", message, result)
            if "error" not in result:
                print(f"  ✓ Sent to {phone}")
                sent += 1
            else:
                print(f"  ✗ Failed {phone}: {result}")
                errors += 1

    print(f"\nDone. Sent: {sent}, Queued: {queued}, Errors: {errors}")


if __name__ == "__main__":
    main()
