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

let background = null;

let personNameTextBox = null;
let personTwitterTextBox = null;
let mainTextBox = null;

let contractedByTextbox = null;

let mainImage = null;
let logoImage = null;
let twitterLogoImage = null;
let previousLogoPosition = null;

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

  canvas.preserveObjectStacking = true;

  const mainImageOffsetSide = Math.ceil(canvas.width * 0.075);
  const mainImageWidth = Math.ceil(canvas.width * 0.425);
  const mainImageOffsetTop = Math.ceil(canvas.height * 0.17);

  const logoSideMargin = Math.ceil(canvas.width * 0.075);
  const logoWidth = Math.ceil(canvas.width * 0.25);

  const twitterLogoImageWidth = Math.ceil(canvas.width * 0.08);
  const twitterLogoOffsetTop = Math.ceil(canvas.height * 0.1);

  const mainTextBoxWidth = Math.ceil(canvas.width * 0.38);
  const mainTextBoxMarginSide = Math.ceil(canvas.width * 0.06);
  const mainTextBoxMarginTop = Math.ceil(canvas.height * 0.03);
  const mainTextBoxFontSize = Math.ceil(canvas.height * 0.038);
  const mainTextBoxLineHeight = 1;
  const mainTextBoxCharSpacing = -Math.ceil(canvas.width * 0.015);

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

  const nameTextFontSize = Math.ceil(canvas.height * 0.065);
  const nameTextOffsetTop = Math.ceil(canvas.height * 0.03);

  const twitterTextFontSize = Math.ceil(canvas.height * 0.037);
  const twitterTextOffsetTop = Math.ceil(canvas.height * -0.007);

  /* BEGIN Background render */

  if (background === null) {
    background = 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,
    });

    canvas.add(background);
  }

  /* END Background render */

  /* BEGIN Twitter logo render */

  if (twitterLogoImage === null) {
    const twitterLogoImageElement = new Image();

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

      twitterLogoImageElement.src = options.twitterLogoImageSource;
    });

    twitterLogoImage = new fabric.Image(twitterLogoImageElement, {
      selectable: false,
    });
    twitterLogoImage.scaleToWidth(twitterLogoImageWidth);
    twitterLogoImage.set({
      left:
        canvas.width -
        mainTextBoxMarginSide -
        (mainTextBoxWidth + twitterLogoImageWidth) / 2,
      top: twitterLogoOffsetTop,
      zIndex: 11,
    });

    canvas.add(twitterLogoImage);
  }

  /* END Twitter logo render */

  if (options.personName !== null) {
    /* BEGIN Name text render */

    personNameTextBox = new fabric.Textbox(options.personName, {
      width: mainTextBoxWidth,
      textAlign: "center",
      fontSize: nameTextFontSize,
      fontFamily: "Bebas Neue",
      fill: options.colors.text.value,
      left: canvas.width - mainTextBoxMarginSide - mainTextBoxWidth,
      top:
        twitterLogoImage.top +
        twitterLogoImage.getScaledHeight() +
        nameTextOffsetTop,
      selectable: false,
      zIndex: 11,
    });

    canvas.add(personNameTextBox);

    /* END Name text render */

    if (options.personTwitter !== null) {
      /* BEGIN Twitter handle text render */

      personTwitterTextBox = new fabric.Textbox(`@${options.personTwitter}`, {
        width: mainTextBoxWidth,
        textAlign: "center",
        fontSize: twitterTextFontSize,
        fontFamily: "Roboto",
        fill: options.colors.text.value,
        left: canvas.width - mainTextBoxMarginSide - mainTextBoxWidth,
        top:
          personNameTextBox.top +
          personNameTextBox.height +
          twitterTextOffsetTop,
        selectable: false,
        zIndex: 11,
      });

      canvas.add(personTwitterTextBox);

      /* END Twitter handle text render */

      /* BEGIN Main text render */

      if (options.mainText !== null) {
        const highlightedData = transformHighlightedText(
          options.mainText,
          mainTextBoxFontSize,
          mainTextBoxWidth,
          "Roboto Condensed",
          options.colors.highlight.value,
          options.colors.highlightedText.value,
          { prependLinesWithSpace: true },
        );

        mainTextBox = new PaddedHighlightingTextbox(highlightedData.text, {
          width: canvas.width,
          textAlign: "left",
          fontSize: mainTextBoxFontSize,
          fontFamily: "Roboto Condensed",
          lineHeight: mainTextBoxLineHeight,
          charSpacing: mainTextBoxCharSpacing,
          fill: options.colors.text.value,
          styles: highlightedData.styles,
          left: canvas.width - mainTextBoxMarginSide - mainTextBoxWidth,
          top:
            personTwitterTextBox.top +
            personTwitterTextBox.height +
            mainTextBoxMarginTop,
          selectable: false,
          highlightPadding: canvas.height * 0.003,
          zIndex: 11,
        });

        checkTextBoxHeight(mainTextBox, 14);

        canvas.add(mainTextBox);
      }

      /* END Main text render */
    }
  }

  /* BEGIN Logo render */

  if (logoImage === null || previousLogoPosition != options.logoPosition.id) {
    if (logoImage !== null) {
      canvas.remove(logoImage);
    }

    const logoImageElement = new Image();

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

      logoImageElement.src = options.logoImageSource;
    });

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

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

    canvas.add(logoImage);
  }

  previousLogoPosition = options.logoPosition.id;

  /* END Logo 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: options.colors.contractedByText.value,
      selectable: false,
      zIndex: 10,
    });

    checkTextBoxHeight(contractedByTextbox, 1);

    canvas.add(contractedByTextbox);
  }

  /* END Contracted by render */

  /* BEGIN Main image render */

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

    mainImage = new fabric.Image(options.mainImage, {
      left: mainImageOffsetSide,
      top: mainImageOffsetTop,
      selectable: false,
      zIndex: 0,
    });
    mainImage.scaleToWidth(mainImageWidth);

    canvas.add(mainImage);
    // canvas.centerObject(mainImage)
  }

  /* END Main image render */

  sortObjects(canvas);
};

export default redraw;
