import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { Call } from "@wailsio/runtime";

/** Fully qualified Go method name prefix for ConnectionService bindings. */
const CONN = "github.com/vstockwell/wraith/internal/connections.ConnectionService";

export interface Connection {
  id: number;
  name: string;
  hostname: string;
  port: number;
  protocol: "ssh" | "rdp";
  groupId: number | null;
  credentialId?: number | null;
  color?: string;
  tags?: string[];
  notes?: string;
  options?: string;
  sortOrder?: number;
  lastConnected?: string | null;
  createdAt?: string;
  updatedAt?: string;
}

export interface Group {
  id: number;
  name: string;
  parentId: number | null;
  sortOrder?: number;
  icon?: string;
  children?: Group[];
}

/**
 * Connection store.
 * Manages connections, groups, and search state.
 * Loads data from the Go backend via Wails bindings.
 */
export const useConnectionStore = defineStore("connection", () => {
  const connections = ref<Connection[]>([]);
  const groups = ref<Group[]>([]);
  const searchQuery = ref("");

  /** Filter connections by search query. */
  const filteredConnections = computed(() => {
    const q = searchQuery.value.toLowerCase().trim();
    if (!q) return connections.value;
    return connections.value.filter(
      (c) =>
        c.name.toLowerCase().includes(q) ||
        c.hostname.toLowerCase().includes(q) ||
        c.tags?.some((t) => t.toLowerCase().includes(q)),
    );
  });

  /** Get connections belonging to a specific group. */
  function connectionsByGroup(groupId: number): Connection[] {
    const q = searchQuery.value.toLowerCase().trim();
    const groupConns = connections.value.filter((c) => c.groupId === groupId);
    if (!q) return groupConns;
    return groupConns.filter(
      (c) =>
        c.name.toLowerCase().includes(q) ||
        c.hostname.toLowerCase().includes(q) ||
        c.tags?.some((t) => t.toLowerCase().includes(q)),
    );
  }

  /** Check if a group has any matching connections (for search filtering). */
  function groupHasResults(groupId: number): boolean {
    return connectionsByGroup(groupId).length > 0;
  }

  /** Load connections from the Go backend. */
  async function loadConnections(): Promise<void> {
    try {
      const conns = await Call.ByName(`${CONN}.ListConnections`) as Connection[];
      connections.value = conns || [];
    } catch (err) {
      console.error("Failed to load connections:", err);
      connections.value = [];
    }
  }

  /** Load groups from the Go backend. */
  async function loadGroups(): Promise<void> {
    try {
      const grps = await Call.ByName(`${CONN}.ListGroups`) as Group[];
      groups.value = grps || [];
    } catch (err) {
      console.error("Failed to load groups:", err);
      groups.value = [];
    }
  }

  /** Load both connections and groups from the Go backend. */
  async function loadAll(): Promise<void> {
    await Promise.all([loadConnections(), loadGroups()]);
  }

  return {
    connections,
    groups,
    searchQuery,
    filteredConnections,
    connectionsByGroup,
    groupHasResults,
    loadConnections,
    loadGroups,
    loadAll,
  };
});
