package notify

import (
	"context"
	"os"
	"sync"
	"time"

	firebase "firebase.google.com/go/v4"
	"firebase.google.com/go/v4/messaging"
	"doormile/utils"
	"google.golang.org/api/option"
)

var (
	fcmClient *messaging.Client
	fcmOnce   sync.Once
)

// InitFCM initializes the Firebase Admin SDK using the service account JSON file
// at FIREBASE_SERVICE_ACCOUNT_PATH. Safe to call from main() at startup.
// If the env var is unset or the file is invalid, FCM is disabled for the process
// lifetime — all SendToDevice calls become no-ops.
func InitFCM() {
	fcmOnce.Do(func() {
		path := os.Getenv("FIREBASE_SERVICE_ACCOUNT_PATH")
		if path == "" {
			utils.Warn("FCM: FIREBASE_SERVICE_ACCOUNT_PATH not set — push notifications disabled")
			return
		}

		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		app, err := firebase.NewApp(ctx, nil, option.WithCredentialsFile(path))
		if err != nil {
			utils.Error("FCM: failed to initialize Firebase app", "error", err)
			return
		}

		client, err := app.Messaging(ctx)
		if err != nil {
			utils.Error("FCM: failed to get Messaging client", "error", err)
			return
		}

		fcmClient = client
		utils.Info("FCM: initialized successfully")
	})
}

// SendToDevice sends an FCM notification to a single device token.
// Returns nil (no-op) if FCM was not initialized or the token is empty.
// The caller should log errors but must not block the booking flow on failure.
func SendToDevice(token, title, body string, data map[string]string) error {
	if fcmClient == nil || token == "" {
		return nil
	}

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	msg := &messaging.Message{
		Notification: &messaging.Notification{
			Title: title,
			Body:  body,
		},
		Data:  data,
		Token: token,
	}

	_, err := fcmClient.Send(ctx, msg)
	return err
}
