import { fabric } from "fabric";
import {
  clearObjects,
  sortObjects,
  transformHighlightedText,
  checkTextBoxHeight,
} from "../../components/canvas/utils";
import COLORS from "../../colors";
import { PaddedHighlightingTextbox } from "../../components/canvas/textbox";

import lightLogoImageSource from "../../assets/logos/default-light.png";
import darkLogoImageSource from "../../assets/logos/default-dark.png";

let mainImage = null;
let logoImage = null;
let mainImageSource = null;
let previousLogoImageSource = null;
let contractedByTextbox = null;
let mainTextBox = null;
let nameText = null;

const redraw = async (canvas, options) => {
  clearObjects([contractedByTextbox, mainTextBox, nameText], canvas);

  const contractedByTextSize = Math.ceil(canvas.height * 0.013);
  const contractedByTextBottomMargin = Math.ceil(canvas.width * 0.04);
  const contractedByTextSideMargin = Math.ceil(canvas.width * 0.05);

  const mainTextMarginTop = Math.ceil(canvas.height * 0.15);
  const mainTextMarginLeft = Math.ceil(canvas.width * 0.05);
  const mainTextWidth = Math.ceil(canvas.width * 0.9);
  const mainTextSize = Math.ceil(canvas.height * 0.1);
  const mainTextMaxLines = 7;
  const mainTextLineHeight = 0.85;

  const nameTextMarginLeft = Math.ceil(canvas.width * 0.05);
  const nameTextMarginTop = Math.ceil(canvas.height * 0.1);
  const nameTextSize = Math.ceil(canvas.height * 0.05);

  const logoWidth = Math.ceil(canvas.width * 0.3);
  const logoSideMargin = Math.ceil(canvas.width * 0.04);

  canvas.preserveObjectStacking = true;

  /* BEGIN Main image render */

  if (
    options.mainImage !== null &&
    (!canvas.contains(mainImage) ||
      mainImage === null ||
      options.mainImage.src !== mainImageSource)
  ) {
    if (mainImage !== null) {
      canvas.remove(mainImage);
    }

    mainImage = new fabric.Image(options.mainImage, {
      left: 0,
      top: 0,
      zIndex: 0,
    });

    mainImage.controls = {
      ...fabric.Image.prototype.controls,
      mtr: new fabric.Control({ visible: false }),
    };

    if (mainImage.width >= mainImage.height) {
      mainImage.scaleToHeight(canvas.height);
    } else {
      mainImage.scaleToWidth(canvas.width);
    }

    canvas.add(mainImage);
    mainImageSource = options.mainImage.src;
    // canvas.centerObject(mainImage)
  } else if (mainImage !== null && options.mainImage === null) {
    canvas.remove(mainImage);
  }

  /* END Main image render */

  /* BEGIN Name text render */

  if (options.nameText !== null) {
    nameText = new fabric.Text(`${options.nameText}:`, {
      left: nameTextMarginLeft,
      top: nameTextMarginTop,
      fontFamily: "Bebas Neue",
      fontSize: nameTextSize,
      fill: options.colors.mainText.value,
      selectable: false,
      zIndex: 40,
    });

    canvas.add(nameText);
  }

  /* BEGIN Main text render */

  if (options.mainText !== null) {
    const highlightedData = transformHighlightedText(
      options.mainText,
      mainTextSize,
      mainTextWidth,
      "Bebas Neue",
      "#fec900",
      "#000000",
      { padWhenDiacritics: false, invertHighlight: true },
    );

    mainTextBox = new PaddedHighlightingTextbox(highlightedData.text, {
      width: mainTextWidth,
      top: mainTextMarginTop,
      left: mainTextMarginLeft,
      textAlign: "left",
      fontFamily: "Bebas Neue",
      fontSize: mainTextSize,
      lineHeight: mainTextLineHeight,
      fill: options.colors.mainText.value,
      styles: highlightedData.styles,
      selectable: false,
      highlightPadding: canvas.height * 0.003,
      zIndex: 10,
    });

    checkTextBoxHeight(mainTextBox, mainTextMaxLines);

    canvas.add(mainTextBox);
  }

  /* END Main text render */

  /* BEGIN Logo render */

  let logoImageSource = null;

  if (options.colors.mainText.value == COLORS.black.value) {
    logoImageSource = darkLogoImageSource;
  } else {
    logoImageSource = lightLogoImageSource;
  }

  if (logoImage === null || previousLogoImageSource != logoImageSource) {
    previousLogoImageSource = logoImageSource;

    if (logoImage !== null) {
      canvas.remove(logoImage);
    }

    const logoImageElement = new Image();

    await new Promise((resolve) => {
      logoImageElement.onload = () => {
        resolve();
      };

      logoImageElement.src = logoImageSource;
    });

    logoImage = new fabric.Image(logoImageElement, { selectable: false });
    logoImage.scaleToWidth(logoWidth);

    logoImage.set({
      left: logoSideMargin,
      top: canvas.height - logoSideMargin - logoImage.getScaledHeight(),
      zIndex: 11,
    });

    canvas.add(logoImage);
  }

  /* END Logo render */

  /* BEGIN Contracted by render */

  if (options.contractedBy !== null) {
    contractedByTextbox = new fabric.Text(options.contractedBy, {
      left: canvas.width - contractedByTextSideMargin,
      top: canvas.height - contractedByTextBottomMargin - contractedByTextSize,
      fontFamily: "Roboto Condensed",
      fontSize: contractedByTextSize,
      textAlign: "right",
      fill: options.colors.contractedByText.value,
      selectable: false,
      zIndex: 10,
    });

    checkTextBoxHeight(contractedByTextbox, 1);

    canvas.add(contractedByTextbox);

    contractedByTextbox.set({
      left: contractedByTextbox.left - contractedByTextbox.width,
    });
    canvas.renderAll();
  }

  /* END Contracted by render */

  sortObjects(canvas);
};

export default redraw;
