/**
 * useLocatorCatalog — one client-side entry point for "locators per organization":
 *
 *   const { fetchLocators, resolveLocator, ensureLocator, isVirtualLocator } = useLocatorCatalog()
 *   list = await fetchLocators({ organizationId, warehouseId })   // org locators + master preview (isVirtual)
 *   real = await resolveLocator(picked, { organizationId, warehouseId })   // creates a virtual one on first use
 *
 * Virtual entries come from the master org's full locator set (id `new:<code>`); they
 * are created in the org's own warehouse the moment they are selected or scanned
 * (`/api/mobile/locator-ensure`). Scans already go through `/api/mobile/locator-lookup`
 * / `locator-by-xyz`, which create on the server the same way. resolveLocator() patches
 * the picked object in place (real id, isVirtual=false) so list state stays consistent,
 * and shows a short toast when a locator was created.
 */
import { toast } from 'bulma-toast'

export interface CatalogLocatorEntry {
  id: number | string
  code: string
  isDefault?: boolean
  isVirtual?: boolean
  warehouseId?: number | null
  organizationId?: number | null
  orgId?: number | null
  qtyOnHand?: number
  created?: boolean
  [key: string]: any
}

export const isVirtualLocatorId = (id: any): boolean => typeof id === 'string' && id.startsWith('new:')

/** Toast for lookup responses (`/api/mobile/locator-lookup`, `locator-by-xyz`) that created the bin server-side. */
export const notifyLocatorCreated = (res: any) => {
  if (!res?.created) return
  try {
    toast({ message: `Lagerplatz ${res.code || res.Value || ''} angelegt`, type: 'is-success', duration: 2500, position: 'top-center' })
  } catch (e) { /* ignore */ }
}

export const useLocatorCatalog = () => {
  const headers = () => useRequestHeaders(['cookie'])

  const isVirtualLocator = (l: any): boolean => !!(l && (l.isVirtual || isVirtualLocatorId(l.id)))

  /** Org locators + master-org preview entries, sorted by code. */
  const fetchLocators = async (ctx: { organizationId?: number | string | null; warehouseId?: number | string | null }): Promise<CatalogLocatorEntry[]> => {
    const organizationId = Number(ctx?.organizationId) || null
    const warehouseId = Number(ctx?.warehouseId) || null
    if (!organizationId && !warehouseId) return []
    const res: any = await $fetch('/api/mobile/locators', { method: 'POST', headers: headers(), body: { organizationId, warehouseId } })
    return (res?.locators || []).map((l: any) => ({ ...l, orgId: l.organizationId }))
  }

  /** Find-or-create by code / coordinates / role for an org (server creates from the master template). */
  const ensureLocator = async (req: { organizationId: number | string | null | undefined; warehouseId?: number | string | null; code?: string; x?: string; y?: string; z?: string; role?: 'default' | 'return' }): Promise<any> => {
    const organizationId = Number(req?.organizationId) || 0
    if (!organizationId) throw new Error('organizationId is required')
    return await $fetch('/api/mobile/locator-ensure', {
      method: 'POST',
      headers: headers(),
      body: { organizationId, warehouseId: Number(req.warehouseId) || null, code: req.code, x: req.x, y: req.y, z: req.z, role: req.role }
    })
  }


  /**
   * Real locator for a picked list entry. Existing ones are returned untouched; a virtual
   * one is created for the org and the entry is patched in place (id, isVirtual, created).
   * Throws when the creation fails (callers show their usual "not found" feedback).
   */
  const resolveLocator = async (locator: CatalogLocatorEntry | null | undefined, ctx: { organizationId?: number | string | null; warehouseId?: number | string | null } = {}): Promise<CatalogLocatorEntry | null> => {
    if (!locator) return null
    if (!isVirtualLocator(locator)) return locator
    const res = await ensureLocator({
      organizationId: ctx.organizationId || locator.organizationId || locator.orgId,
      warehouseId: ctx.warehouseId || locator.warehouseId,
      code: locator.code
    })
    if (!res?.id) throw new Error('Locator could not be created')
    Object.assign(locator, {
      id: res.id,
      code: res.code || locator.code,
      isVirtual: false,
      created: !!res.created,
      warehouseId: res.warehouseId ?? locator.warehouseId ?? null,
      organizationId: res.organizationId ?? locator.organizationId ?? null,
      orgId: res.organizationId ?? locator.orgId ?? null
    })
    notifyLocatorCreated(res)
    return locator
  }

  return { fetchLocators, ensureLocator, resolveLocator, isVirtualLocator, isVirtualLocatorId }
}
