import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { Call } from "@wailsio/runtime";
import { useConnectionStore } from "@/stores/connection.store";

const APP = "github.com/vstockwell/wraith/internal/app.WraithApp";

export interface Session {
  id: string;
  connectionId: number;
  name: string;
  protocol: "ssh" | "rdp";
  active: boolean;
}

export const useSessionStore = defineStore("session", () => {
  const sessions = ref<Session[]>([]);
  const activeSessionId = ref<string | null>(null);
  const connecting = ref(false);

  const activeSession = computed(() =>
    sessions.value.find((s) => s.id === activeSessionId.value) ?? null,
  );

  const sessionCount = computed(() => sessions.value.length);

  function activateSession(id: string): void {
    activeSessionId.value = id;
  }

  async function closeSession(id: string): Promise<void> {
    const idx = sessions.value.findIndex((s) => s.id === id);
    if (idx === -1) return;

    const session = sessions.value[idx];

    // Disconnect the backend session
    try {
      await Call.ByName(`${APP}.DisconnectSession`, session.id);
    } catch (err) {
      console.error("Failed to disconnect session:", err);
    }

    sessions.value.splice(idx, 1);

    if (activeSessionId.value === id) {
      if (sessions.value.length === 0) {
        activeSessionId.value = null;
      } else {
        const nextIdx = Math.min(idx, sessions.value.length - 1);
        activeSessionId.value = sessions.value[nextIdx].id;
      }
    }
  }

  /**
   * Connect to a server by connection ID.
   * Calls the real Go backend to establish an SSH or RDP session.
   */
  async function connect(connectionId: number): Promise<void> {
    const connectionStore = useConnectionStore();
    const conn = connectionStore.connections.find((c) => c.id === connectionId);
    if (!conn) return;

    // Check if there's already an active session for this connection
    const existing = sessions.value.find((s) => s.connectionId === connectionId);
    if (existing) {
      activeSessionId.value = existing.id;
      return;
    }

    connecting.value = true;
    try {
      if (conn.protocol === "ssh") {
        // Call Go backend — resolves credentials, builds auth, returns sessionID
        const sessionId = await Call.ByName(
          `${APP}.ConnectSSH`,
          connectionId,
          120, // cols (will be resized by xterm.js fit addon)
          40,  // rows
        ) as string;

        sessions.value.push({
          id: sessionId,
          connectionId,
          name: conn.name,
          protocol: "ssh",
          active: true,
        });
        activeSessionId.value = sessionId;
      } else if (conn.protocol === "rdp") {
        // TODO: Wire RDP connect when ready
        console.warn("RDP connections not yet wired");
      }
    } catch (err) {
      console.error("Connection failed:", err);
      // TODO: Show error toast in UI
    } finally {
      connecting.value = false;
    }
  }

  return {
    sessions,
    activeSessionId,
    activeSession,
    sessionCount,
    connecting,
    activateSession,
    closeSession,
    connect,
  };
});
