import { useState, useEffect } from "react";
import { useNotificationContext } from "./../context/NotificationContext";
import {
  Modal,
  Button,
  SelectControl,
  TextControl,
  CheckboxControl,
  RadioControl,
  PanelBody,
  Panel,
} from "@wordpress/components";

// import { ReactComponent as PreviewEmailHeader } from "./../assets/preview-icon.svg";

function generateDisconnectURL(platform) {
  const finalURL = new URL(window.location);
  finalURL.searchParams.set(`monitori_disconnect_${platform}`, 1);
  return finalURL;
}

function SlackFields({ data = {} }) {
  if (data?.type === "channel") {
    return (
      <p>
        Sending messages to {data?.channel}{" "}
        <a href={generateDisconnectURL("slack")}>Disconnect</a>
      </p>
    );
  }

  if (data?.type === "connect") {
    return (
      <p>
        Slack is not connected <a href={data?.oauth_url}>Connect</a>
      </p>
    );
  }

  return "";
}

function DiscordFields({ data = {}, selectedDiscordChannel = "", onChange }) {
  if (data?.type === "select") {
    const discordChannels = data?.options
      ? data.options.map((item) => {
          return { label: item.label, value: item.id };
        })
      : [];

    return (
      <>
        <p>
          Discord connected{" "}
          <a href={generateDisconnectURL("discord")}>Disconnect</a>
        </p>
        <SelectControl
          label="Discord channels to use"
          value={selectedDiscordChannel}
          required
          options={[
            { label: "Please select a channel", value: "" },
            ...discordChannels,
          ]}
          onChange={onChange}
        />
      </>
    );
  }

  if (data?.type === "connect") {
    return (
      <p>
        Discord is not connected <a href={data?.oauth_url}>Connect</a>
      </p>
    );
  }

  return "";
}

export default function AddEditModal() {
  const {
    isModalOpen,
    closeModal,
    fetchNotifications,
    addNewNotification,
    updateNotification,
    postToEdit,
    getNotification,
    fieldData,
  } = useNotificationContext();

  const defaultNotificationState = {
    name: "",
    notificationType: "event",
    eventType: "",
    metricName: "",
    changeType: "",
    metricValue: "",
    timePeriod: "",
    comparePeriod: "",
    deliveryChannels: {
      email: { enabled: false, recipient: "" },
      slack: { enabled: false },
      discord: { enabled: false },
    },
  };

  if (postToEdit) {
    let currentNotfication = getNotification(postToEdit);

    defaultNotificationState.name = currentNotfication.name;
    defaultNotificationState.notificationType =
      currentNotfication.notification_type;
    defaultNotificationState.eventType = currentNotfication.event_type;
    defaultNotificationState.changeType = currentNotfication.change_type;
    defaultNotificationState.metricValue = currentNotfication.metric_value;
    defaultNotificationState.metricName = currentNotfication.metric_name;
    defaultNotificationState.timePeriod = currentNotfication.time_period;
    defaultNotificationState.comparePeriod = currentNotfication.compare_period;
    defaultNotificationState.deliveryChannels =
      currentNotfication?.delivery_channels
        ? JSON.parse(currentNotfication.delivery_channels)
        : defaultNotificationState.deliveryChannels;
  }

  const [notificationData, setNotificationData] = useState(
    defaultNotificationState
  );

  // Update top-level fields
  const updateField = (field, value) => {
    setNotificationData((prev) => ({
      ...prev,
      [field]: value,
    }));
  };

  // Update nested deliveryChannels fields
  const updateDeliveryChannel = (channel, field, value) => {
    setNotificationData((prev) => ({
      ...prev,
      deliveryChannels: {
        ...prev.deliveryChannels,
        [channel]: {
          ...prev.deliveryChannels[channel],
          [field]: value,
        },
      },
    }));
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (postToEdit) {
      await updateNotification(postToEdit, notificationData);
    } else {
      await addNewNotification(notificationData);
    }
    fetchNotifications();
    closeModal();
  };

  if (!fieldData) return <></>;

  function EventFields() {
    const eventTypeOptions = Object.entries(fieldData.event_types || {}).map(
      ([id, name]) => ({
        label: name,
        value: id,
      })
    );

    return (
      <div className="monitori-form-field">
        <SelectControl
          required
          label="Event Type"
          value={notificationData.eventType}
          options={[
            {
              value: "",
              label: "Select an event type",
            },
            ...eventTypeOptions,
          ]}
          onChange={(value) => updateField("eventType", value)}
        />
      </div>
    );
  }

  function MetricFields() {
    const prepareOptions = (typesObject) => {
      const options = [];

      if (typesObject) {
        Object.entries(typesObject).forEach(([id, name]) => {
          options.push({
            label: name,
            value: id,
          });
        });
      }

      return options;
    };

    const metricTypeOptions = prepareOptions(fieldData.metric_types || {});
    const changeTypeOptions = prepareOptions(fieldData.change_types || {});
    const timePeriodOptions = prepareOptions(fieldData.time_periods || {});
    const compareOptions = prepareOptions(fieldData.compare_periods || {});

    const [metricVal, setMetricVal] = useState(
      notificationData.metricValue || ""
    );

    return (
      <>
        <div className="monitori-form-field">
          <SelectControl
            label="Metric Name"
            required
            value={notificationData.metricName}
            options={[
              {
                value: "",
                label: "Select a metric type",
              },
              ...metricTypeOptions,
            ]}
            onChange={(value) => updateField("metricName", value)}
          />
        </div>

        <div className="monitori-form-field">
          <SelectControl
            required
            label="Change Type"
            value={notificationData.changeType}
            options={[
              { value: "", label: "Select change type" },
              ...changeTypeOptions,
            ]}
            onChange={(value) => updateField("changeType", value)}
          />
        </div>

        <div className="monitori-form-field">
          <TextControl
            required
            label="Metric Value"
            value={metricVal}
            type="number"
            onChange={(value) => setMetricVal(value)}
            onBlur={() => updateField("metricValue", metricVal)}
          />
        </div>

        <div className="monitori-form-field">
          <SelectControl
            required
            label="Time Period"
            value={notificationData.timePeriod}
            options={[
              { value: "", label: "Select a time period" },
              ...timePeriodOptions,
            ]}
            onChange={(value) => updateField("timePeriod", value)}
          />
        </div>

        {notificationData.changeType !== "value_equals_to" &&
          notificationData.changeType !== "" && (
            <div className="monitori-form-field">
              <SelectControl
                required
                label="Compared to"
                value={notificationData.comparePeriod}
                options={[
                  { value: "", label: "Select a period to compare" },
                  ...compareOptions,
                ]}
                onChange={(value) => updateField("comparePeriod", value)}
              />
            </div>
          )}
      </>
    );
  }

  function DeliveryChannels() {
    const discordExists = fieldData?.delivery_channels?.discord?.fields;
    const [recipient, setRecipient] = useState(
      notificationData.deliveryChannels.email.recipient || ""
    );

    return (
      <fieldset>
        <legend style={{ marginBottom: "8px" }}>Delivery Channels</legend>
        <div className="monitori-form-field">
          <CheckboxControl
            label="Enable Email"
            checked={notificationData.deliveryChannels.email.enabled}
            onChange={(checked) =>
              updateDeliveryChannel("email", "enabled", checked)
            }
          />
        </div>

        {notificationData.deliveryChannels.email.enabled && (
          <div className="monitori-form-field">
            <TextControl
              label="Recipient Email"
              value={recipient}
              onBlur={() =>
                updateDeliveryChannel("email", "recipient", recipient)
              }
              onChange={setRecipient}
            />
          </div>
        )}

        <div className="monitori-form-field">
          <CheckboxControl
            label="Enable Slack"
            checked={notificationData.deliveryChannels.slack.enabled}
            onChange={(checked) =>
              updateDeliveryChannel("slack", "enabled", checked)
            }
          />
        </div>

        {notificationData.deliveryChannels.slack.enabled && (
          <SlackFields data={fieldData?.delivery_channels?.slack?.fields} />
        )}

        {discordExists && (
          <div className="monitori-form-field">
            <CheckboxControl
              label="Enable Discord"
              checked={notificationData.deliveryChannels.discord.enabled}
              onChange={(checked) =>
                updateDeliveryChannel("discord", "enabled", checked)
              }
            />
          </div>
        )}

        {notificationData.deliveryChannels.discord.enabled && (
          <DiscordFields
            onChange={(val) => {
              updateDeliveryChannel("discord", "channel", val);
            }}
            data={fieldData?.delivery_channels?.discord?.fields}
            selectedDiscordChannel={
              notificationData.deliveryChannels.discord.channel
            }
          />
        )}
      </fieldset>
    );
  }

  function NotificationPreview() {
    const previewValues = fieldData?.preview_details;
    const hookLabel =
      fieldData?.event_types?.[notificationData.eventType] || "";
    const currentPreviewValues =
      previewValues?.events?.[notificationData.eventType] || {};

    if (!previewValues || !notificationData?.eventType || !hookLabel) return;

    const heading = "Event triggered: " + hookLabel;

    const previewKeys = Object.keys(currentPreviewValues);
    return (
      <div className="monitori-preview monitori-form-field">
        <Panel header={"Preview"}>
          <PanelBody className="monitori-preview__body">
            <div className="monitori-preview__avatar"></div>
            <div>
              <h3>{heading}</h3>
              {previewKeys?.length > 0
                ? previewKeys.map((key, index) => {
                    if (!key) return;
                    if (key === "hook_name") return;
                    return (
                      <p key={key}>
                        <strong>{key}:</strong> {currentPreviewValues[key]}
                      </p>
                    );
                  })
                : ""}
            </div>
          </PanelBody>
        </Panel>
      </div>
    );
  }

  return (
    isModalOpen && (
      <Modal
        title={postToEdit ? "Edit Notification" : "Add Notification"}
        onRequestClose={closeModal}
        size="large"
      >
        <form onSubmit={handleSubmit}>
          <div className="monitori-form-field">
            <TextControl
              required
              label="Notification Name"
              value={notificationData.name}
              onChange={(value) => updateField("name", value)}
            />
          </div>

          <div className="monitori-form-field">
            <RadioControl
              required
              label="Notification Type"
              selected={notificationData.notificationType}
              options={[
                { label: "Event", value: "event" },
                { label: "Metric", value: "metric" },
              ]}
              onChange={(value) => updateField("notificationType", value)}
            />
          </div>

          {notificationData.notificationType === "event" && <EventFields />}

          {notificationData.notificationType === "metric" && <MetricFields />}

          <DeliveryChannels />

          <NotificationPreview />

          <div style={{ marginTop: "8px" }}>
            <Button type="submit" variant="primary">
              Save
            </Button>
            <Button onClick={closeModal} style={{ marginLeft: "10px" }}>
              Cancel
            </Button>
          </div>
        </form>
      </Modal>
    )
  );
}
