package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/sirupsen/logrus"

	"github.com/titansys/appy-builder/internal/api"
	"github.com/titansys/appy-builder/internal/client"
	"github.com/titansys/appy-builder/internal/config"
	"github.com/titansys/appy-builder/internal/logging"
	"github.com/titansys/appy-builder/internal/platform"
	"github.com/titansys/appy-builder/internal/queue"

	// PLATFORM_IMPORTS_START
	_ "github.com/titansys/appy-builder/internal/platforms/android-webview"
	// PLATFORM_IMPORTS_END
)

const version = "1.1.2"

func main() {
	// Setup logger
	logger := logrus.New()
	logger.SetFormatter(&logging.PrettyFormatter{
		TimestampFormat: "15:04:05.000",
	})

	// Load configuration with CLI flags
	cfg, err := config.LoadWithCLI(version)
	if err != nil {
		fmt.Printf("\n❌ ERROR: %s\n\n", err)
		fmt.Println("Run with --help to see usage information")
		os.Exit(1)
	}

	if cfg.Debug {
		logger.SetLevel(logrus.DebugLevel)
		logger.Info("Debug mode enabled")
	}

	logger.WithFields(logrus.Fields{
		"version": version,
		"port":    cfg.Port,
	}).Info("Configuration loaded successfully")

	// Create storage directories (hardcoded to ./storage)
	if err := createDirectories(logger); err != nil {
		logger.WithError(err).Fatal("Failed to create storage directories")
	}

	// Create TitanClient for purchase code validation
	var titanClient *client.TitanClient
	if cfg.Hosted {
		titanClient = client.NewTitanClient(logger)
	}

	// Initialize components
	appyClient := client.NewAppyClient(cfg, logger)
	builder := platform.NewBuilder(cfg, logger)
	builder.SetAppyClient(appyClient)
	processor := queue.NewProcessor(cfg, appyClient, builder, logger)
	apiServer := api.NewServer(cfg, processor, titanClient, logger, version)

	// Start the build queue processor
	processor.Start()

	// Start HTTP server in a goroutine
	go func() {
		if err := apiServer.Start(); err != nil {
			logger.WithError(err).Fatal("Server failed to start")
		}
	}()

	// Wait for HTTP server to be ready
	time.Sleep(100 * time.Millisecond)

	// Auto-fetch pending builds on startup
	if !cfg.Hosted {
		logger.Info("Fetching pending builds from Appy...")
		if err := processor.FetchAndQueueBuilds(); err != nil {
			logger.WithError(err).Warn("Failed to fetch pending builds on startup, waiting for manual trigger")
		} else {
			pendingCount := processor.PendingCount()
			if pendingCount > 0 {
				logger.WithField("count", pendingCount).Info("Queued pending builds for processing")
			} else {
				logger.Info("No pending builds found")
			}
		}
	}

	// Print startup banner
	fmt.Println()
	fmt.Println("🏗️  APPY BUILD SERVER")
	fmt.Printf("📦 Version:  %s\n", version)
	fmt.Printf("🔌 Port:     %d\n", cfg.Port)
	if !cfg.Hosted {
		fmt.Printf("🔗 Site URL: %s\n", cfg.SiteURL)
	}
	fmt.Printf("👷 Workers:  %d\n", cfg.BuildWorkers)
	fmt.Println()

	// Wait for interrupt signal
	logger.Info("Build server is running. Press Ctrl+C to stop.")
	waitForShutdown()

	logger.Info("Shutting down gracefully...")
}

// createDirectories ensures all required directories exist
func createDirectories(logger *logrus.Logger) error {
	// Storage is hardcoded to ./storage
	dirs := []string{
		"./storage/workspaces",
		"./storage/builds",
		"./storage/logs",
	}

	for _, dir := range dirs {
		if err := os.MkdirAll(dir, 0755); err != nil {
			return err
		}
		logger.WithFields(logrus.Fields{
			"path": dir,
		}).Debug("Created storage directory")
	}

	return nil
}

// waitForShutdown waits for an interrupt signal
func waitForShutdown() {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	<-sigChan
}
