/**
 * API client for vault-client.
 *
 * The host (MeyiConnect) injects its configured axios instance via
 * VaultProvider so we share the same base URL, auth interceptors,
 * and token refresh logic — no duplicate auth code.
 */

import type { AxiosInstance } from 'axios'

let _api: AxiosInstance | null = null

export function setApiInstance(instance: AxiosInstance) {
  _api = instance
}

function getApi(): AxiosInstance {
  if (!_api) throw new Error('[vault-client] No API instance. Wrap your app in <VaultProvider api={...} />')
  return _api
}

// ── Types ─────────────────────────────────────────────────────────────────────

export interface Vault {
  id: string
  name: string
  owner_id: string
  created_at: string
  is_owner: boolean
}

export interface VaultEntry {
  id: string
  vault_id: string
  domain: string
  alias: string
  username: string
  has_password?: boolean
  has_notes?: boolean
  notes: string
  created_at: string
  updated_at: string
}

export interface Grant {
  id: string
  scope: 'vault' | 'entry'
  scope_id: string
  grantee_id: string
  granted_by_id: string
  expires_at: string | null
  revoked_at: string | null
  created_at: string
}

export interface AuditLog {
  id: string
  actor_id: string
  actor_name: string
  actor_email: string
  action: string
  module: string
  item_id: string
  item_label: string
  meta: any
  created_at: string
}

export interface AuditResponse {
  logs: AuditLog[]
  total: number
  page: number
  limit: number
  total_pages: number
}

export type ExpiresIn = '1h' | '8h' | '24h' | '7d' | '30d' | null

// ── API functions ─────────────────────────────────────────────────────────────

export const vaultApi = {
  // Vaults
  listVaults: () =>
    getApi().get<{ vaults: Vault[] }>('/vault/vaults').then((r) => r.data.vaults),

  createVault: (name: string) =>
    getApi().post<{ vault: Vault }>('/vault/vaults', { name }).then((r) => r.data.vault),

  updateVault: (id: string, name: string) =>
    getApi().put<{ vault: Vault }>(`/vault/vaults/${id}`, { name }).then((r) => r.data.vault),

  deleteVault: (id: string) =>
    getApi().delete(`/vault/vaults/${id}`),

  // Entries
  listEntries: (vaultId: string) =>
    getApi()
      .get<{ entries: VaultEntry[] }>(`/vault/vaults/${vaultId}/entries`)
      .then((r) => r.data.entries),

  createEntry: (vaultId: string, data: { alias?: string; username?: string; password?: string; domain?: string; notes?: string }) =>
    getApi()
      .post<{ entry: VaultEntry }>(`/vault/vaults/${vaultId}/entries`, data)
      .then((r) => r.data.entry),

  getEntryCredentials: (vaultId: string, entryId: string, publicKey?: string) =>
    getApi()
      .post<{ encryptedPayload?: string; password?: string | null; notes?: string }>(`/vault/vaults/${vaultId}/entries/${entryId}/credentials`, { publicKey })
      .then((r) => r.data),

  updateEntry: (vaultId: string, entryId: string, data: Partial<VaultEntry>) =>
    getApi()
      .put<{ entry: VaultEntry }>(`/vault/vaults/${vaultId}/entries/${entryId}`, data)
      .then((r) => r.data.entry),

  deleteEntry: (vaultId: string, entryId: string) =>
    getApi().delete(`/vault/vaults/${vaultId}/entries/${entryId}`),

  // Grants
  createGrant: (data: { scope: 'vault' | 'entry'; scope_id: string; grantee_id: string; expires_in: ExpiresIn }) =>
    getApi().post<{ grant: Grant }>('/vault/grants', data).then((r) => r.data.grant),

  listGrants: () =>
    getApi().get<{ grants: Grant[] }>('/vault/grants').then((r) => r.data.grants),

  revokeGrant: (id: string) =>
    getApi().delete(`/vault/grants/${id}`),

  // Stats & User
  stats: () =>
    getApi()
      .get<{ vault_count: number; active_grants: number; entry_count: number }>('/vault/stats')
      .then((r) => r.data),

  getMe: () =>
    getApi()
      .get<{ user: { id: string; full_name: string; email: string; role: string } }>('/vault/stats/me')
      .then((r) => r.data.user),

  // Audit Logs
  listAuditLogs: (params: { page?: number; limit?: number; search?: string; module?: string }) =>
    getApi()
      .get<AuditResponse>('/vault/audit', { params })
      .then((r) => r.data),
}
 