// WebSMS Connexus webhook receiver - handles MO (replies) + DLR (delivery reports).
// One URL handles both - the JSON `type` field tells you which event.
//
//   go run .
//
// Configure the webhook URL in Members Area -> API Keys.
package websms

import (
	"encoding/json"
	"log"
	"net/http"
)

type webhookPayload struct {
	Type       string          `json:"type"`
	MessageID  string          `json:"messageId"`
	From       string          `json:"from"`
	To         string          `json:"to"`
	Body       string          `json:"body"`
	Timestamp  int64           `json:"timestamp"`
	Status     string          `json:"status"`
	StatusCode int             `json:"statusCode"`
	Details    json.RawMessage `json:"details"`
}

// WebhookHandler can be wired into any http.ServeMux:
//
//	mux := http.NewServeMux()
//	mux.HandleFunc("/webhook", websms.WebhookHandler)
//	http.ListenAndServe(":3000", mux)
func WebhookHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}
	defer r.Body.Close()

	var p webhookPayload
	if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
		http.Error(w, "invalid payload", http.StatusBadRequest)
		return
	}

	switch p.Type {
	case "mo":
		// Incoming SMS reply
		log.Printf("mo: %s -> %s", p.From, p.Body)
		// TODO: persist + dispatch to your business logic

	case "dlr":
		// Delivery report
		// statusCode 1=DELIVRD, 2=UNDELIV, 4=QUEUED/expired, 8=ACCEPTD, 16=UNDELIV/rejected
		log.Printf("dlr: %s status=%s code=%d", p.MessageID, p.Status, p.StatusCode)
		// TODO: update the status of the original send

	default:
		log.Printf("unknown webhook type: %q", p.Type)
	}

	// Always respond 200 within 5s; failed webhooks are retried up to 3 times.
	w.Header().Set("Content-Type", "application/json")
	_, _ = w.Write([]byte(`{"ok":true}`))
}
