import { soundPlayer } from "./soundPlayer";
import { NotificationType, NOTIFICATION_SOUNDS } from "./types";
import { invoke } from "@tauri-apps/api/core";
import { sendTerminalNotification } from "./terminalNotifier";

class NotificationManager {
  async notify(type: NotificationType, message?: string): Promise<void> {
    // Always play sound (if enabled)
    await soundPlayer.play(type);

    const sound = NOTIFICATION_SOUNDS[type];
    const title = sound.phrase;
    const body = message || this.getDefaultMessage(type);

    // Try multiple notification methods in order
    const notificationMethods = [
      // Method 1: Try Windows PowerShell (best for system tray notifications)
      async () => {
        console.log("Trying Windows PowerShell notifications...");
        await invoke("send_windows_notification", { title, body });
      },

      // Method 2: Try native Windows toast (for Windows builds)
      async () => {
        console.log("Trying native Windows toast...");
        await invoke("send_windows_toast", { title, body });
      },

      // Method 3: Try WSL-specific notification (Windows toast via PowerShell - for WSL)
      async () => {
        console.log("Trying WSL notification...");
        await invoke("send_wsl_notification", { title, body });
      },

      // Method 4: Try native Tauri notifications
      async () => {
        console.log("Trying Tauri native notifications...");
        const { sendNotification, isPermissionGranted, requestPermission } =
          await import("@tauri-apps/plugin-notification");

        let hasPermission = await isPermissionGranted();
        if (!hasPermission) {
          const permission = await requestPermission();
          hasPermission = permission === "granted";
        }

        if (hasPermission) {
          await sendNotification({ title, body });
        } else {
          throw new Error("Notification permission denied");
        }
      },

      // Method 5: Try notify-send (for native Linux)
      async () => {
        console.log("Trying notify-send...");
        await invoke("send_notify_send", { title, body });
      },

      // Skip VBScript and simple message as they create popup dialogs
      // Only use them in the debugger for testing
    ];

    // Try each method until one succeeds
    for (const method of notificationMethods) {
      try {
        await method();
        console.log("Notification sent successfully");
        return; // Success, stop trying other methods
      } catch (error) {
        console.warn("Notification method failed:", error);
        // Continue to next method
      }
    }

    console.error("All notification methods failed, using terminal notification");
    // Final fallback: Show in terminal
    sendTerminalNotification(type, body);
  }

  private getDefaultMessage(type: NotificationType): string {
    switch (type) {
      case NotificationType.SUCCESS:
        return "Task completed successfully!";
      case NotificationType.ERROR:
        return "Something went wrong...";
      case NotificationType.PERMISSION:
        return "Permission needed to continue";
      case NotificationType.CONNECTION:
        return "Successfully connected to Claude Code";
      case NotificationType.TASK_START:
        return "Starting task...";
      default:
        return "Notification";
    }
  }

  // Helper methods for common notifications
  async notifySuccess(message?: string): Promise<void> {
    await this.notify(NotificationType.SUCCESS, message);
  }

  async notifyError(message?: string): Promise<void> {
    await this.notify(NotificationType.ERROR, message);
  }

  async notifyPermission(message?: string): Promise<void> {
    await this.notify(NotificationType.PERMISSION, message);
  }

  async notifyConnection(message?: string): Promise<void> {
    await this.notify(NotificationType.CONNECTION, message);
  }

  async notifyTaskStart(message?: string): Promise<void> {
    await this.notify(NotificationType.TASK_START, message);
  }
}

// Export singleton instance
export const notificationManager = new NotificationManager();
