import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import * as api from '../api/client.js'

/**
 * Session-storage key for last visited folder per connection.
 * Only folder navigation state is stored — never tokens or credentials.
 */
function folderSessionKey(connectionId) {
  return `docuvault:cloud:folder:${connectionId}`
}

export function saveLastFolder(connectionId, folderId) {
  try {
    if (folderId && folderId !== 'root') {
      sessionStorage.setItem(folderSessionKey(connectionId), folderId)
    } else {
      sessionStorage.removeItem(folderSessionKey(connectionId))
    }
  } catch {
    // sessionStorage unavailable — ignore
  }
}

export function loadLastFolder(connectionId) {
  try {
    return sessionStorage.getItem(folderSessionKey(connectionId)) || null
  } catch {
    return null
  }
}

export const useCloudConnectionsStore = defineStore('cloudConnections', () => {
  const connections = ref([])
  const loading = ref(false)
  const error = ref(null)

  // Active browse state (populated by CloudFolderView)
  const selectedConnectionId = ref(null)
  const browseItems = ref([])
  const browseLoading = ref(false)
  const browseError = ref(null)
  /** Capabilities for the currently selected connection */
  const capabilities = ref(null)
  /** 'refreshing' | 'fresh' | 'stale' | null */
  const folderFreshness = ref(null)
  const lastRefreshedAt = ref(null)
  /** 'cached' | 'cloud_only' | null */
  const byteAvailability = ref(null)

  const selectedConnection = computed(() =>
    connections.value.find(c => c.id === selectedConnectionId.value) ?? null
  )

  async function fetchConnections() {
    loading.value = true
    error.value = null
    try {
      const data = await api.listCloudConnections()
      connections.value = data.items ?? []
    } catch (e) {
      error.value = e.message || 'Failed to load cloud connections'
    } finally {
      loading.value = false
    }
  }

  async function disconnect(id) {
    try {
      await api.disconnectCloud(id)
      connections.value = connections.value.filter(c => c.id !== id)
      if (selectedConnectionId.value === id) {
        selectedConnectionId.value = null
      }
    } catch (e) {
      throw e
    }
  }

  async function disconnectAll() {
    const ids = connections.value.map(c => c.id)
    for (const id of ids) await disconnect(id)
    connections.value = []
  }

  /**
   * Rename a connection's display_name via the API.
   * Only updates the single returned connection in state.
   */
  async function rename(id, displayName) {
    const trimmed = displayName?.trim()
    if (!trimmed) throw new Error('Display name cannot be empty')
    const updated = await api.renameCloudConnection(id, trimmed)
    const idx = connections.value.findIndex(c => c.id === id)
    if (idx !== -1) {
      connections.value[idx] = { ...connections.value[idx], ...updated }
    }
    return updated
  }

  /**
   * Default display_name for a connection.
   * If another connection shares the same provider, append a 4-char UUID suffix.
   */
  function defaultDisplayName(connection) {
    const providerLabel = {
      google_drive: 'Google Drive',
      onedrive: 'OneDrive',
      nextcloud: 'Nextcloud',
      webdav: 'WebDAV',
    }[connection.provider] ?? connection.provider
    const siblings = connections.value.filter(
      c => c.provider === connection.provider && c.id !== connection.id
    )
    if (siblings.length > 0) {
      return `${providerLabel} (${connection.id.slice(0, 4)})`
    }
    return providerLabel
  }

  function selectConnection(id) {
    selectedConnectionId.value = id
    browseItems.value = []
    browseError.value = null
    capabilities.value = null
    folderFreshness.value = null
    lastRefreshedAt.value = null
    byteAvailability.value = null
  }

  function setBrowseState({ items, caps, freshness, refreshedAt, byteAvail, err }) {
    if (err !== undefined) browseError.value = err
    if (items !== undefined) browseItems.value = items
    if (caps !== undefined) capabilities.value = caps
    if (freshness !== undefined) folderFreshness.value = freshness
    if (refreshedAt !== undefined) lastRefreshedAt.value = refreshedAt
    if (byteAvail !== undefined) byteAvailability.value = byteAvail
  }

  return {
    connections,
    loading,
    error,
    selectedConnectionId,
    selectedConnection,
    browseItems,
    browseLoading,
    browseError,
    capabilities,
    folderFreshness,
    lastRefreshedAt,
    byteAvailability,
    fetchConnections,
    disconnect,
    disconnectAll,
    rename,
    defaultDisplayName,
    selectConnection,
    setBrowseState,
  }
})
