import { fabric } from "fabric";
import {
  clearObjects,
  sortObjects,
  transformHighlightedText,
  checkTextBoxHeight,
} from "../../components/canvas/utils";
import { PaddedHighlightingTextbox } from "../../components/canvas/textbox";
import backgroundTopImageURL from "../../assets/template/regional_success/bg_top.png";
import backgroundBottomImageURL from "../../assets/template/regional_success/bg_bottom.png";
import backgroundArrowsImageURL from "../../assets/template/regional_success/arrows_bg.png";
//import overlayURL from '../../assets/template/poster/overlay.png'

let mainTextBox = null;
let contractedByTextbox = null;

let logoImage = null;
let mainImage = null;
let mainImageSource = null;
let pointerDownEventAssigned = false;
let backgroundTopImage = null;
let backgroundBottomImage = null;
let backgroundArrowsImage = null;
let mainText = null;
let firstRow = null;
let firstEmoji = null;
let secondRow = null;
let secondEmoji = null;
let thirdRow = null;
let thirdEmoji = null;
let fourthRow = null;
let fourthEmoji = null;
let nameText = null;
let nameTextDesc = null;
let gradientRect = null;

let previousLogoPosition = null;

const removeDownEventListener = () => {
  document
    .getElementsByClassName("upper-canvas")[0]
    .removeEventListener("pointerdown", canvasPointerDownEvent);
};

let upEventFunction = null;
let canvasPointerDownEvent = null;

const redraw = async (canvas, options) => {
  clearObjects(
    [
      mainText,
      firstRow,
      firstEmoji,
      secondRow,
      secondEmoji,
      thirdRow,
      thirdEmoji,
      fourthRow,
      fourthEmoji,
      nameText,
      nameTextDesc,
      contractedByTextbox,
      gradientRect,
    ],
    canvas,
  );

  const headerHeight = 391;
  const mainTextSize = 59;

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

  const rowHeightBg = 187;
  const rowBottomMargin = 10;
  const rowHeight = rowHeightBg + rowBottomMargin;

  const emojiHeight = 80;
  const emojiLeftMargin = 490;
  const emojiTopMargin = Math.ceil(
    headerHeight + (rowHeightBg - emojiHeight) / 2,
  );

  const contractedByTextSize = Math.ceil(canvas.height * 0.013);
  const contractedByTextMaxWidth = Math.ceil(canvas.width * 0.9);
  const contractedByTextSideMargin = Math.ceil(canvas.width * 0.068);
  const contractedByTextBottomMargin = Math.ceil(canvas.height * 0.023);

  const rowsMaxWidth = 425;
  const rowsTextSize = 38;
  const rowsLineHeight = 0.9;
  const rowsLeftMargin = 55;
  const rowsFontFamily = "Bebas Neue";
  const rowsTextColor = "#fff";

  document
    .getElementsByClassName("upper-canvas")[0]
    .removeEventListener("pointerup", upEventFunction);
  document
    .getElementsByClassName("upper-canvas")[0]
    .removeEventListener("pointerout", upEventFunction);
  document
    .getElementsByClassName("upper-canvas")[0]
    .removeEventListener("pointercancel", upEventFunction);

  canvas.preserveObjectStacking = true;

  /* BEGIN Background render */

  if (backgroundTopImage === null) {
    backgroundTopImage = new Image();

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

      backgroundTopImage.src = backgroundTopImageURL;
    });

    backgroundTopImage = new fabric.Image(backgroundTopImage, {
      top: 0,
      left: 0,
      selectable: false,
      zIndex: 5,
    });
    backgroundTopImage.scaleToWidth(canvas.width);

    canvas.add(backgroundTopImage);
  }

  if (backgroundBottomImage === null) {
    backgroundBottomImage = new Image();

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

      backgroundBottomImage.src = backgroundBottomImageURL;
    });

    backgroundBottomImage = new fabric.Image(backgroundBottomImage, {
      top: 1169,
      left: 0,
      zIndex: 10,
      selectable: false,
    });
    backgroundBottomImage.scaleToWidth(canvas.width);

    canvas.add(backgroundBottomImage);
  }

  /* END Background render */

  /* BEGIN Logo render */

  // A logo is provided, and it either hasn't been rendered yet or is a new one.
  const createNewLogo =
    (options.logoImage !== null &&
      (logoImage === null ||
        (options.logoImage !== null &&
          options.logoImage !== logoImage._element))) ||
    previousLogoPosition != options.logoPosition.id;

  previousLogoPosition = options.logoPosition.id;

  if (createNewLogo) {
    canvas.remove(logoImage);

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

    if (options.logoPosition.id == "top-right") {
      logoImage.set({
        left: canvas.width - logoWidth - logoSideMargin,
        top: logoSideMargin,
        zIndex: 11,
      });
    } else {
      logoImage.set({
        left: logoSideMargin,
        top: logoSideMargin,
        zIndex: 11,
      });
    }

    canvas.add(logoImage);
  }

  /* END Logo render */

  /* BEGIN Main image render */
  gradientRect = new fabric.Rect({
    left: 0,
    top: 400,
    width: 684,
    height: 780,
    zIndex: 5,
    fill: new fabric.Gradient({
      type: "linear",
      coords: { x1: 0, y1: 0, x2: 684, y2: 0 },
      colorStops: [
        { offset: 0, color: "rgba(255, 255, 255, 1)" },
        { offset: 1, color: "rgba(255, 255, 255, 0)" },
      ],
    }),

    selectable: false,
  });
  canvas.add(gradientRect);

  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, {
      top: 391,
      maxHeight: 782,
      right: 0,
      zIndex: 3,
    });

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

    canvas.add(mainImage);
    mainImageSource = options.mainImage.src;
    // canvas.centerObject(mainImage)

    removeDownEventListener();
    pointerDownEventAssigned = false;
  } else if (mainImage !== null && options.mainImage === null) {
    canvas.remove(mainImage);

    removeDownEventListener();
    pointerDownEventAssigned = false;
  }

  /* END Main image render */

  /* BEGIN Arrow background render */

  if (backgroundArrowsImage === null) {
    backgroundArrowsImage = new Image();

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

      backgroundArrowsImage.src = backgroundArrowsImageURL;
    });

    backgroundArrowsImage = new fabric.Image(backgroundArrowsImage, {
      top: 391,
      left: 0,
      selectable: false,
      zIndex: 6,
    });

    canvas.add(backgroundArrowsImage);
  }

  /* END Arrows background render */

  /* BEGIN Main text render */

  if (options.mainText !== null) {
    const highlightedData = transformHighlightedText(
      options.mainText,
      mainTextSize,
      "Bebas Neue",
      "#000",
      "#fec900",
      { padWhenDiacritics: true },
    );
    mainText = new PaddedHighlightingTextbox(highlightedData.text, {
      width: canvas.width - 37 * 2,
      left: 37,
      top: 155,
      textAlign: "left",
      fontFamily: "Bebas Neue",
      fontSize: 80,
      lineHeight: 1,
      zIndex: 10,
      fill: options.colors.baseText.value,
      styles: highlightedData.styles,
      selectable: false,
      highlightPadding: 5,
    });

    canvas.add(mainText);
  }
  /* END Main text render */

  /* BEGIN Row text render */
  if (options.firstRow !== null) {
    firstRow = new fabric.Textbox(options.firstRow, {
      top: 403,
      left: rowsLeftMargin,
      width: rowsMaxWidth,
      fontFamily: rowsFontFamily,
      fontSize: rowsTextSize,
      lineHeight: rowsLineHeight,
      fill: "#fff",
      selectable: false,
      zIndex: 40,
    });

    canvas.add(firstRow);
  }
  if (options.firstEmoji !== null) {
    firstEmoji = new fabric.Image(options.firstEmoji, {
      selectable: false,
      zIndex: 40,
    });
    firstEmoji.scaleToHeight(emojiHeight);
    firstEmoji.set({
      left: emojiLeftMargin,
      top: emojiTopMargin,
    });

    canvas.add(firstEmoji);
  }

  if (options.secondRow !== null) {
    secondRow = new fabric.Textbox(options.secondRow, {
      top: 600,
      left: rowsLeftMargin,
      width: rowsMaxWidth,
      fontFamily: rowsFontFamily,
      fontSize: rowsTextSize,
      lineHeight: rowsLineHeight,
      fill: rowsTextColor,
      selectable: false,
      zIndex: 40,
    });

    canvas.add(secondRow);
  }
  if (options.secondEmoji !== null) {
    secondEmoji = new fabric.Image(options.secondEmoji, {
      selectable: false,
      zIndex: 40,
    });
    secondEmoji.scaleToHeight(emojiHeight);
    secondEmoji.set({
      left: emojiLeftMargin,
      top: emojiTopMargin + rowHeight,
    });

    canvas.add(secondEmoji);
  }

  if (options.thirdRow !== null) {
    thirdRow = new fabric.Textbox(options.thirdRow, {
      top: 797,
      left: rowsLeftMargin,
      width: rowsMaxWidth,
      fontFamily: rowsFontFamily,
      fontSize: rowsTextSize,
      lineHeight: rowsLineHeight,
      fill: rowsTextColor,
      selectable: false,
      zIndex: 40,
    });

    canvas.add(thirdRow);
  }
  if (options.thirdEmoji !== null) {
    thirdEmoji = new fabric.Image(options.thirdEmoji, {
      selectable: false,
      zIndex: 40,
    });
    thirdEmoji.scaleToHeight(emojiHeight);
    thirdEmoji.set({
      left: emojiLeftMargin,
      top: emojiTopMargin + rowHeight * 2,
    });

    canvas.add(thirdEmoji);
  }

  if (options.fourthRow !== null) {
    fourthRow = new fabric.Textbox(options.fourthRow, {
      top: 994,
      left: rowsLeftMargin,
      width: rowsMaxWidth,
      fontFamily: rowsFontFamily,
      fontSize: rowsTextSize,
      lineHeight: rowsLineHeight,
      fill: rowsTextColor,
      selectable: false,
      zIndex: 40,
    });

    canvas.add(fourthRow);
  }
  if (options.fourthEmoji !== null) {
    fourthEmoji = new fabric.Image(options.fourthEmoji, {
      selectable: false,
      zIndex: 40,
    });
    fourthEmoji.scaleToHeight(emojiHeight);
    fourthEmoji.set({
      left: emojiLeftMargin,
      top: emojiTopMargin + rowHeight * 3,
    });

    canvas.add(fourthEmoji);
  }

  /* END Rows text render */

  /* BEGIN Name text render */

  if (options.nameText !== null) {
    const highlightedNameData = transformHighlightedText(
      options.nameText,
      mainTextSize,
      "Bebas Neue",
      "#000",
      "#fec900",
      { padWhenDiacritics: true },
    );

    nameText = new PaddedHighlightingTextbox(highlightedNameData.text, {
      width: canvas.width - 37 * 2,
      right: 60,
      top: 1200,
      textAlign: "right",
      fontFamily: "Bebas Neue",
      fontSize: 50,
      lineHeight: 1,
      zIndex: 12,
      fill: options.colors.baseText.value,
      styles: highlightedNameData.styles,
      selectable: false,
      highlightPadding: 5,
    });

    canvas.add(nameText);
  }
  /* END Name text render */

  /* BEGIN Name text description render */
  if (options.nameTextDesc !== null) {
    nameTextDesc = new fabric.Textbox(options.nameTextDesc, {
      width: canvas.width - 37 * 2,
      right: 60,
      top: 1265,
      textAlign: "right",
      fontFamily: "Roboto Condensed",
      fontSize: 20,
      fill: "#000",
      selectable: false,
      zIndex: 12,
    });

    canvas.add(nameTextDesc);
  }
  /* END Name text description render */

  /* BEGIN Contracted by render */

  if (options.contractedBy !== null) {
    contractedByTextbox = new fabric.Textbox(options.contractedBy, {
      left:
        canvas.width - contractedByTextMaxWidth - contractedByTextSideMargin,
      top: canvas.height - contractedByTextBottomMargin - contractedByTextSize,
      width: contractedByTextMaxWidth,
      fontFamily: "Roboto Condensed",
      fontSize: contractedByTextSize,
      textAlign: "right",
      fill: "#505050",
      selectable: false,
      zIndex: 40,
    });

    checkTextBoxHeight(contractedByTextbox, 1);

    canvas.add(contractedByTextbox);
  }

  /* END Contracted by render */

  sortObjects(canvas);

  if (!pointerDownEventAssigned) {
    document
      .getElementsByClassName("upper-canvas")[0]
      .addEventListener("pointerdown", canvasPointerDownEvent);

    pointerDownEventAssigned = true;
  }

  upEventFunction = (event) => {
    redraw(canvas, options);
  };

  document
    .getElementsByClassName("upper-canvas")[0]
    .addEventListener("pointerup", upEventFunction);

  document
    .getElementsByClassName("upper-canvas")[0]
    .addEventListener("pointerout", upEventFunction);

  document
    .getElementsByClassName("upper-canvas")[0]
    .addEventListener("pointercancel", upEventFunction);
};

export default redraw;
