import alertifyjs from "alertifyjs";
import "alertifyjs/build/css/alertify.css";

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

let mainTextBox = null;
let mainTextBoxBackground = null;

let contractedByTextbox = null;

let mainImage = null;
let logoImage = null;

let firstEmojiImage = null;
let secondEmojiImage = null;

let firstEmojiText = null;
let secondEmojiText = null;

let mainImageSource = null;
let previousLogoPosition = null;

const redraw = async (canvas, options) => {
  clearObjects(
    [
      mainTextBox,
      mainTextBoxBackground,
      firstEmojiImage,
      firstEmojiText,
      secondEmojiImage,
      secondEmojiText,
      contractedByTextbox,
    ],
    canvas,
  );

  canvas.preserveObjectStacking = true;

  const textMarginSides = Math.ceil(canvas.width * 0.14);

  let mainTextMarginBottom = Math.ceil(canvas.height * 0.06);
  const mainTextBackgroundMarginTop = Math.ceil(canvas.height * 0.14);
  const mainTextSize = Math.ceil(canvas.height * 0.0725);
  const mainTextLineHeight = 1;

  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 emojiImageHeight = Math.ceil(canvas.height * 0.1);

  const firstEmojiImageMarginSide = Math.ceil(canvas.width * 0.25);
  const firstEmojiImageMarginTop = 50;
  const secondEmojiImageMarginSide = Math.ceil(canvas.width * 0.65);
  const secondEmojiImageMarginTop = 50;

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

  if (options.mainText !== null) {
    /* BEGIN Main text render */

    const mainTextWidth = canvas.width - textMarginSides * 2;

    const highlightedData = transformHighlightedText(
      options.mainText,
      mainTextSize,
      mainTextWidth,
      "Bebas Neue",
      options.colors.highlight.value,
      options.colors.highlightedText.value,
    );

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

    checkTextBoxHeight(mainTextBox, 3);

    canvas.add(mainTextBox);

    mainTextBox.top =
      canvas.height - mainTextBox.height - mainTextMarginBottom - 200;

    canvas.renderAll();

    /* END Main text render */

    /* BEGIN First Emoji render*/

    if (options.firstEmojiImage !== null) {
      firstEmojiImage = new fabric.Image(options.firstEmojiImage, {
        selectable: false,
        zIndex: 10,
      });
      firstEmojiImage.scaleToHeight(emojiImageHeight);
      firstEmojiImage.set({
        left: canvas.width / 2 - 600,
        top: mainTextBox.top + mainTextBox.height + firstEmojiImageMarginTop,
      });

      canvas.add(firstEmojiImage);
    }

    if (options.firstEmojiText !== null && options.firstEmojiImage !== null) {
      firstEmojiText = new fabric.Textbox(options.firstEmojiText, {
        left: firstEmojiImage.left + 250,
        width: 500,
        top:
          mainTextBox.top +
          mainTextBox.height +
          firstEmojiImageMarginTop +
          emojiImageHeight / 8,
        fontFamily: "Bebas Neue",
        fontSize: mainTextSize,
        fill: options.colors.baseText.value,
        selectable: false,
        zIndex: 10,
      });

      canvas.add(firstEmojiText);

      if (firstEmojiText._textLines.length > 1) {
        firstEmojiText.set({
          fontSize: firstEmojiText.fontSize - mainTextSize / 2,
          lineHeight: 0.9,
        });
        canvas.renderAll();
      } else if (firstEmojiText.width > 500) {
        firstEmojiText.set({
          fontSize: firstEmojiText.fontSize - mainTextSize / 2,
          lineHeight: 0.9,
        });
        firstEmojiText.top += firstEmojiText.fontSize / 2.5;
        canvas.renderAll();
      }

      if (firstEmojiText._textLines.length > 2) {
        canvas.remove(firstEmojiText);

        if (!window.showingMaxLinesWarning) {
          window.showingMaxLinesWarning = true;

          const errorMessage = alertifyjs.error(
            "Text je moc dlouhý a nevejde se do 2 řádků. Prosím, zkrať ho.",
          );

          errorMessage.callback = () => {
            window.showingMaxLinesWarning = false;
          };
        }
      }
    }

    /* END First emoji render */

    /* BEGIN Second Emoji render */

    if (options.secondEmojiImage !== null) {
      secondEmojiImage = new fabric.Image(options.secondEmojiImage, {
        selectable: false,
        zIndex: 10,
      });
      secondEmojiImage.scaleToHeight(emojiImageHeight);
      secondEmojiImage.set({
        left: canvas.width / 2 + 200,
        top: mainTextBox.top + mainTextBox.height + firstEmojiImageMarginTop,
      });

      canvas.add(secondEmojiImage);
    }

    if (options.secondEmojiText !== null && options.secondEmojiImage !== null) {
      secondEmojiText = new fabric.Textbox(options.secondEmojiText, {
        left: secondEmojiImage.left + 250,
        width: 300,
        top:
          mainTextBox.top +
          mainTextBox.height +
          secondEmojiImageMarginTop +
          emojiImageHeight / 8,
        fontFamily: "Bebas Neue",
        fontSize: mainTextSize,
        fill: options.colors.baseText.value,
        selectable: false,
        zIndex: 10,
      });

      canvas.add(secondEmojiText);

      if (secondEmojiText._textLines.length > 1) {
        secondEmojiText.set({
          fontSize: secondEmojiText.fontSize - mainTextSize / 2,
          lineHeight: 0.9,
        });
        canvas.renderAll();
      } else if (secondEmojiText.width > 500) {
        secondEmojiText.set({
          fontSize: secondEmojiText.fontSize - mainTextSize / 2,
          lineHeight: 0.9,
        });
        secondEmojiText.top += secondEmojiText.fontSize / 2.5;
        canvas.renderAll();
      }

      if (secondEmojiText._textLines.length > 2) {
        canvas.remove(secondEmojiText);

        if (!window.showingMaxLinesWarning) {
          window.showingMaxLinesWarning = true;

          const errorMessage = alertifyjs.error(
            "Text je moc dlouhý a nevejde se do 2 řádků. Prosím, zkrať ho.",
          );

          errorMessage.callback = () => {
            window.showingMaxLinesWarning = false;
          };
        }
      }
    }

    /* END Second Emoji render */

    /* BEGIN Main text background render */

    const backgroundHeight =
      canvas.height - mainTextBox.top + mainTextBackgroundMarginTop;

    mainTextBoxBackground = new fabric.Rect({
      width: canvas.width + 40, // FIXME: My god!
      height: backgroundHeight * options.gradientHeightMultiplier,
      left: -20,
      top:
        mainTextBox.top -
        mainTextBackgroundMarginTop -
        backgroundHeight * (options.gradientHeightMultiplier - 1),
      fill: new fabric.Gradient({
        type: "linear",
        gradientUnits: "pixels",
        coords: {
          x1: 0,
          y1: 0,
          x2: 0,
          y2: backgroundHeight * options.gradientHeightMultiplier,
        },
        colorStops: [
          {
            offset: 1,
            color: options.colors.background.value,
          },
          {
            offset: 0.45,
            color: options.colors.background.value,
          },
          {
            offset: 0,
            color: `${options.colors.background.value}00`,
          },
        ],
      }),
      selectable: false,
      zIndex: 9,
    });

    canvas.add(mainTextBoxBackground);

    /* END Main text 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 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 &&
    (!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 */

  sortObjects(canvas);
};

export default redraw;
