import { fabric } from "fabric";
import {
  clearObjects,
  sortObjects,
  transformHighlightedText,
  checkTextBoxHeight,
} from "../../components/canvas/utils";
import { PaddedHighlightingTextbox } from "../../components/canvas/textbox";
import overlayURL from "../../assets/template/poster/overlay.png";

let mainImage = null;
let mainImageSource = null;
let overlayImage = null;
let pointerDownEventAssigned = false;
let socialMediaTextObject = null;
let backgroundRect = null;
let bottomBackgroundRect = null;
let personNameText = null;
let mainText = null;
let firstColumn = null;
let secondColumn = null;

let arrow = null;

let contractedByTextbox = null;

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

let upEventFunction = null;
let canvasPointerDownEvent = null;

const redraw = async (canvas, options) => {
  clearObjects(
    [
      socialMediaTextObject,
      personNameText,
      contractedByTextbox,
      arrow,
      mainText,
      firstColumn,
      secondColumn,
    ],
    canvas,
  );

  const leftMarginText = 300;
  const leftMarginPersonText = 410;
  const bottomMarginText = 200;
  const bottomFontSize = 90;

  const topMarginText = 150;

  const mainTextMarginBottom = 1180;
  const mainTextSize = 300;

  const nameTextSize = 100;

  const arrowWidth = Math.ceil(canvas.width * 0.0235);
  const arrowHeight = Math.ceil(canvas.width * 0.0275);
  const arrowThickness = Math.ceil(canvas.width * 0.01);
  const arrowMarginLeft = 300;
  const arrowMarginBottom = Math.ceil(canvas.height * 0.257);

  const columnsMarginTop = 600;
  const columnsMarginBetween = 100;
  const columnsMaxWidth = 1500;
  const columnTextSize = 75;
  const columnLineHeight = 1;

  const contractedByTextSize = Math.ceil(canvas.height * 0.01);
  const contractedByTextMaxWidth = Math.ceil(canvas.width * 0.9);
  const contractedByTextSidesMargin = Math.ceil(canvas.width * 0.03);

  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 (backgroundRect === null) {
    backgroundRect = new fabric.Rect({
      width: canvas.width * 1.1,
      height: canvas.height * 1.1,
      top: -20, // FIXME: Why???? Fabric.js, what are you trying to tell me?!
      left: -20,
      fill: options.colors.background.value,
      selectable: false,
      zIndex: 0,
    });

    canvas.add(backgroundRect);
  }

  /* END Background render */

  /* 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: 10,
    });

    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)

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

    removeDownEventListener();
    pointerDownEventAssigned = false;
  }

  /* END Main image render */

  /* BEGIN Overlay render */

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

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

      overlayImage.src = overlayURL;
    });

    overlayImage = new fabric.Image(overlayImage, {
      top: -20, // FIXME: Why???? Fabric.js, what are you trying to tell me?!
      left: -20,
      zIndex: 20,
      selectable: false,
    });
    overlayImage.scaleToWidth(canvas.width + 22);

    canvas.add(overlayImage);
  }

  /* END Overlay render */

  /* BEGIN Bottom background render */

  if (bottomBackgroundRect === null) {
    bottomBackgroundRect = new fabric.Rect({
      width: canvas.width * 1.1,
      height: 1458,
      top: 3620, // FIXME: Why???? Fabric.js, what are you trying to tell me?!
      left: -20,
      fill: options.colors.background.value,
      zIndex: 30,
      selectable: false,
    });

    canvas.add(bottomBackgroundRect);
  }

  /* END Bottom background render */

  /* BEGIN Arrow render */

  arrow = new fabric.Polygon(
    [
      { x: 0, y: 0 },
      { x: arrowThickness, y: 0 },
      {
        x: arrowWidth,
        y: Math.ceil(arrowHeight) / 2,
      },
      {
        x: arrowThickness,
        y: arrowHeight,
      },
      { x: 0, y: arrowHeight },
      {
        x: arrowWidth - arrowThickness,
        y: Math.ceil(arrowHeight) / 2,
      },
      { x: 0, y: 0 },
    ],
    {
      top: canvas.height - arrowMarginBottom,
      left: arrowMarginLeft,
      fill: "#fec900",
      selectable: false,
      zIndex: 40,
    },
  );

  canvas.add(arrow);

  /* END Arrow render */

  /* BEGIN Name / position text render */

  if (options.personName !== null) {
    let styles = {
      0: {},
    };

    for (let position = 0; position < options.personName.length; position++) {
      styles[0][position] = {
        fontWeight: "bold",
      };
    }

    let nameText = options.personName;

    if (options.personPosition !== null) {
      nameText += ` | ${options.personPosition}`;
    }

    personNameText = new fabric.Text(nameText, {
      left: leftMarginPersonText,
      top: canvas.height - bottomBackgroundRect.height + topMarginText,
      fontFamily: "Roboto Condensed",
      fontSize: nameTextSize,
      styles: styles,
      fill: "#000",
      selectable: false,
      zIndex: 40,
    });

    canvas.add(personNameText);
  }

  /* END Name / position text render */

  /* BEGIN Main text render */

  if (options.mainText !== null) {
    mainText = new fabric.Text(options.mainText, {
      left: leftMarginText,
      top: canvas.height - mainTextMarginBottom,
      fontFamily: "Bebas Neue",
      fontSize: mainTextSize,
      fill: "#000",
      selectable: false,
      zIndex: 40,
    });

    canvas.add(mainText);
  }

  /* END Main text render */

  /* BEGIN Column text render */

  if (options.firstColumn !== null) {
    firstColumn = new fabric.Textbox(options.firstColumn, {
      left: leftMarginText,
      top: canvas.height - bottomBackgroundRect.height + columnsMarginTop,
      width: columnsMaxWidth,
      fontFamily: "Roboto Condensed",
      fontSize: columnTextSize,
      lineHeight: columnLineHeight,
      fill: "#000",
      selectable: false,
      zIndex: 40,
    });

    canvas.add(firstColumn);
  }

  if (options.secondColumn !== null) {
    secondColumn = new fabric.Textbox(options.secondColumn, {
      left: leftMarginText + columnsMarginBetween + columnsMaxWidth,
      top: canvas.height - bottomBackgroundRect.height + columnsMarginTop,
      width: columnsMaxWidth,
      fontFamily: "Roboto Condensed",
      fontSize: columnTextSize,
      lineHeight: columnLineHeight,
      fill: "#000",
      selectable: false,
      zIndex: 40,
    });

    canvas.add(secondColumn);
  }

  /* END Column text render */

  /* BEGIN Bottom text render */

  if (options.socialMedia1 || options.socialMedia2 || options.socialMedia3) {
    let socialMediaText = `${
      options.socialMedia1 !== null ? options.socialMedia1 + "         " : ""
    }${
      options.socialMedia2 !== null ? options.socialMedia2 + "         " : ""
    }${options.socialMedia3 !== null ? options.socialMedia3 : ""}`;

    socialMediaTextObject = new fabric.Text(socialMediaText, {
      left: leftMarginText,
      top: canvas.height - bottomMarginText - bottomFontSize,
      fontFamily: "Roboto Condensed",
      fontSize: bottomFontSize,
      fill: "#000",
      selectable: false,
      zIndex: 40,
    });

    canvas.add(socialMediaTextObject);
  }

  /* END Bottom text render */

  /* BEGIN Contracted by render */

  if (options.contractedBy !== null) {
    contractedByTextbox = new fabric.Textbox(options.contractedBy, {
      left:
        canvas.width - contractedByTextMaxWidth - contractedByTextSidesMargin,
      top: canvas.height - contractedByTextSidesMargin - 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);

  canvasPointerDownEvent = (event) => {
    let activeObject = canvas.getActiveObject();

    if (activeObject === null) {
      return;
    }

    // if (activeObject._element.src == mainImage._element.src) {
    // return
    // }

    canvas.remove(overlayImage);
    overlayImage = null;
  };

  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;
