import { ref, watch } from 'vue'
import { Notify } from 'quasar'
import { listDocs, createDoc, updateDoc } from 'src/api/erp'
import { useScanner } from 'src/composables/useScanner'
import { equipScanTypeMap, defaultNewEquip } from 'src/data/client-constants'

export function useEquipmentActions (customer, equipment) {
  const scannerState = useScanner()
  const addEquipOpen = ref(false)
  const addEquipLoc = ref(null)
  const addingEquip = ref(false)
  const equipLookupResult = ref(null)
  const equipLookingUp = ref(false)
  const newEquip = ref(defaultNewEquip())

  let lookupTimer = null
  watch(() => newEquip.value.serial_number, (sn) => {
    clearTimeout(lookupTimer)
    equipLookupResult.value = null
    if (!sn || sn.length < 3) return
    lookupTimer = setTimeout(() => lookupSerial(sn), 500)
  })

  async function lookupSerial (sn) {
    equipLookingUp.value = true
    try {
      const results = await listDocs('Service Equipment', {
        filters: { serial_number: sn },
        fields: ['name', 'equipment_type', 'brand', 'model', 'serial_number', 'service_location', 'customer'],
        limit: 1,
      })
      if (results.length) {
        equipLookupResult.value = { found: true, equipment: results[0] }
      }
    } catch { /* ignore */ }
    finally { equipLookingUp.value = false }
  }

  function openAddEquipment (loc) {
    addEquipLoc.value = loc
    newEquip.value = defaultNewEquip()
    equipLookupResult.value = null
    scannerState.clearBarcodes()
    addEquipOpen.value = true
  }

  function closeAddEquipment () {
    addEquipOpen.value = false
    addEquipLoc.value = null
    scannerState.clearBarcodes()
  }

  async function onScanPhoto (e) {
    const file = e.target?.files?.[0]
    if (!file) return
    const result = await scannerState.scanEquipmentLabel(file)
    if (result) {
      if (result.serial_number && !newEquip.value.serial_number) newEquip.value.serial_number = result.serial_number
      if (result.brand) newEquip.value.brand = result.brand
      if (result.model) newEquip.value.model = result.model
      if (result.mac_address) newEquip.value.mac_address = result.mac_address
      if (result.ip_address) newEquip.value.ip_address = result.ip_address
      if (result.equipment_type) {
        const mapped = equipScanTypeMap[result.equipment_type.toLowerCase()]
        if (mapped) newEquip.value.equipment_type = mapped
      }
    }
    e.target.value = ''
  }

  function applyScannedCode (code) {
    newEquip.value.serial_number = code
  }

  async function createEquipment () {
    addingEquip.value = true
    try {
      const doc = await createDoc('Service Equipment', {
        ...newEquip.value,
        customer: customer.value.name,
        service_location: addEquipLoc.value.name,
      })
      equipment.value.push({
        name: doc.name,
        equipment_type: newEquip.value.equipment_type,
        brand: newEquip.value.brand,
        model: newEquip.value.model,
        serial_number: newEquip.value.serial_number,
        mac_address: newEquip.value.mac_address,
        ip_address: newEquip.value.ip_address,
        status: newEquip.value.status,
        service_location: addEquipLoc.value.name,
      })
      Notify.create({ type: 'positive', message: `Equipement ${doc.name} cree`, timeout: 2000 })
      closeAddEquipment()
    } catch (e) {
      Notify.create({ type: 'negative', message: 'Erreur: ' + e.message })
    } finally {
      addingEquip.value = false
    }
  }

  async function linkExistingEquipment () {
    if (!equipLookupResult.value?.found) return
    addingEquip.value = true
    try {
      const existing = equipLookupResult.value.equipment
      await updateDoc('Service Equipment', existing.name, {
        customer: customer.value.name,
        service_location: addEquipLoc.value.name,
      })
      const idx = equipment.value.findIndex(e => e.name === existing.name)
      if (idx >= 0) {
        equipment.value[idx].service_location = addEquipLoc.value.name
      } else {
        equipment.value.push({
          ...existing,
          service_location: addEquipLoc.value.name,
          customer: customer.value.name,
        })
      }
      Notify.create({ type: 'positive', message: `Equipement ${existing.name} lie a ${addEquipLoc.value.address_line || addEquipLoc.value.location_name}`, timeout: 2000 })
      closeAddEquipment()
    } catch (e) {
      Notify.create({ type: 'negative', message: 'Erreur: ' + e.message })
    } finally {
      addingEquip.value = false
    }
  }

  return {
    scannerState, addEquipOpen, addEquipLoc, addingEquip,
    equipLookupResult, equipLookingUp, newEquip,
    openAddEquipment, closeAddEquipment, onScanPhoto,
    applyScannedCode, createEquipment, linkExistingEquipment,
  }
}
