/**
 * Composable for interacting with Metabase API
 *
 * Provides methods to query databases, tables, and execute queries
 * through the Nuxt server API endpoints
 */

export interface MetabaseDatabase {
  id: number
  name: string
  engine: string
  [key: string]: any
}

export interface MetabaseTable {
  id: number
  name: string
  display_name: string
  schema: string
  fields: MetabaseField[]
  [key: string]: any
}

export interface MetabaseField {
  id: number
  name: string
  display_name: string
  base_type: string
  semantic_type: string | null
  [key: string]: any
}

export interface MetabaseQueryResult {
  data: {
    rows: any[][]
    cols: Array<{
      name: string
      display_name: string
      base_type: string
      [key: string]: any
    }>
  }
  row_count: number
  status: string
  [key: string]: any
}

export function useMetabase() {
  const loading = ref(false)
  const error = ref<Error | null>(null)

  /**
   * Get all available databases
   */
  async function getDatabases(): Promise<MetabaseDatabase[]> {
    loading.value = true
    error.value = null

    try {
      const databases = await $fetch<MetabaseDatabase[]>('/api/metabase/databases')
      return databases
    } catch (err: any) {
      error.value = err
      console.error('[useMetabase] Failed to get databases:', err)
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * Get metadata for a specific database (includes all tables and fields)
   */
  async function getDatabaseMetadata(databaseId: number): Promise<any> {
    loading.value = true
    error.value = null

    try {
      const metadata = await $fetch(`/api/metabase/tables/${databaseId}`)
      return metadata
    } catch (err: any) {
      error.value = err
      console.error(`[useMetabase] Failed to get metadata for database ${databaseId}:`, err)
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * Execute a query against a specific table
   *
   * @param databaseId - The Metabase database ID
   * @param tableId - The Metabase table ID
   * @param query - Optional query parameters (limit, filters, etc.)
   */
  async function queryTable(
    databaseId: number,
    tableId: number,
    query: {
      limit?: number
      filter?: any[]
      'order-by'?: any[]
      [key: string]: any
    } = {}
  ): Promise<MetabaseQueryResult> {
    loading.value = true
    error.value = null

    try {
      const result = await $fetch<MetabaseQueryResult>('/api/metabase/query', {
        method: 'POST',
        body: {
          databaseId,
          tableId,
          query
        }
      })
      return result
    } catch (err: any) {
      error.value = err
      console.error('[useMetabase] Failed to execute query:', err)
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * Helper to convert Metabase query result to array of objects
   * Makes it easier to work with the data in components
   */
  function resultToObjects(result: MetabaseQueryResult): Record<string, any>[] {
    const cols = result.data.cols
    const rows = result.data.rows

    return rows.map(row => {
      const obj: Record<string, any> = {}
      cols.forEach((col, index) => {
        obj[col.name] = row[index]
      })
      return obj
    })
  }

  return {
    loading,
    error,
    getDatabases,
    getDatabaseMetadata,
    queryTable,
    resultToObjects
  }
}
