const previewUrl = ''
const imageRendering = 'auto'
const renderSize = {
  width: 1000,
  height: 1000
};


class PreviewImageData {
  constructor(name, url, position, rotation, size) {
      this.name = name;
      this.url = url;
      this.position = position;
      this.rotation = rotation;
      this.size = size;
  }
}



async function loadImage(url) {
  return new Promise((resolve, reject) => {
    const image = document.createElement('img')
    image.src = url
    image.crossOrigin = 'anonymous'
    image.onload = () => {
      resolve(image)
    }
    image.onerror = () => {
      // Some display fallbacks for when the image fails to load
      if (!image.src.startsWith('https://')) {
        image.src = 'https://ordinals.com' + url
      } else if (image.src.startsWith('https://ordinals.com')) {
        image.src = 'https://ord-mirror.magiceden.dev' + url
      }
    }
  })
}

//check Attribute Existed
function CheckExisted(category, attribute){
  const sheet = category.getAttribute(attribute);
  if(sheet != null){
    return true;
  }
  return false;
}

//check Attribute if is true or false
function CheckBool(category, attribute){
  const sheet = category.getAttribute(attribute);
  if(sheet != null){
    if(JSON.parse(sheet)){
      return true;
    }
    return false;
  }
  return false;
}

function renderImageWithTranslate(canvasContext, canvas, image, position=[0.5,0.5], scale=[1,1], angle=0){
  const imageAspectRatio = image.width / image.height;
  const canvasAspectRatio = canvas.width / canvas.height;

  let drawWidth, drawHeight;
  if (imageAspectRatio > canvasAspectRatio) {
    drawWidth = canvas.width;
    drawHeight = canvas.width / imageAspectRatio;
  } else {
    drawHeight = canvas.height;
    drawWidth = canvas.height * imageAspectRatio;
  }

  const scaledWidth =drawWidth * scale[0];
  const scaledHeight  = drawHeight * scale[1];
  const rotationAngle = angle;
  const offsetX = canvas.width * position[0] - scaledWidth / 2;
  const offsetY = canvas.height * position[1] - scaledHeight / 2;

  canvasContext.save();
  canvasContext.translate(offsetX + scaledWidth/2, offsetY + scaledHeight/2);
  canvasContext.rotate((rotationAngle * Math.PI) / 180);
  canvasContext.drawImage(image,  -scaledWidth / 2, -scaledHeight / 2, scaledWidth, scaledHeight);
  canvasContext.restore();
}

function renderSheetImage(altasImg, sheetlayout, canvasContext, canvas, index=0, position=[0.5,0.5], scale=[1,1], angle=0){
  const tempCanvas = document.createElement('canvas');
  const atlasCols = sheetlayout[0];
  const atlasRows = sheetlayout[1];
  const imageIndex = index;
  const imageWidth = altasImg.width / atlasCols;
  const imageHeight = altasImg.height / atlasRows;
  tempCanvas.width = imageWidth;
  tempCanvas.height = imageHeight;
  const tempCtx = tempCanvas.getContext("2d");
  const col = imageIndex % atlasCols;
  const row = Math.floor(imageIndex / atlasCols);
  tempCtx.drawImage(altasImg, col * imageWidth, row * imageHeight, imageWidth, imageHeight, 0, 0, imageWidth, imageHeight);
  renderImageWithTranslate(canvasContext, canvas, tempCanvas,position,scale,angle);
}

function renderAtlasImage(canvasContext, canvas, image, atlasrange, position=[0.5,0.5], scale=[1,1], angle=0){
  const tempCanvas = document.createElement('canvas');
  tempCanvas.width = atlasrange[2];
  tempCanvas.height = atlasrange[3];
  const tempCtx = tempCanvas.getContext("2d");
  tempCtx.drawImage(image, atlasrange[0], image.height-atlasrange[1]-atlasrange[3], atlasrange[2], atlasrange[3], 0, 0, atlasrange[2], atlasrange[3]);
  renderImageWithTranslate(canvasContext,canvas,tempCanvas,position,scale,angle);
}


function GetPreviewImg(metaversepreviewElement){
  const previewImages = [];
  getAllPreviewData(metaversepreviewElement,previewImages);
  return previewImages;
}


function getAllPreviewData(metaversepreviewElement, imagesArray){
  var previewImgElements = metaversepreviewElement.querySelectorAll('previewimg');
  if(previewImgElements){
    previewImgElements.forEach((Element,index)=> {
      element_url = Element.getAttribute('src');
      element_size = Element.getAttribute('size');
      element_position = Element.getAttribute('position');
      element_rotation = Element.getAttribute('rotation');
      if(element_url){
        num = index;
        url = element_url;
        size = [1.0,1.0];
        position = [0.5,0.5];
        rotation = 0;
        if(element_size){
          size = JSON.parse(element_size);
        }
        if(element_position){
          position = JSON.parse(element_position);
        }
        if(element_rotation){
          rotation = JSON.parse(element_rotation);
        }
        const previewImage = new PreviewImageData(num, url, position, rotation, size);
        
        imagesArray.push(previewImage);
      }
    })
  }
}




async function renderImage(imageEl) {
  const canvas = document.createElement('canvas');
  const metaverse = 'metaverse';
  const metaversepreview = 'metaversepreview';
  const sheetlayout = 'sheetlayout';
  const sheetindex = 'sheetindex';
  canvas.width = renderSize.width;
  canvas.height = renderSize.height;

  const ctx = canvas.getContext("2d");
  ctx.imageSmoothingEnabled = false;
  const frontimg = "frontimg";
  const metaverseElement = document.querySelector(metaverse);
  const metaversepreviewElement = document.querySelector(metaversepreview);
  const baseimgurl = metaverseElement.getAttribute('src');
  const baseimg = await loadImage(baseimgurl);
  

  
  var previewImgs = [];
  var previewimgurls = [];
  var previewimages = [];
  

  if(metaversepreviewElement){
    const backgroundcolor = metaversepreviewElement.getAttribute('backgroundcolor');
    if(backgroundcolor){
      document.body.style.backgroundColor = backgroundcolor;
    }
    previewImgs = GetPreviewImg(metaversepreviewElement);
    previewimgurls = previewImgs.map(image => image.url);
    previewimages = await Promise.all((previewimgurls).map(loadImage));
  }
  
  
  if(previewImgs.length==0 && previewimages==0){
    if(CheckBool(metaverseElement,'issheetanimate') && CheckExisted(metaverseElement,sheetlayout))
    {
      const sheet = JSON.parse(metaverseElement.getAttribute(sheetlayout));
      renderSheetImage(baseimg, sheet, ctx, canvas);
    }else if(CheckBool(metaverseElement,'isatlas') && CheckExisted(metaverseElement,'atlasrange')){
      const imgatlasrange = JSON.parse(metaverseElement.getAttribute('atlasrange'));
      renderAtlasImage(ctx, canvas, baseimg, imgatlasrange);
    }
    else{
      renderImageWithTranslate(ctx, canvas, baseimg);
    }
  }
  
  if(previewimages.length > 0){
    var previewElements = metaversepreviewElement.querySelectorAll('previewimg');
    previewimages.forEach((element,index) => {
      
      var previewchildElement = previewElements[index];
      if(!CheckExisted(previewchildElement,'src'))
      {
        return;
      }
      if(CheckBool(previewchildElement,'issheetanimate') && CheckExisted(previewchildElement,sheetlayout)){
        const sheet = JSON.parse(previewchildElement.getAttribute(sheetlayout));
        const stindex = previewchildElement.getAttribute(sheetindex);
        if(stindex){
          const sheetindex = JSON.parse(stindex);
          renderSheetImage(element, sheet, ctx, canvas, stindex, previewImgs[index].position, previewImgs[index].size, previewImgs[index].rotation);
        }else{
          renderSheetImage(element, sheet, ctx, canvas, 0, previewImgs[index].position, previewImgs[index].size, previewImgs[index].rotation);
        }
      }else if(CheckBool(previewchildElement,'isatlas') && CheckExisted(previewchildElement,'atlasrange')){
        const imgatlasrange = JSON.parse(previewchildElement.getAttribute('atlasrange'));
        renderAtlasImage(ctx, canvas, element, imgatlasrange, previewImgs[index].position, previewImgs[index].size, previewImgs[index].rotation);
      }
      else{
        renderImageWithTranslate(ctx,canvas,element,previewImgs[index].position,previewImgs[index].size,previewImgs[index].rotation);
      }
    });
  }
  
  
  imageEl.src = canvas.toDataURL("image/png")
}



function createInitialImage() {

  document.body.style.margin = '0px';
  document.body.style.padding = '0px';
  document.body.style.backgroundColor = 'ffffff';


  const img = document.createElement('img');
  img.id = 'img';
  img.style.height = '100%';
  img.style.width = '100%';
  img.style.objectFit = 'contain';
  img.style.imageRendering = imageRendering;

  return img
}

async function createInscriptionHtml() {
  const imageEl = createInitialImage()
  try{
    await renderImage(imageEl);
  }catch (e) {
    console.error(e)
  }finally {
    // Append the <img> tag to the <body>
    document.body.appendChild(imageEl);
  }

}

window.onload = function() {
  createInscriptionHtml();
}