import React, { useState } from "react";
import EmailEditor, { Design, Editor, EditorRef } from "react-email-editor";

import { TemplateAddressDto } from "types/templates";

import { startingTemplate } from "./assets/startingTemplate";
import { emptyAddress } from "../utils";
import { unlayerOptions } from "../constants";
import { noop } from "utils/noop";
import { FLAGS, useFeatureIsOn } from "@komi-app/flags-sdk";

export interface TemplateBuilderProps {
  // eslint-disable-next-line @typescript-eslint/ban-types
  initialTemplate?: object;
  onDesignUpdated: () => void;
  setAddress: (address: TemplateAddressDto) => void;
  setDesign: (design: Design) => void;
  setEmailEditor: (editor: Editor) => void;
  setHtml: (html: string) => void;
  setIsLoading: (isSaving: boolean) => void;
}

const TemplateBuilder = React.forwardRef<EditorRef, TemplateBuilderProps>(
  (
    {
      initialTemplate,
      onDesignUpdated,
      setAddress,
      setDesign = noop,
      setEmailEditor,
      setHtml,
      setIsLoading,
    },
    emailEditorRef,
  ) => {
    const isAllowDeleteFooter = useFeatureIsOn(
      FLAGS.FEAT_CRM_1267_ALLOW_DELETE_FOOTER,
    );

    const [templateSet, setTemplateSet] = useState(false);
    const [hasLoaded, setHasLoaded] = useState(false);

    const emailEditor =
      typeof emailEditorRef === "function"
        ? null
        : emailEditorRef?.current?.editor;
    const setDefaultContentWidth = useFeatureIsOn(
      FLAGS.FEAT_CRM_1249_EMAIL_TEMPLATE_DEFAULT_WIDTH,
    );

    // Called when the editor is ready
    const onReady = () => {
      if (!hasLoaded) {
        setHasLoaded(true);
        setIsLoading(false);
      }

      if (!emailEditor) return;
      setEmailEditor(emailEditor);

      // Add a listener for when the design is updated
      emailEditor.addEventListener("design:updated", function () {
        onDesignUpdated();

        if (!emailEditor) return;

        emailEditor.exportHtml((data) => {
          setHtml(data.html);
          setDesign(data.design);

          const address = getAddress(data.design);

          setAddress(address ?? emptyAddress());
        });
      });

      if (templateSet) return;

      const designToLoad = initialTemplate
        ? initialTemplate
        : startingTemplate(isAllowDeleteFooter, setDefaultContentWidth);

      emailEditor.loadDesign(designToLoad as Design);

      setTemplateSet(true);
    };

    // Some more than average gnarlyness here.
    // We have to manually retrieve the values of the custom block
    // so we can parse the address and pass them up
    const getAddress = (design: Design) => {
      // If there's no custom block return undefined
      const addressBlock = (design.body.rows as any)
        .flatMap((x: any) => x.columns.flatMap((y: any) => y.contents))
        .find((z: any) => z.slug === "komi_campaign_email_footer")?.values;

      if (!addressBlock) return undefined;

      const {
        address_line_a: firstLine,
        address_line_b: secondLine,
        address_city: city,
        address_country: country,
        address_zip_code: zipcode,
      } = addressBlock;

      if (!firstLine && !secondLine && !city && !country && !zipcode)
        return undefined;

      // Parse the address values and return them
      const address = {
        firstLine: firstLine === "" ? null : firstLine,
        secondLine: secondLine === "" ? null : secondLine,
        city: city === "" ? null : city,
        country: country === "" ? null : country,
        zipcode: zipcode === "" ? null : zipcode,
      };

      return address;
    };

    // Custom blocks are created within Unlayer itself:
    //  - Komi Footer: https://dashboard.unlayer.com/projects/148721/design/tools/7868
    return (
      <div className="template-builder">
        <EmailEditor
          options={unlayerOptions}
          ref={emailEditorRef}
          onReady={onReady}
        />
      </div>
    );
  },
);

TemplateBuilder.displayName = "TemplateBuilder";
export default TemplateBuilder;
