package auctiora;

import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Core;

/**
 * Main entry point for Troostwijk Auction Monitor.
 *
 * ARCHITECTURE:
 * This project focuses on:
 * 1. Image processing and object detection
 * 2. Bid monitoring and notifications
 * 3. Data enrichment
 *
 * Auction/Lot scraping is handled by the external ARCHITECTURE-TROOSTWIJK-SCRAPER process.
 * That process populates the auctions and lots tables in the shared database.
 * This process reads from those tables and enriches them with:
 * - Downloaded images
 * - Object detection labels
 * - Bid monitoring
 * - Notifications
 */
@Slf4j
public class Main {

    @SuppressWarnings("restricted")
    private static Object loadOpenCV() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        return null;
    }

    public static void main(String[] args) throws Exception {
        log.info("=== Troostwijk Auction Monitor ===\n");

        // Parse command line arguments
       var mode = args.length > 0 ? args[0] : "workflow";

        // Configuration - Windows paths
       var databaseFile       = System.getenv().getOrDefault("DATABASE_FILE", "C:\\mnt\\okcomputer\\output\\cache.db");
       var notificationConfig = System.getenv().getOrDefault("NOTIFICATION_CONFIG", "desktop");

        // YOLO model paths (optional - monitor works without object detection)
       var yoloCfg     = "models/yolov4.cfg";
       var yoloWeights = "models/yolov4.weights";
       var     yoloClasses = "models/coco.names";

        // Load native OpenCV library (only if models exist)
        try {
            loadOpenCV();
            log.info("✓ OpenCV loaded");
        } catch (UnsatisfiedLinkError e) {
            log.info("⚠️  OpenCV not available - image detection disabled");
        }

        switch (mode.toLowerCase()) {
            case "workflow":
                runWorkflowMode(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
                break;

            case "once":
                runOnceMode(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
                break;

            case "legacy":
                runLegacyMode(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
                break;

            case "status":
                showStatus(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
                break;

            default:
                showUsage();
                break;
        }
    }

    /**
     * WORKFLOW MODE: Run orchestrated scheduled workflows (default)
     * This is the recommended mode for production use.
     */
    private static void runWorkflowMode(String dbPath, String notifConfig,
                                       String yoloCfg, String yoloWeights, String yoloClasses)
            throws Exception {

        log.info("🚀 Starting in WORKFLOW MODE (Orchestrated Scheduling)\n");
       
       var orchestrator = new WorkflowOrchestrator(
            dbPath, notifConfig, yoloCfg, yoloWeights, yoloClasses
        );

        // Show initial status
        orchestrator.printStatus();

        // Start all scheduled workflows
        orchestrator.startScheduledWorkflows();

        log.info("✓ All workflows are running");
        log.info("  - Scraper import: every 30 min");
        log.info("  - Image processing: every 1 hour");
        log.info("  - Bid monitoring: every 15 min");
        log.info("  - Closing alerts: every 5 min");
        log.info("\nPress Ctrl+C to stop.\n");

        // Add shutdown hook
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.info("\n🛑 Shutdown signal received...");
            orchestrator.shutdown();
        }));

        // Keep application alive
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            orchestrator.shutdown();
        }
    }

    /**
     * ONCE MODE: Run complete workflow once and exit
     * Useful for cron jobs or scheduled tasks.
     */
    private static void runOnceMode(String dbPath, String notifConfig,
                                   String yoloCfg, String yoloWeights, String yoloClasses)
            throws Exception {

        log.info("🔄 Starting in ONCE MODE (Single Execution)\n");
       
       var orchestrator = new WorkflowOrchestrator(
            dbPath, notifConfig, yoloCfg, yoloWeights, yoloClasses
        );

        orchestrator.runCompleteWorkflowOnce();

        log.info("✓ Workflow execution completed. Exiting.\n");
    }

    /**
     * LEGACY MODE: Original monitoring approach
     * Kept for backward compatibility.
     */
    private static void runLegacyMode(String dbPath, String notifConfig,
                                     String yoloCfg, String yoloWeights, String yoloClasses)
            throws Exception {

        log.info("⚙️  Starting in LEGACY MODE\n");

        var monitor = new TroostwijkMonitor(dbPath, notifConfig,
                yoloCfg, yoloWeights, yoloClasses);

        log.info("\n📊 Current Database State:");
        monitor.printDatabaseStats();

        log.info("\n[1/2] Processing images...");
        monitor.processPendingImages();

        log.info("\n[2/2] Starting bid monitoring...");
        monitor.scheduleMonitoring();

        log.info("\n✓ Monitor is running. Press Ctrl+C to stop.\n");
        log.info("NOTE: This process expects auction/lot data from the external scraper.");
        log.info("      Make sure ARCHITECTURE-TROOSTWIJK-SCRAPER is running and populating the database.\n");

        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.info("Monitor interrupted, exiting.");
        }
    }

    /**
     * STATUS MODE: Show current status and exit
     */
    private static void showStatus(String dbPath, String notifConfig,
                                  String yoloCfg, String yoloWeights, String yoloClasses)
            throws Exception {

        log.info("📊 Checking Status...\n");
       
       var orchestrator = new WorkflowOrchestrator(
            dbPath, notifConfig, yoloCfg, yoloWeights, yoloClasses
        );

        orchestrator.printStatus();
    }

    /**
     * Show usage information
     */
    private static void showUsage() {
        log.info("Usage: java -jar troostwijk-monitor.jar [mode]\n");
        log.info("Modes:");
        log.info("  workflow  - Run orchestrated scheduled workflows (default)");
        log.info("  once      - Run complete workflow once and exit (for cron)");
        log.info("  legacy    - Run original monitoring approach");
        log.info("  status    - Show current status and exit");
        log.info("\nEnvironment Variables:");
        log.info("  DATABASE_FILE       - Path to SQLite database");
        log.info("                        (default: C:\\mnt\\okcomputer\\output\\cache.db)");
        log.info("  NOTIFICATION_CONFIG - 'desktop' or 'smtp:user:pass:email'");
        log.info("                        (default: desktop)");
        log.info("\nExamples:");
        log.info("  java -jar troostwijk-monitor.jar workflow");
        log.info("  java -jar troostwijk-monitor.jar once");
        log.info("  java -jar troostwijk-monitor.jar status");
        IO.println();
    }

    /**
     * Alternative entry point for container environments.
     * Simply keeps the container alive for manual commands.
     */
    public static void main2(String[] args) {
        if (args.length > 0) {
            log.info("Command mode - exiting to allow shell commands");
            return;
        }

        log.info("Troostwijk Monitor container is running and healthy.");
        log.info("Use 'docker exec' or 'dokku run' to execute commands.");

        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.info("Container interrupted, exiting.");
        }
    }
}
