import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { Device } from '@/types'

export const useDevicesStore = defineStore('devices', () => {
  const devices = ref<Device[]>([])
  const loading = ref(false)
  const error = ref<string | null>(null)

  /**
   * Fetch the device list. Pass `silent: true` from background refreshes
   * (pull-to-refresh, visibility-change polling) so the loading spinner
   * doesn't blink and replace the existing cards mid-fetch.
   */
  async function fetchDevices(opts: { silent?: boolean } = {}) {
    if (!opts.silent) loading.value = true
    error.value = null
    try {
      const res = await fetch('/api/devices')
      if (!res.ok) throw new Error('Failed to load devices')
      devices.value = await res.json()
    } catch (e) {
      error.value = e instanceof Error ? e.message : 'Unknown error'
    } finally {
      loading.value = false
    }
  }

  async function updateDevice(id: number, patch: Partial<Pick<Device, 'name' | 'orientation' | 'rotationIntervalMinutes' | 'wakeTimes' | 'timezone' | 'uniquenessWindow' | 'rotationMode' | 'prioritizeNeverShown'>>) {
    const res = await fetch(`/api/devices/${id}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(patch),
    })
    if (!res.ok) throw new Error('Failed to update device')
    const updated: Device = await res.json()
    const idx = devices.value.findIndex(d => d.id === id)
    if (idx !== -1) devices.value[idx] = updated
    return updated
  }

  async function lockImage(deviceId: number, imageId: number): Promise<Device> {
    const res = await fetch(`/api/devices/${deviceId}/lock`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ imageId }),
    })
    if (!res.ok) throw new Error('Failed to lock image')
    const updated: Device = await res.json()
    const idx = devices.value.findIndex(d => d.id === deviceId)
    if (idx !== -1) devices.value[idx] = updated
    return updated
  }

  /**
   * Owner-initiated remove. Hits the API DELETE; on success splices the
   * device out of the local list so the UI updates immediately. The
   * Mercure subscription will also receive a `{deleted: true}` push for
   * any other tabs the user has open.
   */
  async function removeDevice(id: number): Promise<void> {
    const res = await fetch(`/api/devices/${id}`, { method: 'DELETE' })
    if (!res.ok) throw new Error('Failed to remove device')
    devices.value = devices.value.filter(d => d.id !== id)
  }

  async function unlockImage(deviceId: number): Promise<Device> {
    const res = await fetch(`/api/devices/${deviceId}/lock`, { method: 'DELETE' })
    if (!res.ok) throw new Error('Failed to unlock')
    const updated: Device = await res.json()
    const idx = devices.value.findIndex(d => d.id === deviceId)
    if (idx !== -1) devices.value[idx] = updated
    return updated
  }

  return { devices, loading, error, fetchDevices, updateDevice, removeDevice, lockImage, unlockImage }
})
