import { app } from '../../../scripts/app.js'
import { api } from '../../../scripts/api.js'
// import { ComfyWidgets } from '../../../scripts/widgets.js'
import { $el } from '../../../scripts/ui.js'
import { applyTextReplacements } from '../../../scripts/utils.js'

import { loadExternalScript, get_position_style } from './common.js'

function loadImageToCanvas (base64Image) {
  var img = new Image()
  var canvas = document.createElement('canvas')
  var ctx = canvas.getContext('2d')
  return new Promise((res, rej) => {
    img.onload = function () {
      // 等比例缩放图片
      var width = img.width
      var height = img.height
      var max_width = 1024
      if (width > max_width) {
        height *= max_width / width
        width = max_width
      }

      // 设置canvas尺寸
      canvas.width = width
      canvas.height = height

      // 在canvas上绘制图片
      ctx.drawImage(img, 0, 0, width, height)

      // 将canvas转换为base64图片数据
      var canvasData = canvas.toDataURL()
      res(canvasData) //  canvas转换后的base64图片数据
    }

    img.src = base64Image
  })
}

async function uploadImage (blob, fileType = '.svg', filename) {
  // const blob = await (await fetch(src)).blob();
  const body = new FormData()
  body.append(
    'image',
    new File([blob], (filename || new Date().getTime()) + fileType)
  )

  const resp = await api.fetchApi('/upload/image', {
    method: 'POST',
    body
  })

  // console.log(resp)
  let data = await resp.json()
  let { name, subfolder } = data
  let src = api.apiURL(
    `/view?filename=${encodeURIComponent(
      name
    )}&type=input&subfolder=${subfolder}${app.getPreviewFormatParam()}${app.getRandParam()}`
  )

  return src
}

const base64Df =
  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAALZJREFUKFOFkLERwjAQBPdbgBkInECGaMLUQDsE0AkRVRAYWqAByxldPPOWHwnw4OBGye1p50UDSoA+W2ABLPN7i+C5dyC6R/uiAUXRQCs0bXoNIu4QPQzAxDKxHoALOrZcqtiyR/T6CXw7+3IGHhkYcy6BOR2izwT8LptG8rbMiCRAUb+CQ6WzQVb0SNOi5Z2/nX35DRyb/ENazhpWKoGwrpD6nICp5c2qogc4of+c7QcrhgF4Aa/aoAFHiL+RAAAAAElFTkSuQmCC'

function base64ToBlobFromURL (base64URL, contentType) {
  return fetch(base64URL).then(response => response.blob())
}

function getContentTypeFromBase64 (base64Data) {
  const regex = /^data:(.+);base64,/
  const matches = base64Data.match(regex)
  if (matches && matches.length >= 2) {
    return matches[1]
  }
  return null
}

// 示例用法
// const base64Data = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD/...'; // 替换为实际的base64图片数据
// const contentType = getContentTypeFromBase64(base64Data);
// console.log(contentType);

// // 示例用法
// const base64Data = '...'; // 替换为实际的base64图片数据
// const contentType = 'image/jpeg'; // 替换为实际的图片类型

// const blob = base64ToBlob(base64Data, contentType);
// console.log(blob);

// function get_position_style (ctx, widget_width, y, node_height) {
//   const MARGIN = 4 // the margin around the html element

//   /* Create a transform that deals with all the scrolling and zooming */
//   const elRect = ctx.canvas.getBoundingClientRect()
//   const transform = new DOMMatrix()
//     .scaleSelf(
//       elRect.width / ctx.canvas.width,
//       elRect.height / ctx.canvas.height
//     )
//     .multiplySelf(ctx.getTransform())
//     .translateSelf(MARGIN, MARGIN + y)

//   return {
//     transformOrigin: '0 0',
//     transform: transform,
//     left:
//       document.querySelector('.comfy-menu').style.display === 'none'
//         ? `60px`
//         : `0`,
//     top: `0`,
//     cursor: 'pointer',
//     position: 'absolute',
//     maxWidth: `${widget_width - MARGIN * 2}px`,
//     // maxHeight: `${node_height - MARGIN * 2}px`, // we're assuming we have the whole height of the node
//     width: `${widget_width - MARGIN * 2}px`,
//     // height: `${node_height * 0.3 - MARGIN * 2}px`,
//     // background: '#EEEEEE',
//     display: 'flex',
//     flexDirection: 'column',
//     // alignItems: 'center',
//     justifyContent: 'space-around'
//   }
// }

const getLocalData = key => {
  let data = {}
  try {
    data = JSON.parse(localStorage.getItem(key)) || {}
  } catch (error) {
    return {}
  }
  return data
}

const setLocalDataOfWin = (key, value) => {
  localStorage.setItem(key, JSON.stringify(value))
  // window[key] = value
}

function createImage (url) {
  let im = new Image()
  return new Promise((res, rej) => {
    im.onload = () => res(im)
    im.src = url
  })
}

const parseImageToBase64 = url => {
  return new Promise((res, rej) => {
    fetch(url)
      .then(response => response.blob())
      .then(blob => {
        const reader = new FileReader()
        reader.onloadend = () => {
          const base64data = reader.result
          res(base64data)
          // 在这里可以将base64数据用于进一步处理或显示图片
        }
        reader.readAsDataURL(blob)
      })
      .catch(error => {
        console.log('发生错误:', error)
      })
  })
}

const parseSvg = async svgContent => {
  let scale = 2
  // 创建一个临时的DOM元素来解析SVG
  const tempContainer = document.createElement('div')
  tempContainer.innerHTML = svgContent

  // 提取SVG元素
  const svgElement = tempContainer.querySelector('svg')
  if (!svgElement) return
  // 获取SVG中 rect元素
  var rectElements = svgElement?.querySelectorAll('rect') || []
  // console.log(rectElements,svgElement)
  // 定义一个数组来存储处理后的数据
  var data = []

  Array.from(rectElements, (rectElement, i) => {
    // 获取rect元素的属性值
    var x = ~~(rectElement.getAttribute('x') || 0)
    var y = ~~(rectElement.getAttribute('y') || 0)
    var width = ~~rectElement.getAttribute('width')
    var height = ~~rectElement.getAttribute('height')
    // console.log('rectElements',rectElement,x,y,width,height)
    if (x != undefined && y != undefined && width && height) {
      // 创建一个新的canvas元素
      var canvas = document.createElement('canvas')
      canvas.width = width
      canvas.height = height
      var context = canvas.getContext('2d')

      // 填充颜色到canvas
      var fill = rectElement.getAttribute('fill')
      context.fillStyle = fill
      context.fillRect(0, 0, width, height)

      // 将canvas转换为base64格式
      var base64 = canvas.toDataURL()

      // 将数据转化为指定的JSON格式

      var rectData = {
        x: parseInt(x),
        y: parseInt(y),
        width: parseInt(width),
        height: parseInt(height),
        z_index: i + 1,
        scale_option: 'width',
        image: base64,
        mask: base64,
        type: 'base64',
        _t: 'rect'
      }

      // 将处理后的数据添加到数组中
      data.push(rectData)
    }
  })

  var svgWidth = svgElement.getAttribute('width')
  var svgHeight = svgElement.getAttribute('height')

  if (!(svgWidth && svgHeight)) {
    // viewBox
    let viewBox = svgElement.viewBox.baseVal

    svgWidth = viewBox.width
    svgHeight = viewBox.height
  } else {
    try {
      svgWidth = ~~svgWidth.replace('px', '')
      svgHeight = ~~svgHeight.replace('px', '')
    } catch (error) {}
  }

  // 创建一个新的canvas元素
  var canvas = document.createElement('canvas')
  canvas.width = svgWidth
  canvas.height = svgHeight
  var context = canvas.getContext('2d')
  // 绘制SVG到canvas
  var svgString = new XMLSerializer().serializeToString(svgElement)
  var DOMURL = window.URL || window.webkitURL || window

  var svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' })
  var url = DOMURL.createObjectURL(svgBlob)

  let img = await createImage(url)
  context.drawImage(img, 0, 0)

  let base64 = canvas.toDataURL()

  var rectData = {
    x: 0,
    y: 0,
    width: parseInt(svgWidth),
    height: parseInt(svgHeight),
    z_index: 0,
    scale_option: 'width',
    image: base64,
    mask: base64,
    type: 'base64',
    _t: 'canvas'
  }
  data.push(rectData)

  // 打印处理后的数据
  console.log('layers', { data, image: base64, svgElement })
  return { data, image: base64, svgElement }
}

function exportModelViewerImage (
  modelViewer,
  width,
  height,
  format = 'image/png',
  quality = 1.0
) {
  const canvas = document.createElement('canvas')
  canvas.width = width
  canvas.height = height
  const context = canvas.getContext('2d')

  return new Promise((resolve, reject) => {
    context.drawImage(modelViewer, 0, 0, width, height)

    resolve(canvas.toDataURL(format, quality))
  })
}

app.registerExtension({
  name: 'Mixlab.image.SvgImage',
  async getCustomWidgets (app) {
    return {
      SVG (node, inputName, inputData, app) {
        // console.log('##node', node, inputName, inputData)
        const widget = {
          type: inputData[0], // the type, CHEESE
          name: inputName, // the name, slice
          size: [128, 88], // a default size
          draw (ctx, node, width, y) {},
          computeSize (...args) {
            return [128, 88] // a method to compute the current size of the widget
          },
          async serializeValue (nodeId, widgetIndex) {
            let d = getLocalData('_mixlab_svg_image')
            // console.log('serializeValue',d)
            if (d) {
              let url = d[node.id]
              let dt = await fetch(url)
              let svgStr = await dt.text()
              const { data, image } = (await parseSvg(svgStr)) || {}
              // console.log(data, image)
              return JSON.parse(JSON.stringify({ data, image }))
            } else {
              return
            }
          }
        }

        // console.log('##node',node.serialize)
        //  widget.something = something;          // maybe adds stuff to it
        node.addCustomWidget(widget) // adds it to the node

        return widget // and returns it.
      }
    }
  },

  async beforeRegisterNodeDef (nodeType, nodeData, app) {
    if (nodeType.comfyClass == 'SvgImage') {
      const orig_nodeCreated = nodeType.prototype.onNodeCreated
      nodeType.prototype.onNodeCreated = async function () {
        orig_nodeCreated?.apply(this, arguments)

        const uploadWidget = this.widgets.filter(w => w.name == 'upload')[0]
        // console.log('SvgImage nodeData',await uploadWidget.serializeValue())

        const widget = {
          type: 'div',
          name: 'upload-preview',
          draw (ctx, node, widget_width, y, widget_height) {
            Object.assign(
              this.div.style,
              get_position_style(ctx, widget_width, 44, node.size[1], 60)
            )
          }
        }

        widget.div = $el('div', {})

        document.body.appendChild(widget.div)

        const inputDiv = (key, placeholder, svgContainer) => {
          let div = document.createElement('div')
          const ip = document.createElement('input')
          ip.type = 'file'
          ip.className = `${'comfy-multiline-input'} ${placeholder}`
          div.style = `display: flex;
          align-items: center; 
          margin: 6px 8px;
          margin-top: 0;`
          ip.placeholder = placeholder
          // ip.value = value

          ip.style = `outline: none;
          border: none;
          padding: 4px;
          width: 60%;cursor: pointer;
          height: 32px;`
          const label = document.createElement('label')
          label.style = 'font-size: 10px;min-width:32px'
          label.innerText = placeholder
          div.appendChild(label)
          div.appendChild(ip)

          let that = this

          ip.addEventListener('change', event => {
            const file = event.target.files[0]
            const reader = new FileReader()

            // 读取文件内容
            reader.onload = async e => {
              const svgContent = e.target.result

              var blob = new Blob([svgContent], { type: 'image/svg+xml' })
              let url = await uploadImage(blob)
              // console.log(url)
              const { svgElement, data, image } = await parseSvg(svgContent)
              // 将提取的SVG元素显示在页面上
              let dd = getLocalData(key)
              dd[that.id] = url
              setLocalDataOfWin(key, dd)
              // console.log(this.id, ip.value.trim())

              svgElement.style = `width: 90%;padding: 5%;height: auto;`
              // 将提取的SVG元素显示在页面上

              svgContainer.innerHTML = ''
              svgContainer.appendChild(svgElement)
              let h = ~~getComputedStyle(svgElement).height.replace('px', '')
              if (that.size && that.size[1] < h) {
                that.setSize([that.size[0], that.size[1] + h])
                app.canvas.draw(true, true)
              }
              // console.log(that.size,~~getComputedStyle(svgElement).height.replace('px',''))

              uploadWidget.value = await uploadWidget.serializeValue()
            }

            // 以文本形式读取文件
            reader.readAsText(file)
          })
          return div
        }

        let svg = document.createElement('div')
        svg.className = 'preview'
        svg.style = `background:#eee;margin-top: 12px;`

        let upload = inputDiv('_mixlab_svg_image', 'Svg', svg)

        widget.div.appendChild(upload)
        widget.div.appendChild(svg)
        this.addCustomWidget(widget)

        const onRemoved = this.onRemoved
        this.onRemoved = () => {
          upload.remove()
          svg.remove()
          widget.div.remove()
          return onRemoved?.()
        }

        if (this.onResize) {
          this.onResize(this.size)
        }

        this.serialize_widgets = true //需要保存参数
      }
    }
  },
  async loadedGraphNode (node, app) {
    // Fires every time a node is constructed
    // You can modify widgets/add handlers/etc here
    const sleep = (t = 1000) => {
      return new Promise((res, rej) => {
        setTimeout(() => res(1), t)
      })
    }
    if (node.type === 'SvgImage') {
      // await sleep(0)
      let widget = node.widgets.filter(w => w.name === 'upload-preview')[0]

      let dd = getLocalData('_mixlab_svg_image')

      let id = node.id
      console.log('SvgImage load', node.widgets[0], node.widgets)
      if (!dd[id]) return
      let dt = await fetch(dd[id])
      let svgStr = await dt.text()

      const { svgElement, data, image } = await parseSvg(svgStr)
      svgElement.style = `width: 90%;padding: 5%;height:auto`
      // 将提取的SVG元素显示在页面上

      widget.div.querySelector('.preview').innerHTML = ''
      widget.div.querySelector('.preview').appendChild(svgElement)

      const uploadWidget = node.widgets.filter(w => w.name == 'upload')[0]
      uploadWidget.value = await uploadWidget.serializeValue()
    }
  }
})

const createSelect = (imgDiv, select, opts, targetWidget, textWidget) => {
  select.style.display = 'block'
  let html = ''
  let isMatch = false
  for (const opt of opts) {
    html += `<option value='${opt.keyword}' ${opt.selected ? 'selected' : ''}>${
      opt.keyword
    }</option>`
    if (opt.selected) {
      isMatch = true
      imgDiv.src = opt.imgurl
      // targetWidget.value = opt.keyword
    }
  }
  select.innerHTML = html
  if (!isMatch) {
    // targetWidget.value = opts[0].keyword
    imgDiv.src = opts[0].imgurl
  }

  // 添加change事件监听器
  select.addEventListener('change', async function () {
    // 获取选中的选项的值
    var selectedOption = select.options[select.selectedIndex].value
    let t = opts.filter(opt => opt.keyword === selectedOption)[0]

    targetWidget.value = await parseImageToBase64(t.imgurl)
    imgDiv.src = targetWidget.value
    textWidget.value = t.keyword
  })
  // console.log(select)
}

app.registerExtension({
  name: 'Mixlab.prompt.ImagesPrompt_',
  async beforeRegisterNodeDef (nodeType, nodeData, app) {
    if (nodeType.comfyClass == 'ImagesPrompt_') {
      const orig_nodeCreated = nodeType.prototype.onNodeCreated
      nodeType.prototype.onNodeCreated = async function () {
        orig_nodeCreated?.apply(this, arguments)

        const image_prompt = this.widgets.filter(
          w => w.name == 'image_base64'
        )[0]
        const image_text = this.widgets.filter(w => w.name == 'text')[0]

        const node = this

        const widget = {
          type: 'div',
          name: 'upload',
          draw (ctx, node, widget_width, y, widget_height) {
            Object.assign(
              this.div.style,
              get_position_style(ctx, widget_width, y, node.size[1], 36)
            )
          }
        }

        widget.div = $el('div', {})

        // console.log('image_prompt',image_prompt)
        const img = new Image()
        img.src = image_prompt?.value || base64Df
        widget.div.appendChild(img)

        const btn = document.createElement('button')
        btn.innerText = 'Upload Images JSON'

        btn.style = `cursor: pointer;
        font-weight: 300;
        margin: 2px; 
        color: var(--descrip-text);
        background-color: var(--comfy-input-bg);
        border-radius: 8px;
        border-color: var(--border-color);
        border-style: solid;height: 30px;min-width: 122px;
       `

        const select = document.createElement('select')
        select.style = `display:none;cursor: pointer;
        font-weight: 300;
        margin: 2px; 
        color: var(--descrip-text);
        background-color: var(--comfy-input-bg);
        border-radius: 8px;
        border-color: var(--border-color);
        border-style: solid;height: 30px;min-width: 100px;
       `
        widget.select = select

        // const btn=document.createElement('button');
        // btn.innerText='Upload'
        btn.addEventListener('click', () => {
          let inp = document.createElement('input')
          inp.type = 'file'
          inp.accept = '.json'
          inp.click()
          inp.addEventListener('change', event => {
            // 获取选择的文件
            // [{title,imageUrl}]
            const file = event.target.files[0]
            this.title = file.name.split('.')[0]

            // console.log(file.name.split('.')[0])
            // 创建文件读取器
            const reader = new FileReader()

            // 定义读取完成事件的回调函数
            reader.onload = async event => {
              // 读取完成后的文本内容
              const json = JSON.parse(event.target.result)
              console.log(node, json)

              widget.value = JSON.stringify(json)

              let img = widget.div.querySelector('img')

              createSelect(img, select, json, image_prompt, image_text)

              image_prompt.value = await parseImageToBase64(json[0].imgurl)
              image_text.value = json[0].keyword

              if (img) {
                img.src = image_prompt.value
              }

              inp.remove()
            }

            // 以文本方式读取文件
            reader.readAsText(file)
          })
        })

        widget.div.appendChild(btn)
        widget.div.appendChild(select)
        document.body.appendChild(widget.div)
        this.addCustomWidget(widget)

        const onRemoved = this.onRemoved
        this.onRemoved = () => {
          widget.div.remove()
          return onRemoved?.()
        }

        if (this.onResize) {
          this.onResize(this.size)
        }

        this.serialize_widgets = true //需要保存参数
      }
    }
  },
  async loadedGraphNode (node, app) {
    if (node.type === 'ImagesPrompt_') {
      try {
        let prompt = node.widgets.filter(w => w.name === 'image_base64')[0]
        let text = node.widgets.filter(w => w.name === 'text')[0]
        let uploadWidget = node.widgets.filter(w => w.name == 'upload')[0]
        // console.log('##prompt',prompt.value)
        let img = uploadWidget.div.querySelector('img')
        let json = JSON.parse(uploadWidget.value)

        for (let index = 0; index < json.length; index++) {
          const j = json[index]
          let base64 = await parseImageToBase64(j.imgurl)
          if (base64 === prompt.value) {
            json[index].selected = true
          }
        }

        if (json && json[0]) {
          uploadWidget.select.style.display = 'block'
          createSelect(img, uploadWidget.select, json, prompt, text)
        }
      } catch (error) {}
    }
  }
})

const createInputImageForBatch = (base64, widget) => {
  let im = new Image()
  im.src = base64
  im.style = `width: 88px;`

  im.addEventListener('click', e => {
    let newValue = []
    let items = widget.value?.base64 || []
    for (const v of items) {
      if (v != base64) newValue.push(v)
    }
    widget.value.base64 = newValue
    im.remove()
  })

  return im
}

// 添加新图片
const addBase64ToWidgetForLoadImagesToBatch = (
  base64,
  imagesWidget,
  imagesDiv
) => {
  if (!imagesWidget.value.base64) imagesWidget.value.base64 = []
  imagesWidget.value.base64.push(base64)
  let im = createInputImageForBatch(base64, imagesWidget)
  imagesDiv.appendChild(im)
}

app.registerExtension({
  name: 'Mixlab.Comfy.LoadImagesToBatch',
  async getCustomWidgets (app) {
    return {
      IMAGEBASE64 (node, inputName, inputData, app) {
        // console.log('##node', node)
        const widget = {
          value: {
            base64: []
          }, // 不能[x,x,x]
          type: inputData[0], // the type
          name: inputName, // the name, slice
          size: [128, 32], // a default size
          draw (ctx, node, width, y) {},
          computeSize (...args) {
            return [128, 32] // a method to compute the current size of the widget
          }
          // serializeValue (nodeId, widgetIndex) {
          //   return widget.value
          // },
        }
        //  widget.something = something;          // maybe adds stuff to it
        node.addCustomWidget(widget) // adds it to the node
        return widget // and returns it.
      }
    }
  },

  async beforeRegisterNodeDef (nodeType, nodeData, app) {
    if (nodeType.comfyClass == 'LoadImagesToBatch') {
      const orig_nodeCreated = nodeType.prototype.onNodeCreated

      nodeType.prototype.onNodeCreated = function () {
        orig_nodeCreated?.apply(this, arguments)

        let imagesWidget = this.widgets.filter(w => w.name == 'images')[0]

        const widget = {
          type: 'div',
          name: 'image_base64',
          draw (ctx, node, widget_width, y, widget_height) {
            Object.assign(this.div.style, {
              ...get_position_style(ctx, widget_width, y, node.size[1], 72),
              top: `${widget_height}px`
            })
          },
          serialize: false
        }

        widget.div = $el('div', {})

        document.body.appendChild(widget.div)

        let imagePreview = document.createElement('div')
        let imagesDiv = document.createElement('div') //显示图片
        imagesDiv.className = 'images_preview'
        imagesDiv.style = `width: calc(100% - 14px);
        display: flex;
        flex-wrap: wrap;
        padding: 7px;    justify-content: space-between;
        align-items: center;`

        let inputImage = document.createElement('input')
        inputImage.type = 'file'
        inputImage.style.display = 'none'
        inputImage.addEventListener('change', e => {
          e.preventDefault()
          const file = e.target.files[0]
          const reader = new FileReader()
          reader.onload = async event => {
            let base64 = event.target.result
            //压缩图片，控制1024以内
            base64 = await loadImageToCanvas(base64)
            // console.log(base64)
            if (!imagesWidget.value) imagesWidget.value = { base64: [] }
            addBase64ToWidgetForLoadImagesToBatch(
              base64,
              imagesWidget,
              imagesDiv
            )
          }
          reader.readAsDataURL(file)
        })

        // 如果是复制的，有数据 , 这个不生效，取不到数据， 需要在nodeCreated里获取
        // console.log('#LoadImagesToBatch', imagesWidget.value?.base64)

        const btn = document.createElement('button')
        btn.innerText = 'Upload Image'

        btn.style = `cursor: pointer;
        font-weight: 300;
        margin: 2px; 
        color: var(--descrip-text);
        background-color: var(--comfy-input-bg);
        border-radius: 8px;
        border-color: var(--border-color);
        border-style: solid;height: 30px;min-width: 122px;
       `

        btn.addEventListener('click', e => {
          e.preventDefault()
          inputImage.click()
        })

        widget.div.appendChild(imagePreview)
        imagePreview.appendChild(imagesDiv)
        imagePreview.appendChild(btn)
        imagePreview.appendChild(inputImage)

        this.addCustomWidget(widget)

        // document.addEventListener('wheel', handleMouseWheel)

        const onRemoved = this.onRemoved
        this.onRemoved = () => {
          inputImage.remove()
          widget.div.remove()
          try {
            // document.removeEventListener('wheel', handleMouseWheel)
          } catch (error) {
            console.log(error)
          }

          return onRemoved?.()
        }

        this.serialize_widgets = true //需要保存参数
      }
    }

    if (nodeData.name === 'SaveImageAndMetadata_') {
      const onNodeCreated = nodeType.prototype.onNodeCreated
      // /web/extensions/core/saveImageExtraOutput.js
      nodeType.prototype.onNodeCreated = function () {
        const r = onNodeCreated
          ? onNodeCreated.apply(this, arguments)
          : undefined
        const widget = this.widgets.find(w => w.name === 'filename_prefix')
        widget.serializeValue = () => {
          return applyTextReplacements(app, widget.value)
        }

        return r
      }

      const onExecuted = nodeType.prototype.onExecuted
      nodeType.prototype.onExecuted = function (message) {
        onExecuted?.apply(this, arguments)
        console.log('##onExecuted', this, message)
        //TODO 是否 保存base64
        if (message.base64) {
          if (Array.isArray(message.base64)) {
          }
        }
      }
    }
  },

  async loadedGraphNode (node, app) {
    if (node.type === 'LoadImagesToBatch') {
      let imagesWidget = node.widgets.filter(w => w.name === 'images')[0]
      let imagePreview = node.widgets.filter(w => w.name == 'image_base64')[0]
      // console.log('#LoadImagesToBatch', imagesWidget.value?.base64)
      let imagesDiv = imagePreview.div.querySelector('.images_preview')
      imagesDiv.innerHTML = ''
      for (const d of imagesWidget.value?.base64 || []) {
        let im = createInputImageForBatch(d, imagesWidget)
        imagesDiv.appendChild(im)
      }
    }
  },
  nodeCreated (node, app) {
    //数据延迟？？
    setTimeout(() => {
      // console.log('#LoadImagesToBatch', node.type)
      if (node.type === 'LoadImagesToBatch') {
        let imagesWidget = node.widgets.filter(w => w.name === 'images')[0]
        let imagePreview = node.widgets.filter(w => w.name == 'image_base64')[0]

        let imagesDiv = imagePreview?.div?.querySelector('.images_preview')
        imagesDiv.innerHTML = ''
        for (const d of imagesWidget.value?.base64 || []) {
          let im = createInputImageForBatch(d, imagesWidget)
          imagesDiv.appendChild(im)
        }
      }
    }, 1000)
  }
})

// 如何引入css
app.registerExtension({
  name: 'Mixlab.output.ComparingTwoFrames_',
  init () {
    loadExternalScript('/mixlab/app/lib/juxtapose.min.js')

    $el('link', {
      rel: 'stylesheet',
      href: '/mixlab/app/lib/juxtapose.css',
      parent: document.head
    })

    $el('style', {
      textContent: `
      .juxtapose-name{
        display: none!important; 
      }
			`,
      parent: document.body
    })
  },
  async beforeRegisterNodeDef (nodeType, nodeData, app) {
    if (nodeType.comfyClass == 'ComparingTwoFrames_') {
      const onNodeCreated = nodeType.prototype.onNodeCreated
      nodeType.prototype.onNodeCreated = function () {
        const r = onNodeCreated
          ? onNodeCreated.apply(this, arguments)
          : undefined

        this.size = [400, this.size[1]]
        console.log('##onNodeCreated', this)
        const widget = {
          type: 'div',
          name: 'preview',
          draw (ctx, node, widget_width, y, widget_height) {
            let s = get_position_style(ctx, widget_width, 44, node.size[1], 36)
            delete s.height

            Object.assign(this.div.style, s)
          },
          serialize: false
        }

        widget.div = $el('div', {})

        document.body.appendChild(widget.div)
        this.addCustomWidget(widget)
        this.serialize_widgets = true //需要保存参数

        const onRemoved = this.onRemoved
        this.onRemoved = () => {
          widget.div.remove()
          return onRemoved?.()
        }

        return r
      }

      const onExecuted = nodeType.prototype.onExecuted
      nodeType.prototype.onExecuted = function (message) {
        onExecuted?.apply(this, arguments)
        console.log('##onExecuted', this, message)

        this.widgets[0].div.id = 'mix_comparingtowframes_' + this.id

        let after_image = message.after_images[0]
        let before_image = message.before_images[0]

        after_image = `${window.location.protocol}//${
          window.location.hostname
        }:${window.location.port}/view?filename=${encodeURIComponent(
          after_image.filename
        )}&type=${after_image.type}&subfolder=${encodeURIComponent(
          after_image.subfolder
        )}&t=${+new Date()}`

        before_image = `${window.location.protocol}//${
          window.location.hostname
        }:${window.location.port}/view?filename=${encodeURIComponent(
          before_image.filename
        )}&type=${before_image.type}&subfolder=${encodeURIComponent(
          before_image.subfolder
        )}&t=${+new Date()}`

        this.widgets[0].div.innerHTML = ''

        let slider = new juxtapose.JXSlider(
          '#mix_comparingtowframes_' + this.id,
          [
            {
              src: before_image,
              label: 'Before'
            },
            {
              src: after_image,
              label: 'After'
            }
          ],
          {
            animate: true,
            showLabels: true,
            showCredits: false,
            startingPosition: '50%',
            makeResponsive: false
          }
        )

        this.widgets_values = [
          {
            src: before_image,
            label: 'Before'
          },
          {
            src: after_image,
            label: 'After'
          }
        ]
        this.size = [this.size[0], 300]
      }
    }
  },
  async loadedGraphNode (node, app) {
    // console.log('##loadedGraphNode', node)
    if (node.type === 'ComparingTwoFrames_') {
      // node.widgets[0].div.id = 'mix_comparingtowframes_' + node.id
      // if (node.widgets_values && node.widgets_values[0]) {
      //   node.widgets[0].div.innerHTML = ''
      //   let slider = new juxtapose.JXSlider(
      //     '#mix_comparingtowframes_' + node.id,
      //     node.widgets_values,
      //     {
      //       animate: true,
      //       showLabels: true,
      //       showCredits: false,
      //       startingPosition: '50%',
      //       makeResponsive: false
      //     }
      //   )
      // }
    }
  }
})
