package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"
	"time"

	"git.warky.dev/wdevs/whatshooked/pkg/logging"
	"git.warky.dev/wdevs/whatshooked/pkg/whatshooked"
)

var (
	configPath = flag.String("config", "", "Path to configuration file (optional, defaults to user home directory)")
)

// resolveConfigPath determines the config file path to use
// Priority: 1) provided path (if exists), 2) config.json in current dir, 3) .whatshooked/config.json in user home
func resolveConfigPath(providedPath string) (string, error) {
	// If a path was explicitly provided, check if it exists
	if providedPath != "" {
		if _, err := os.Stat(providedPath); err == nil {
			return providedPath, nil
		}
		// Directory doesn't exist, fall through to default locations
		fmt.Fprintf(os.Stderr, "Provided config path directory does not exist, using default locations: %s\n", providedPath)
	}

	// Check for config.json in current directory
	currentDirConfig := "config.json"
	if _, err := os.Stat(currentDirConfig); err == nil {
		return currentDirConfig, nil
	}

	// Fall back to user home directory
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("failed to get user home directory: %w", err)
	}

	// Create .whatshooked directory if it doesn't exist
	configDir := filepath.Join(homeDir, ".whatshooked")
	if err := os.MkdirAll(configDir, 0755); err != nil {
		return "", fmt.Errorf("failed to create config directory: %w", err)
	}

	return filepath.Join(configDir, "config.json"), nil
}

func main() {
	flag.Parse()

	// Resolve config path
	cfgPath, err := resolveConfigPath(*configPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to resolve config path: %v\n", err)
		os.Exit(1)
	}

	// Create WhatsHooked instance from config file
	wh, err := whatshooked.NewFromFile(cfgPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to initialize WhatsHooked from %s: %v\n", cfgPath, err)
		os.Exit(1)
	}

	logging.Info("Starting WhatsHooked server", "config_path", cfgPath)

	// Create context for initialization
	ctx := context.Background()

	// Start the ResolveSpec server
	// This serves both the WhatsApp API and the Admin UI
	if err := wh.StartServer(ctx); err != nil {
		logging.Error("Failed to start server", "error", err)
		os.Exit(1)
	}

	// Connect to WhatsApp accounts after a brief delay
	go func() {
		time.Sleep(500 * time.Millisecond) // Give server a moment to start
		logging.Info("Server ready, connecting to WhatsApp accounts")
		if err := wh.ConnectAll(context.Background()); err != nil {
			logging.Error("Failed to connect to WhatsApp accounts", "error", err)
		}
	}()

	// Wait for interrupt signal
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	<-sigChan

	logging.Info("Shutting down server")

	// Graceful shutdown
	shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// Stop server
	if err := wh.StopServer(shutdownCtx); err != nil {
		logging.Error("Error stopping server", "error", err)
	}

	// Close WhatsHooked (disconnects WhatsApp, closes event logger, etc.)
	if err := wh.Close(); err != nil {
		logging.Error("Error closing WhatsHooked", "error", err)
	}

	logging.Info("Server stopped")
}
