import { useState, useEffect } from "react";
import { CampaignStatuses, useConfirmationModal } from "@komi-app/components";
import { Prompt, useHistory, useLocation } from "react-router-dom";
import { Location } from "history";
import { useMutation, useQuery } from "@tanstack/react-query";
import { getCampaignSDK } from "services";
import CampaignPageHeader from "../../CampaignPageHeader";
import CampaignForm from "./EmailCampaignDetailsForm";
import { campaignsUrl } from "constants/dca/campaigns";
import { useUnsavedChangesRedirectionWarning } from "hooks/useUnsavedChangesRedirectionWarning";

import {
  CampaignType,
  EMAIL_CAMPAIGN_DEFAULT_FORM_VALUES,
  EmailCampaignDetailsProps,
  EmailCampaignForm,
} from "@komi-app/messaging-sdk";

import moment from "moment";
import { prune } from "utils/prune";

import { formToPayload } from "../helpers";

import "./EmailCampaignDetails.scss";

export const EmailCampaignDetails = ({
  campaignId,
}: EmailCampaignDetailsProps) => {
  const router = useHistory();
  const [isUnsaved, setIsUnsaved] = useState(false);
  const [isConfirming, setIsConfirming] = useState(false);
  const [navigatingLocation, setNavigatingLocation] = useState<string | null>(
    null,
  );

  const confirmationModal = useConfirmationModal();
  useUnsavedChangesRedirectionWarning(isUnsaved && !isConfirming);

  const location = useLocation<{
    formValues: Partial<EmailCampaignForm>;
  }>();

  const { data: campaign = {} } = useQuery(
    ["campaigns", campaignId],
    async (): Promise<EmailCampaignForm> => {
      // TODO: ESS_NORMALIZE: ensure SMS has the same SDK route layout
      const result = await getCampaignSDK().getOne(
        campaignId || "",
        CampaignType.EMAIL,
      );

      if (!result.scheduledTimestamp)
        return {
          ...EMAIL_CAMPAIGN_DEFAULT_FORM_VALUES,
          ...result,
        };

      const m = moment.tz(result.scheduledTimestamp, result.scheduledTimezone);

      const date = m.clone().startOf("day");
      const hour = Number(m.format("h"));
      const minute = Number(m.minute());
      const period = m.hour() >= 12 ? "PM" : "AM";

      const localDate = new Date(date.year(), date.month(), date.date());

      return {
        ...EMAIL_CAMPAIGN_DEFAULT_FORM_VALUES,
        ...result,
        scheduledDate: localDate,
        scheduledHour: hour,
        scheduledMinute: minute,
        scheduledPeriod: period.toString(),
      };
    },
    {
      cacheTime: 0,
      refetchOnWindowFocus: false,
      enabled: Boolean(campaignId),
    },
  );

  const formState = {
    ...EMAIL_CAMPAIGN_DEFAULT_FORM_VALUES,
    ...prune(campaign),
    ...prune(location.state?.formValues || {}),
  };

  const modifyCampaign = useMutation(
    async (formValues: Partial<EmailCampaignForm>) => {
      const payload = formToPayload(formValues);

      campaignId
        ? await getCampaignSDK().email.updateOne(campaignId, payload)
        : await getCampaignSDK().email.createOne(payload);
    },
    {
      onSuccess: () => router.push(campaignsUrl, { state: campaign }),
    },
  );

  const renderConfirmationModal = () => {
    setIsConfirming(true);

    confirmationModal.open({
      className: "confirmation-modal-campaign-update",
      title: "Are you sure you want to leave this page?",
      description: "Any changes made to this campaign will be lost.",
      onConfirm: () => {
        setIsUnsaved(false);
      },
      onCancel: () => {
        setIsConfirming(false);
      },
      buttons: [
        {
          label: "Leave",
          action: "confirm",
          variant: "primary",
        },
        {
          label: "Cancel",
          action: "cancel",
          variant: "secondary",
        },
      ],
    });
  };

  const handleUnsavedChanges = (value: boolean) => {
    setIsUnsaved(value);
  };

  const handleBlockedNavigation = (nextLocation: Location<unknown>) => {
    if (isUnsaved) {
      setNavigatingLocation(nextLocation.pathname);
      renderConfirmationModal();
    }
    // Allow navigation if there are no unsaved changes
    return !isUnsaved;
  };

  useEffect(() => {
    if (!isUnsaved && navigatingLocation) {
      // Navigate to the previous blocked location with your navigate function
      window.location.href = navigatingLocation;
    }
  }, [isUnsaved, navigatingLocation]);

  return (
    <div className="create-campaign">
      <Prompt when={isUnsaved} message={handleBlockedNavigation} />
      <CampaignPageHeader
        name={campaignId && campaign ? formState.name : "New Campaign"}
        onBackClick={() => router.push(campaignsUrl)}
        status={CampaignStatuses.DRAFT}
      />
      {campaign && (
        <CampaignForm
          initialValues={formState}
          onSubmit={async (formValues) => {
            await modifyCampaign.mutateAsync(formValues);
          }}
          isLoading={modifyCampaign.isLoading}
          campaignId={campaignId}
          handleUnsavedChanges={handleUnsavedChanges}
        />
      )}
    </div>
  );
};

export default EmailCampaignDetails;
