import StatusPagesElement from "../../Components/StatusPage/StatusPagesElement";
import PageComponentProps from "../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import SubscriberNotificationStatus from "../../Components/StatusPageSubscribers/SubscriberNotificationStatus";
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import StatusPageAnnouncement from "Common/Models/DatabaseModels/StatusPageAnnouncement";
import StatusPage from "Common/Models/DatabaseModels/StatusPage";
import Monitor from "Common/Models/DatabaseModels/Monitor";
import StatusPageSubscriberNotificationStatus from "Common/Types/StatusPage/StatusPageSubscriberNotificationStatus";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import React, {
  Fragment,
  FunctionComponent,
  ReactElement,
  useState,
} from "react";
import MarkdownUtil from "Common/UI/Utils/Markdown";
import { ModalWidth } from "Common/UI/Components/Modal/Modal";
import AttachmentList from "../../Components/Attachment/AttachmentList";
import { getModelIdString } from "../../Utils/ModelId";

const AnnouncementView: FunctionComponent<
  PageComponentProps
> = (): ReactElement => {
  const modelId: ObjectID = Navigation.getLastParamAsObjectID();
  const [refreshToggle, setRefreshToggle] = useState<boolean>(false);

  const handleResendNotification: () => Promise<void> =
    async (): Promise<void> => {
      try {
        // Reset the notification status to Pending so the worker can pick it up again
        await ModelAPI.updateById({
          id: modelId,
          modelType: StatusPageAnnouncement,
          data: {
            subscriberNotificationStatus:
              StatusPageSubscriberNotificationStatus.Pending,
            subscriberNotificationStatusMessage:
              "Notification queued for resending",
          },
        });

        // Trigger a refresh by toggling the refresh state
        setRefreshToggle(!refreshToggle);
      } catch {
        // Error resending notification: handle appropriately
      }
    };

  return (
    <Fragment>
      {/* Status Page Announcement View  */}
      <CardModelDetail<StatusPageAnnouncement>
        name="Status Page Announcement Details"
        cardProps={{
          title: "Status Page Announcement Details",
          description: "Here are more details for this announcement.",
        }}
        createEditModalWidth={ModalWidth.Large}
        formSteps={[
          {
            title: "Basic Information",
            id: "basic",
          },
          {
            title: "Status Pages",
            id: "status-pages",
          },
          {
            title: "Resources Affected",
            id: "resources-affected",
          },
          {
            title: "Schedule & Settings",
            id: "more",
          },
        ]}
        isEditable={true}
        formFields={[
          {
            field: {
              title: true,
            },
            stepId: "basic",
            title: "Announcement Title",
            fieldType: FormFieldSchemaType.Text,
            required: true,
            placeholder: "Announcement Title",
            validation: {
              minLength: 2,
            },
          },
          {
            field: {
              description: true,
            },
            title: "Description",
            stepId: "basic",
            fieldType: FormFieldSchemaType.Markdown,
            required: false,
            description: MarkdownUtil.getMarkdownCheatsheet(
              "Add an announcement note",
            ),
          },
          {
            field: {
              attachments: true,
            },
            title: "Attachments",
            stepId: "basic",
            fieldType: FormFieldSchemaType.MultipleFiles,
            required: false,
            description:
              "Attach files that should be available with this announcement on the status page.",
          },
          {
            field: {
              statusPages: true,
            },
            title: "Show announcement on these status pages",
            stepId: "status-pages",
            description: "Select status pages to show this announcement on",
            fieldType: FormFieldSchemaType.MultiSelectDropdown,
            dropdownModal: {
              type: StatusPage,
              labelField: "name",
              valueField: "_id",
            },
            required: true,
            placeholder: "Select Status Pages",
          },
          {
            field: {
              monitors: true,
            },
            title: "Monitors affected (Optional)",
            stepId: "resources-affected",
            description:
              "Select monitors affected by this announcement. If none selected, all subscribers will be notified.",
            fieldType: FormFieldSchemaType.MultiSelectDropdown,
            dropdownModal: {
              type: Monitor,
              labelField: "name",
              valueField: "_id",
            },
            required: false,
            placeholder: "Select Monitors (Optional)",
          },
          {
            field: {
              showAnnouncementAt: true,
            },
            stepId: "more",
            title: "Start Showing Announcement At",
            fieldType: FormFieldSchemaType.DateTime,
            required: true,
            placeholder: "Pick Date and Time",
          },
          {
            field: {
              endAnnouncementAt: true,
            },
            stepId: "more",
            title: "End Showing Announcement At",
            fieldType: FormFieldSchemaType.DateTime,
            required: false,
            placeholder: "Pick Date and Time",
          },
          {
            field: {
              shouldStatusPageSubscribersBeNotified: true,
            },
            title: "Notify Status Page Subscribers",
            stepId: "more",
            description: "Should status page subscribers be notified?",
            fieldType: FormFieldSchemaType.Checkbox,
            required: false,
          },
        ]}
        modelDetailProps={{
          showDetailsInNumberOfColumns: 2,
          modelType: StatusPageAnnouncement,
          id: "model-detail-status-page-announcement",
          selectMoreFields: {
            subscriberNotificationStatusMessage: true,
          },
          fields: [
            {
              field: {
                _id: true,
              },
              title: "Announcement ID",
              fieldType: FieldType.ObjectID,
            },
            {
              field: {
                title: true,
              },
              title: "Title",
              fieldType: FieldType.Text,
            },
            {
              field: {
                statusPages: {
                  name: true,
                  _id: true,
                },
              },
              title: "Shown on Status Pages",
              fieldType: FieldType.Element,
              getElement: (item: StatusPageAnnouncement): ReactElement => {
                return (
                  <StatusPagesElement statusPages={item.statusPages || []} />
                );
              },
            },
            {
              field: {
                showAnnouncementAt: true,
              },
              title: "Show Announcement At",
              fieldType: FieldType.DateTime,
            },
            {
              field: {
                endAnnouncementAt: true,
              },
              title: "End Announcement At",
              fieldType: FieldType.DateTime,
            },
            {
              field: {
                subscriberNotificationStatus: true,
              },
              title: "Subscriber Notification Status",
              fieldType: FieldType.Element,
              getElement: (item: StatusPageAnnouncement): ReactElement => {
                return (
                  <SubscriberNotificationStatus
                    status={item.subscriberNotificationStatus}
                    subscriberNotificationStatusMessage={
                      item.subscriberNotificationStatusMessage
                    }
                    onResendNotification={handleResendNotification}
                  />
                );
              },
            },
            {
              field: {
                createdAt: true,
              },
              title: "Created",
              fieldType: FieldType.DateTime,
            },
            {
              field: {
                updatedAt: true,
              },
              title: "Updated",
              fieldType: FieldType.DateTime,
            },
          ],
          modelId: modelId,
        }}
      />
      <div className="mt-4"></div>
      <CardModelDetail<StatusPageAnnouncement>
        name="Status Page Announcement Content"
        cardProps={{
          title: "Announcement Content",
          description:
            "Rich-text description and any attachments shared with subscribers.",
        }}
        isEditable={false}
        modelDetailProps={{
          showDetailsInNumberOfColumns: 1,
          modelType: StatusPageAnnouncement,
          id: "model-detail-status-page-announcement-content",
          selectMoreFields: {
            attachments: {
              _id: true,
              name: true,
            },
          },
          fields: [
            {
              field: {
                description: true,
              },
              title: "Description",
              fieldType: FieldType.Markdown,
            },
            {
              field: {
                attachments: {
                  _id: true,
                  name: true,
                },
              },
              title: "Attachments",
              fieldType: FieldType.Element,
              getElement: (item: StatusPageAnnouncement): ReactElement => {
                const modelIdString: string | null = getModelIdString(item);

                if (!modelIdString || !item.attachments?.length) {
                  return <></>;
                }

                return (
                  <AttachmentList
                    modelId={modelIdString}
                    attachments={item.attachments}
                    attachmentApiPath="/status-page-announcement/attachment"
                  />
                );
              },
            },
          ],
          modelId: modelId,
        }}
      />
      <div className="mt-4"></div>
    </Fragment>
  );
};

export default AnnouncementView;
