import React, { useMemo } from "react";
import {
  useConfirmationModal,
  Pagination,
  EmptyStateWithButton,
  Paginate,
} from "@komi-app/components";

import { services } from "services";
import {
  Segment,
  SegmentMode,
  SegmentItemAction,
  SegmentDeleteError,
} from "@komi-app/fans-sdk";

import { useHistory } from "react-router-dom";
import { createSegmentUrl } from "utils/dca/segments";
import { createNewCampaignWithSegment } from "utils/dca/campaigns";
import notification from "utils/notification";

import "./SegmentsTable.scss";
import { useSegmentsList } from "../Utils";
import { FLAGS, useFeatureIsOn } from "@komi-app/flags-sdk";
import { SegmentItemSkeleton } from "../SegmentQueryBuilderPage/BuilderPage/Segment/SegmentItemSkeleton";
import {
  SegmentItemWithCount,
  SegmentItemWithoutCount,
} from "../SegmentQueryBuilderPage/BuilderPage/Segment/SegmentItem";

export interface SegmentListProps {
  searchTerm?: string;
  onSegmentCreateClick: () => any;
}

const SegmentsTable = ({
  searchTerm = "",
  onSegmentCreateClick,
}: SegmentListProps) => {
  const {
    data,
    isLoading,
    currentPageIndex,
    changePageIndex,
    pageCount,
    reset,
  } = useSegmentsList(searchTerm);

  const router = useHistory();
  const confirmDeleteModal = useConfirmationModal();

  const showConfirmDeleteModal = (segment: Segment) => {
    confirmDeleteModal.open({
      title: "Are you sure you want to delete this segment?",
      description: `This segment will be deleted and you can’t undo this action.`,
      className: "segments-page__modal",
      onConfirm: () => deleteSegment(segment),
      buttons: [
        {
          label: "No thanks",
          action: "cancel",
          variant: "primary",
        },
        {
          label: "Delete",
          action: "confirm",
          variant: "secondary",
        },
      ],
    });
  };

  const onActionItemClick = (action: string, segment: Segment) => {
    switch (action) {
      case SegmentItemAction.DELETE:
        return showConfirmDeleteModal(segment);

      case SegmentItemAction.EDIT:
        return editSegment(segment);

      case SegmentItemAction.SEND:
        return createCampaign(segment);

      case SegmentItemAction.EXPORT:
        return;
    }
  };

  const getSegmentCount = async (segment: Segment) => {
    const segmentName = encodeURIComponent(segment.name);

    const segmentExists = await services.segment().exists(segmentName);
    if (!segmentExists) {
      return 0;
    }

    const count =
      (await services.segment().countSegmentQueryById(segment.segmentId)) || 0;
    return count;
  };

  /**
   * Deletes a single segment
   * First checks if any campaigns are associated with the segment
   * if yes, then it will not delete the segment
   * @param deletedSegment
   * @returns void
   */
  const deleteSegment = async (deletedSegment: Segment) => {
    try {
      await services.segment().deleteSegment(deletedSegment.segmentId);
      await reset();

      notification.success({
        message: `Your segment ${deletedSegment.name} has been deleted.`,
      });
    } catch (error) {
      if (error instanceof SegmentDeleteError) {
        if (error.status === 409) {
          notification.error({
            message: `The segment is currently being used by campaigns and cannot be deleted.`,
          });
          return;
        }
      }

      notification.error({
        message: `Unable to delete segment.`,
      });
    }
  };
  const editSegment = ({ segmentId }: Segment) => {
    router.push(createSegmentUrl({ mode: SegmentMode.Edit, segmentId }));
  };

  const createCampaign = (segment: Segment) => {
    // TODO: integrate campaigns
    router.push(createNewCampaignWithSegment(segment.segmentId));
  };

  const skeletonItems = useMemo(
    () =>
      Array.from({ length: 10 }, (_, index) => (
        <SegmentItemSkeleton
          key={index}
          className="segment-table__item-skeleton"
        />
      )),
    [],
  );

  return (
    <div className="segment-table-container">
      <div className="segment-table">
        {isLoading ? (
          skeletonItems
        ) : data.length === 0 ? (
          <EmptyStateWithButton
            className="segment-list__empty-state"
            buttonLabel="Create New Segment"
            onButtonClick={onSegmentCreateClick}
          />
        ) : (
          data.map((segment, index) => (
            <SegmentItemWithoutCount
              key={index}
              segment={segment}
              getContactsCount={getSegmentCount}
              onActionItemClick={onActionItemClick}
              onNameClick={() => editSegment(segment)}
            />
          ))
        )}

        {searchTerm && !isLoading && data.length === 0 && (
          <div className="no-results-box">
            <span>No results matching &quot;{searchTerm}&quot;</span>
          </div>
        )}
      </div>

      <div className="komi-pagination">
        <Paginate
          initialPage={currentPageIndex}
          pageCount={pageCount}
          onPageChange={({ selected }) => changePageIndex(selected)}
          pageRangeDisplayed={5}
          marginPagesDisplayed={1}
        />
      </div>
    </div>
  );
};

export default SegmentsTable;
