package main

import (
	"flag"
	"fmt"
	"os"

	apns "github.com/sideshow/apns2"
	"github.com/sideshow/apns2/token"
	"party.at/party/cmd/party/common"
	"party.at/party/internal/data"
)

func runSendTestNotification(args []string) {
	fs := flag.NewFlagSet("send-test-notification", flag.ExitOnError)
	email := fs.String("email", "", "Send to all device tokens for this user")
	deviceToken := fs.String("token", "", "Send to this specific device token")
	message := fs.String("message", "Test notification", "Notification body")
	sandbox := fs.Bool("sandbox", false, "Use APNs sandbox (development builds)")
	fs.Parse(args)

	if *email == "" && *deviceToken == "" {
		fmt.Fprintln(os.Stderr, "usage: party send-test-notification [-email EMAIL | -token TOKEN] [-message TEXT]")
		os.Exit(1)
	}

	keyPath := os.Getenv("APNS_KEY_PATH")
	keyID := os.Getenv("APNS_KEY_ID")
	teamID := os.Getenv("APNS_TEAM_ID")
	bundleID := os.Getenv("APNS_BUNDLE_ID")

	if keyPath == "" || keyID == "" || teamID == "" || bundleID == "" {
		fmt.Fprintln(os.Stderr, "missing APNS_KEY_PATH, APNS_KEY_ID, APNS_TEAM_ID or APNS_BUNDLE_ID")
		os.Exit(1)
	}

	authKey, err := token.AuthKeyFromFile(keyPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "apns key: %v\n", err)
		os.Exit(1)
	}
	t := &token.Token{AuthKey: authKey, KeyID: keyID, TeamID: teamID}
	var client *apns.Client
	if *sandbox {
		client = apns.NewTokenClient(t).Development()
	} else {
		client = apns.NewTokenClient(t).Production()
	}

	var targets []string

	if *deviceToken != "" {
		targets = []string{*deviceToken}
	} else {
		var cfg common.Config
		cfg.DB.DSN = os.Getenv("PARTY_DB_DSN")
		cfg.DB.MaxOpenConns = 5
		cfg.DB.MaxIdleConns = 5
		cfg.DB.MaxIdleTime = "15m"

		db, err := openDB(cfg)
		if err != nil {
			fmt.Fprintf(os.Stderr, "db: %v\n", err)
			os.Exit(1)
		}
		defer db.Close()

		models := data.NewModels(db)
		user, err := models.Users.GetByEmail(*email)
		if err != nil {
			fmt.Fprintf(os.Stderr, "user: %v\n", err)
			os.Exit(1)
		}
		deviceTokens, err := models.DeviceTokens.GetForUser(user.ID)
		if err != nil {
			fmt.Fprintf(os.Stderr, "device tokens: %v\n", err)
			os.Exit(1)
		}
		if len(deviceTokens) == 0 {
			fmt.Fprintln(os.Stderr, "no device tokens registered for this user")
			os.Exit(1)
		}
		for _, dt := range deviceTokens {
			targets = append(targets, dt.Token)
		}
	}

	payload := fmt.Sprintf(`{"aps":{"alert":%q,"sound":"default"}}`, *message)

	for _, t := range targets {
		notification := &apns.Notification{
			DeviceToken: t,
			Topic:       bundleID,
			Payload:     []byte(payload),
		}
		resp, err := client.Push(notification)
		if err != nil {
			fmt.Fprintf(os.Stderr, "push failed for %s: %v\n", t, err)
			continue
		}
		fmt.Printf("token=%s status=%d apns_id=%s\n", t, resp.StatusCode, resp.ApnsID)
	}
}
