import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { StickerLayer, CropParams } from '@/types'

export const useUploadStore = defineStore('upload', () => {
  const originalFile     = ref<File | null>(null)
  const originalUrl      = ref<string | null>(null)
  const croppedBlob      = ref<Blob | null>(null)
  const croppedUrl       = ref<string | null>(null)
  const cropParams       = ref<CropParams | null>(null)
  const cropOrientation  = ref<'landscape' | 'portrait' | null>(null)
  const stickers         = ref<StickerLayer[]>([])
  const contextDeviceId  = ref<number | null>(null)
  const selectedDeviceIds = ref<number[]>([])
  const editingImageId   = ref<number | null>(null)

  function init(file: File, deviceId?: number) {
    cleanup()
    originalFile.value      = file
    originalUrl.value       = URL.createObjectURL(file)
    contextDeviceId.value   = deviceId ?? null
    selectedDeviceIds.value = deviceId ? [deviceId] : []
  }

  async function initEdit(image: import('@/types').Image, deviceId?: number) {
    cleanup()
    const res  = await fetch(image.originalUrl)
    const blob = await res.blob()
    originalFile.value      = new File([blob], image.originalFilename, { type: blob.type })
    originalUrl.value       = URL.createObjectURL(blob)
    editingImageId.value    = image.id
    cropParams.value        = image.cropParams ?? null
    cropOrientation.value   = image.cropOrientation ?? null
    stickers.value          = image.stickerState ? [...image.stickerState] : []
    selectedDeviceIds.value = image.approvedDeviceIds
    contextDeviceId.value   = deviceId ?? null
  }

  function setCrop(blob: Blob, params: CropParams, orientation: 'landscape' | 'portrait') {
    if (croppedUrl.value) URL.revokeObjectURL(croppedUrl.value)
    croppedBlob.value     = blob
    croppedUrl.value      = URL.createObjectURL(blob)
    cropParams.value      = params
    cropOrientation.value = orientation
  }

  function addSticker(s: StickerLayer) {
    stickers.value = [...stickers.value, s]
  }

  function updateSticker(id: string, patch: Partial<StickerLayer>) {
    stickers.value = stickers.value.map(s => s.id === id ? { ...s, ...patch } : s)
  }

  function removeSticker(id: string) {
    stickers.value = stickers.value.filter(s => s.id !== id)
  }

  function cleanup() {
    if (originalUrl.value) URL.revokeObjectURL(originalUrl.value)
    if (croppedUrl.value)  URL.revokeObjectURL(croppedUrl.value)
    originalFile.value      = null
    originalUrl.value       = null
    croppedBlob.value       = null
    croppedUrl.value        = null
    cropParams.value        = null
    cropOrientation.value   = null
    stickers.value          = []
    contextDeviceId.value   = null
    selectedDeviceIds.value = []
    editingImageId.value    = null
  }

  return {
    originalFile, originalUrl,
    croppedBlob, croppedUrl, cropParams, cropOrientation,
    stickers, contextDeviceId, selectedDeviceIds, editingImageId,
    init, initEdit, setCrop, addSticker, updateSticker, removeSticker, cleanup,
  }
})
