import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { vaultApi, type ExpiresIn } from '@/services/api'

// ── Query keys ────────────────────────────────────────────────────────────────
export const vaultKeys = {
  vaults:  () => ['vault', 'vaults'] as const,
  entries: (vaultId: string) => ['vault', 'entries', vaultId] as const,
  grants:  () => ['vault', 'grants'] as const,
  stats:   () => ['vault', 'stats'] as const,
  me:      () => ['vault', 'me'] as const,
  audit:   (params: any) => ['vault', 'audit', params] as const,
}

// ── Auth / Me ─────────────────────────────────────────────────────────────────

export function useMe() {
  return useQuery({
    queryKey: vaultKeys.me(),
    queryFn: vaultApi.getMe,
  })
}

// ── Vaults ────────────────────────────────────────────────────────────────────

export function useVaults() {
  return useQuery({
    queryKey: vaultKeys.vaults(),
    queryFn: vaultApi.listVaults,
  })
}

export function useCreateVault() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (name: string) => vaultApi.createVault(name),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.vaults() })
      toast.success('Vault created')
    },
    onError: () => toast.error('Failed to create vault'),
  })
}

export function useDeleteVault() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: string) => vaultApi.deleteVault(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.vaults() })
      toast.success('Vault deleted')
    },
    onError: () => toast.error('Failed to delete vault'),
  })
}

export function useUpdateVault() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ id, name }: { id: string; name: string }) => vaultApi.updateVault(id, name),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.vaults() })
      toast.success('Vault updated')
    },
    onError: () => toast.error('Failed to update vault'),
  })
}

// ── Entries ───────────────────────────────────────────────────────────────────

export function useEntries(vaultId: string) {
  return useQuery({
    queryKey: vaultKeys.entries(vaultId),
    queryFn: () => vaultApi.listEntries(vaultId),
    enabled: !!vaultId,
  })
}

export function useCreateEntry(vaultId: string) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: { alias?: string; username?: string; password?: string; domain?: string; notes?: string }) =>
      vaultApi.createEntry(vaultId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.entries(vaultId) })
      toast.success('Credential saved')
    },
    onError: (err: any) => {
      const msg = err.response?.data?.error || 'Failed to save credential'
      toast.error(msg)
    },
  })
}

export function useUpdateEntry(vaultId: string) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ entryId, data }: { entryId: string; data: any }) =>
      vaultApi.updateEntry(vaultId, entryId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.entries(vaultId) })
      toast.success('Credential updated')
    },
    onError: (err: any) => {
      const msg = err.response?.data?.error || 'Failed to update credential'
      toast.error(msg)
    },
  })
}

export function useDeleteEntry(vaultId: string) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (entryId: string) => vaultApi.deleteEntry(vaultId, entryId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.entries(vaultId) })
      toast.success('Credential deleted')
    },
    onError: () => toast.error('Failed to delete credential'),
  })
}

// ── Grants ────────────────────────────────────────────────────────────────────

export function useGrants() {
  return useQuery({
    queryKey: vaultKeys.grants(),
    queryFn: vaultApi.listGrants,
  })
}

export function useCreateGrant() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: {
      scope: 'vault' | 'entry'
      scope_id: string
      grantee_id: string
      expires_in: ExpiresIn
    }) => vaultApi.createGrant(data),
    onSuccess: (_, _vars) => {
      qc.invalidateQueries({ queryKey: vaultKeys.grants() })
      toast.success('Access granted')
    },
    onError: () => toast.error('Failed to grant access'),
  })
}

export function useRevokeGrant() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: string) => vaultApi.revokeGrant(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: vaultKeys.grants() })
      toast.success('Access revoked')
    },
    onError: () => toast.error('Failed to revoke access'),
  })
}

// ── Stats ─────────────────────────────────────────────────────────────────────

export function useVaultStats() {
  return useQuery({
    queryKey: vaultKeys.stats(),
    queryFn: vaultApi.stats,
  })
}

// ── Audit ─────────────────────────────────────────────────────────────────────

export function useAuditLogs(params: { page?: number; limit?: number; search?: string; module?: string, action?: string }) {
  return useQuery({
    queryKey: vaultKeys.audit(params),
    queryFn: () => vaultApi.listAuditLogs(params),
  })
}
