import { buildDefaultChartInstance, isChartDefinition } from './chartBlock.js'

export const businessBlockCanvas = 'business-blocks-v1'

export function parseBusinessBlockLayout(value) {
  if (!value) {
    return { canvas: businessBlockCanvas, blocks: [] }
  }
  try {
    const parsed = typeof value === 'string' ? JSON.parse(value) : value
    return {
      ...parsed,
      canvas: businessBlockCanvas,
      blocks: Array.isArray(parsed?.blocks) ? parsed.blocks : []
    }
  } catch (error) {
    return { canvas: businessBlockCanvas, blocks: [] }
  }
}

export function addBlockInstance(layout, definition, idFactory = defaultIdFactory) {
  const next = cloneLayout(layout)
  const id = idFactory(definition.code)
  next.blocks.push(isChartDefinition(definition)
    ? buildDefaultChartInstance(definition, id)
    : {
        id,
        blockCode: definition.code,
        name: definition.name || definition.code,
        config: {}
      })
  return next
}

export function updateBlockConfig(layout, blockId, config) {
  const next = cloneLayout(layout)
  next.blocks = next.blocks.map((block) => (
    block.id === blockId ? { ...block, config: { ...(config || {}) } } : block
  ))
  return next
}

export function reorderBlockInstance(layout, fromIndex, toIndex) {
  const next = cloneLayout(layout)
  if (fromIndex < 0 || toIndex < 0 || fromIndex >= next.blocks.length || toIndex >= next.blocks.length) {
    return next
  }
  const [moved] = next.blocks.splice(fromIndex, 1)
  next.blocks.splice(toIndex, 0, moved)
  return next
}

export function removeBlockInstance(layout, blockId) {
  const next = cloneLayout(layout)
  next.blocks = next.blocks.filter((block) => block.id !== blockId)
  return next
}

export function validateRequiredConfig(definition, config) {
  return (definition?.configs || [])
    .filter((item) => item.required && !config?.[item.key])
    .map((item) => item.label || item.key)
}

function cloneLayout(layout) {
  return JSON.parse(JSON.stringify(parseBusinessBlockLayout(layout)))
}

function defaultIdFactory(code) {
  return `${code}_${Date.now()}`
}
