import { client } from "@sc/api/gql";
import { getPage } from "@sc/api/gql/pages";
import {
  Button,
  Cell,
  Dialog,
  DialogBody,
  DialogFooter,
  Grid,
} from "@sc/components/ui";
import { AppConfig } from "@sc/modules/app";
import _ from "lodash";
import React, { Component } from "react";
import style from "./style";
import { triggerAsyncHook } from "@sc/plugins";

/**
 * This is the popup window that displays when a user attempts to publish their page
 * @param {object} props The props
 * @returns {function} The component
 */
class PublishCampaignSuccess extends Component {
  constructor(props) {
    super(props);
    this.state = {
      url: "",
      published: false,
    };

    this.getNextPage = this.getNextPage.bind(this);
    this.doPublish = this.doPublish.bind(this);

    window.scroll(0, 0);
  }

  static contextType = AppConfig;

  // calculate nextPage
  getNextPage(pageId) {
    // 1. get list of page objects
    const objects = this.props.getCampaignQuery.campaign.objects;
    const pages = objects.filter(
      (obj) => !obj.deleted && _.has(obj, "page.slug")
    );

    // 2. find the object associated with the provided pageId
    if (pages) {
      const theObject = pages.filter((obj) => obj.page.id === pageId);

      if (theObject.length) {
        const object = theObject[0]; // this is the object associated with the page I'm using to find the nextPage's slug

        // 3. in that object, find the first matching connectTo objId that happens to be
        // a page (find out if any of the connectTo ids match any of the ids in the
        // pages object array)
        if (object.connectTo) {
          const nextPageObj = object.connectTo.filter((itm) => {
            const objId = itm.id; // this is the object id in the connectTo array
            return pages.filter((pg) => pg.id === objId) && !itm.deleted;
          });

          // 4. return the slug of that matching object
          console.log(pageId, { pages }, { nextPageObj });
          if (nextPageObj.length) {
            const thePages = _.head(
              _.filter(pages, (pg) => pg.id === nextPageObj[0].id)
            );
            return _.get(thePages, "page.slug", false);
          }
          return false;
        }
        return false;
      }
    }

    return false;
  }

  async doPublish() {
    const { app } = this.context;

    const {
      // getPageQuery,
      // getPage,
      getCampaignQuery,
      publishCampaign,
      getUserQuery,
      // updateCampaignObjectMutation,
      updatePageSettings,
      updateObjectSettings,
    } = this.props;

    const userSettings = getUserQuery.user;
    const { objects, id, type } = getCampaignQuery.campaign;

    // build page array
    //  1. loop through objects (filter page objects)
    // const parentDomain = _.get(
    //   getCampaignQuery,
    //   "campaign.domain.name",
    //   `${userSettings.subdomain}.${app.domain}`
    // );

    // ^^ we now map domains to their subdomain on s3, so we should upload to that folder (and not a folder with their domain name)
    const parentDomain = `${userSettings.subdomain}.${app.domain}`;

    const pageObjects = objects.filter(
      (obj) => !obj.deleted && _.has(obj, "page.slug")
    );

    console.log({ pageObjects });

    let returnThisObjectArray = [];

    for (const obj of pageObjects) {
      //  2. fetch page for each object
      const { page } = obj;
      console.log("PAGEID: ", page.id);
      // console.log({ getPageQuery });

      await triggerAsyncHook(
        "onNodePublish",
        { type: obj.type, mode: "campaign" },
        { item: obj },
        {
          // updateObject: async variables =>
          //   await updateCampaignObjectMutation({ variables }),
          updateObjectSettings: async (variables) =>
            await updateObjectSettings({ variables }),
          updatePageSettings: async (variables) =>
            await updatePageSettings({ variables }),
        }
      );

      // const pageData = await getPageQuery.refetch({ pageId: page.id });
      const pageData = await client.query({
        query: getPage,
        variables: {
          pageId: page.id,
        },
      });

      console.log({ pageData });

      const {
        content,
        homePageForDomain,
        errorPageForDomain,
        id,
        pageSettings,
        slug,
        type,
      } = pageData.data.page;

      //  3. convert to json using json.stringify
      const seoPayload = _.get(pageSettings, "seo", {});
      const emailPayload = _.get(pageSettings, "email", {});
      const merchantPayload = _.get(pageSettings, "merchant", {});
      const trackingPayload = _.get(pageSettings, "tracking", {});
      const isHomePage = homePageForDomain !== null;
      const is404 = errorPageForDomain !== null;

      const pageObject = {
        content: JSON.stringify(content),
        id,
        slug,
        type,
        seoPayload: JSON.stringify(seoPayload),
        emailPayload: JSON.stringify(emailPayload),
        merchantPayload: JSON.stringify(merchantPayload),
        trackingPayload: JSON.stringify(trackingPayload),
        isHomePage,
        is404,
        launchDate: new Date().toISOString(),
        nextPage: this.getNextPage(id) || "#",
      };

      returnThisObjectArray.push(pageObject);
    }

    console.log({ returnThisObjectArray });
    const pageObjectJson = JSON.stringify(returnThisObjectArray);

    //  4. finish building campaign publish graphQL payload
    const variables = {
      campaignId: id,
      objects: pageObjectJson,
      trackingPayload: getCampaignQuery.campaign.scriptTags || "{}",
      launchDate: new Date().toISOString(),
      type,
      parentDomain,
      cloudfrontDistribution:
        _.get(
          getCampaignQuery,
          "campaign.domain.cloudfrontDistribution",
          false
        ) || app.cloudfrontDistribution,
    };

    //  5. call the publishCampaign graphQL command
    console.log({ variables });

    publishCampaign({ variables }).then((response) => {
      const firstBuildableObject = _.head(
        getCampaignQuery.campaign.objects.filter(
          (itm) => itm.type === "PageComponent" && !itm.deleted
        )
      );

      const showSlug = _.head(
        _.filter(
          getCampaignQuery.campaign.objects,
          (obj) =>
            _.get(obj, "page.homePageForDomain", false) !== null && !obj.deleted
        )
      );

      const slug = _.has(showSlug, "page.homePageForDomain.id")
        ? showSlug.page.slug
        : firstBuildableObject.page.slug;

      // console.log({ firstBuildableObject, showSlug, slug });

      //  6. return success/fail response
      console.log({ response });

      const publishedDomain = _.get(
        getCampaignQuery,
        "campaign.domain.name",
        `${userSettings.subdomain}.${app.domain}`
      );

      this.setState({
        published: true,
        url: `http://${publishedDomain}/${slug}`,
      });
    });
  }

  componentDidMount() {
    const { getCampaignQuery } = this.props;

    if (!getCampaignQuery.loading && !getCampaignQuery.error) {
      this.doPublish();
    }
  }

  render() {
    const { app } = this.context;
    return (
      <Dialog
        {...this.props}
        style={style.popup}
        overlayStyle={style.popupBg}
        centered
        hidden={false}
      >
        <DialogBody>
          {this.state.published ? (
            <div>
              <img
                alt=""
                style={{
                  margin: 10,
                }}
                src="https://s3.amazonaws.com/sandcastleassets/images/success_check.png"
              />
              <h2>Your Campaign Has Been Published!</h2>
              {/* <div
                style={{
                  color: "red",
                  textAlign: "center"
                }}
              >
                Please Note: Your changes may not take effect for up to another
                60 seconds!
              </div> */}
              <Grid
                justify="center"
                style={{
                  marginTop: 30,
                  border: "1px solid #CCC",
                  padding: 5,
                  borderRadius: 3,
                  width: 600,
                }}
              >
                <Cell align="center">
                  <a
                    target="_blank"
                    href={this.state.url}
                    rel="noopener noreferrer"
                  >
                    <span
                      style={{
                        color: "#555",
                        textDecoration: "underline",
                      }}
                    >
                      {this.state.url}
                    </span>
                  </a>
                </Cell>
                <Cell align="center">
                  <Button
                    style={{
                      color: "#999",
                      visibility: "hidden",
                    }}
                    icon
                  >
                    edit
                  </Button>
                </Cell>
              </Grid>
            </div>
          ) : (
            <div>
              <h2>Please wait while we publish your campaign...</h2>
              <div
                style={{
                  color: "red",
                  textAlign: "center",
                }}
              >
                Note: This may take up to 60 seconds
              </div>
              <img
                style={{
                  marginTop: 10,
                }}
                alt=""
                src={app.loadingImage}
              />
            </div>
          )}
        </DialogBody>
        <DialogFooter>
          {this.state.published ? (
            <Grid justify="space-evenly">
              <Cell align="center">
                <a
                  target="_blank"
                  href={this.state.url}
                  rel="noopener noreferrer"
                >
                  <Button large tertiary>
                    VISIT PAGE NOW
                  </Button>
                </a>
              </Cell>
            </Grid>
          ) : null}
        </DialogFooter>
      </Dialog>
    );
  }
}

PublishCampaignSuccess.defaultProps = {
  hide: true,
};

export default PublishCampaignSuccess;
