/**
 * @file Capacitor Main Entry Point
 * @author Matthew Raymer
 *
 * This file initializes the deep linking system for the TimeSafari app.
 * It sets up the connection between Capacitor's URL handling and our deep link processor.
 *
 * Deep Linking Flow:
 * 1. Capacitor receives URL open event
 * 2. Event is passed to DeepLinkHandler
 * 3. URL is validated and processed
 * 4. Router navigates to appropriate view
 *
 * Integration Points:
 * - Capacitor App plugin for URL handling
 * - Vue Router for navigation
 * - Error handling system
 * - Logging system
 *
 * Type Safety:
 * - Uses DeepLinkHandler for type-safe parameter processing
 * - Ensures type safety between Capacitor events and app routing
 * - Maintains type checking through the entire deep link flow
 *
 * @example
 * // URL open event from OS
 * timesafari://claim/123?view=details
 * // Processed and routed to appropriate view with type-safe parameters
 */

import { initializeApp } from "./main.common";
import { App as CapacitorApp } from "@capacitor/app";
import router from "./router";
import { handleApiError } from "./services/api";
import { AxiosError } from "axios";
import { DeepLinkHandler } from "./services/deepLinks";
import { logger, safeStringify } from "./utils/logger";
import "./utils/safeAreaInset";

logger.log("[Capacitor] 🚀 Starting initialization");
logger.log("[Capacitor] Platform:", process.env.VITE_PLATFORM);

const app = initializeApp();

// Initialize API error handling for unhandled promise rejections
window.addEventListener("unhandledrejection", (event) => {
  if (event.reason?.response) {
    handleApiError(event.reason, event.reason.config?.url || "unknown");
  }
});

const deepLinkHandler = new DeepLinkHandler(router);

/**
 * Handles deep link routing for the application
 * Processes URLs in the format timesafari://<route>/<param>
 * Maps incoming deep links to corresponding router paths with parameters
 *
 * @param {Object} data - Deep link data object
 * @param {string} data.url - The full deep link URL to process
 * @returns {Promise<void>}
 *
 * @example
 * // Handles URLs like:
 * // timesafari://claim/01JMAAFZRNSRTQ0EBSD70A8E1H
 * // timesafari://project/abc123
 *
 * @throws {Error} If URL format is invalid
 */
const handleDeepLink = async (data: { url: string }) => {
  const { url } = data;
  logger.info(`[Main] 🌐 Deeplink received from Capacitor: ${url}`);

  try {
    // Wait for router to be ready
    logger.info(`[Main] ⏳ Waiting for router to be ready...`);
    await router.isReady();
    logger.info(`[Main] ✅ Router is ready, processing deeplink`);

    // Process the deeplink
    logger.info(`[Main] 🚀 Starting deeplink processing`);
    await deepLinkHandler.handleDeepLink(url);
    logger.info(`[Main] ✅ Deeplink processed successfully`);
  } catch (error) {
    logger.error(`[Main] ❌ Deeplink processing failed:`, {
      url,
      error: error instanceof Error ? error.message : String(error),
      stack: error instanceof Error ? error.stack : undefined,
      timestamp: new Date().toISOString(),
    });

    // Log additional context for debugging
    logger.error(`[Main] 🔍 Debug context:`, {
      routerReady: router.isReady(),
      currentRoute: router.currentRoute.value,
      appMounted: app._instance?.isMounted,
      timestamp: new Date().toISOString(),
    });

    // Fallback to original error handling
    let message: string =
      error instanceof Error ? error.message : safeStringify(error);
    if (url) {
      message += `\nURL: ${url}`;
    }
    handleApiError({ message } as AxiosError, "deep-link");
  }
};

// Function to register the deeplink listener
const registerDeepLinkListener = async () => {
  try {
    logger.info(
      `[Main] 🔗 Attempting to register deeplink handler with Capacitor`,
    );

    // Check if Capacitor App plugin is available
    logger.info(`[Main] 🔍 Checking Capacitor App plugin availability...`);
    if (!CapacitorApp) {
      throw new Error("Capacitor App plugin not available");
    }
    logger.info(`[Main] ✅ Capacitor App plugin is available`);

    // Check available methods on CapacitorApp
    logger.info(
      `[Main] 🔍 Capacitor App plugin methods:`,
      Object.getOwnPropertyNames(CapacitorApp),
    );
    logger.info(
      `[Main] 🔍 Capacitor App plugin addListener method:`,
      typeof CapacitorApp.addListener,
    );

    // Wait for router to be ready first
    await router.isReady();
    logger.info(
      `[Main] ✅ Router is ready, proceeding with listener registration`,
    );

    // Try to register the listener
    logger.info(`[Main] 🧪 Attempting to register appUrlOpen listener...`);
    const listenerHandle = await CapacitorApp.addListener(
      "appUrlOpen",
      handleDeepLink,
    );
    logger.info(
      `[Main] ✅ appUrlOpen listener registered successfully with handle:`,
      listenerHandle,
    );

    // Test the listener registration by checking if it's actually registered
    logger.info(`[Main] 🧪 Verifying listener registration...`);

    return listenerHandle;
  } catch (error) {
    logger.error(`[Main] ❌ Failed to register deeplink listener:`, {
      error: error instanceof Error ? error.message : String(error),
      stack: error instanceof Error ? error.stack : undefined,
      timestamp: new Date().toISOString(),
    });
    throw error;
  }
};

logger.log("[Capacitor] 🚀 Mounting app");
app.mount("#app");
logger.info(`[Main] ✅ App mounted successfully`);

// Register deeplink listener after app is mounted
setTimeout(async () => {
  try {
    logger.info(
      `[Main] ⏳ Delaying listener registration to ensure Capacitor is ready...`,
    );
    await registerDeepLinkListener();
    logger.info(`[Main] 🎉 Deep link system fully initialized!`);
  } catch (error) {
    logger.error(`[Main] ❌ Deep link system initialization failed:`, error);
  }
}, 2000); // 2 second delay to ensure Capacitor is fully ready

// Log app initialization status
setTimeout(() => {
  logger.info(`[Main] 📊 App initialization status:`, {
    routerReady: router.isReady(),
    currentRoute: router.currentRoute.value,
    appMounted: app._instance?.isMounted,
    timestamp: new Date().toISOString(),
  });
}, 1000);
