import React, { useState } from "react";

import { useRouter } from "next/router";

import { mutate } from "swr";

// services
import cyclesService from "services/cycles.service";
// hooks
import useToast from "hooks/use-toast";
import useUserAuth from "hooks/use-user-auth";
// components
import {
  CreateUpdateCycleModal,
  CyclesListGanttChartView,
  DeleteCycleModal,
  SingleCycleCard,
  SingleCycleList,
} from "components/cycles";
// ui
import { EmptyState, Loader } from "components/ui";
// images
import emptyCycle from "public/empty-state/empty-cycle.svg";
// helpers
import { getDateRangeStatus } from "helpers/date-time.helper";
// types
import { ICycle } from "types";
// fetch-keys
import {
  COMPLETED_CYCLES_LIST,
  CURRENT_CYCLE_LIST,
  CYCLES_LIST,
  DRAFT_CYCLES_LIST,
  UPCOMING_CYCLES_LIST,
} from "constants/fetch-keys";

type Props = {
  cycles: ICycle[] | undefined;
  viewType: string | null;
};

export const CyclesView: React.FC<Props> = ({ cycles, viewType }) => {
  const [createUpdateCycleModal, setCreateUpdateCycleModal] = useState(false);
  const [selectedCycleToUpdate, setSelectedCycleToUpdate] = useState<ICycle | null>(null);

  const [deleteCycleModal, setDeleteCycleModal] = useState(false);
  const [selectedCycleToDelete, setSelectedCycleToDelete] = useState<ICycle | null>(null);

  const router = useRouter();
  const { workspaceSlug, projectId } = router.query;

  const { user } = useUserAuth();
  const { setToastAlert } = useToast();

  const handleEditCycle = (cycle: ICycle) => {
    setSelectedCycleToUpdate(cycle);
    setCreateUpdateCycleModal(true);
  };

  const handleDeleteCycle = (cycle: ICycle) => {
    setSelectedCycleToDelete(cycle);
    setDeleteCycleModal(true);
  };

  const handleAddToFavorites = (cycle: ICycle) => {
    if (!workspaceSlug || !projectId) return;

    const cycleStatus = getDateRangeStatus(cycle.start_date, cycle.end_date);

    const fetchKey =
      cycleStatus === "current"
        ? CURRENT_CYCLE_LIST(projectId as string)
        : cycleStatus === "upcoming"
        ? UPCOMING_CYCLES_LIST(projectId as string)
        : cycleStatus === "completed"
        ? COMPLETED_CYCLES_LIST(projectId as string)
        : DRAFT_CYCLES_LIST(projectId as string);

    mutate<ICycle[]>(
      fetchKey,
      (prevData) =>
        (prevData ?? []).map((c) => ({
          ...c,
          is_favorite: c.id === cycle.id ? true : c.is_favorite,
        })),
      false
    );

    mutate(
      CYCLES_LIST(projectId as string),
      (prevData: any) =>
        (prevData ?? []).map((c: any) => ({
          ...c,
          is_favorite: c.id === cycle.id ? true : c.is_favorite,
        })),
      false
    );

    cyclesService
      .addCycleToFavorites(workspaceSlug as string, projectId as string, {
        cycle: cycle.id,
      })
      .catch(() => {
        setToastAlert({
          type: "error",
          title: "Error!",
          message: "Couldn't add the cycle to favorites. Please try again.",
        });
      });
  };

  const handleRemoveFromFavorites = (cycle: ICycle) => {
    if (!workspaceSlug || !projectId) return;

    const cycleStatus = getDateRangeStatus(cycle.start_date, cycle.end_date);

    const fetchKey =
      cycleStatus === "current"
        ? CURRENT_CYCLE_LIST(projectId as string)
        : cycleStatus === "upcoming"
        ? UPCOMING_CYCLES_LIST(projectId as string)
        : cycleStatus === "completed"
        ? COMPLETED_CYCLES_LIST(projectId as string)
        : DRAFT_CYCLES_LIST(projectId as string);

    mutate<ICycle[]>(
      fetchKey,
      (prevData) =>
        (prevData ?? []).map((c) => ({
          ...c,
          is_favorite: c.id === cycle.id ? false : c.is_favorite,
        })),
      false
    );

    mutate(
      CYCLES_LIST(projectId as string),
      (prevData: any) =>
        (prevData ?? []).map((c: any) => ({
          ...c,
          is_favorite: c.id === cycle.id ? false : c.is_favorite,
        })),
      false
    );

    cyclesService
      .removeCycleFromFavorites(workspaceSlug as string, projectId as string, cycle.id)
      .catch(() => {
        setToastAlert({
          type: "error",
          title: "Error!",
          message: "Couldn't remove the cycle from favorites. Please try again.",
        });
      });
  };

  return (
    <>
      <CreateUpdateCycleModal
        isOpen={createUpdateCycleModal}
        handleClose={() => setCreateUpdateCycleModal(false)}
        data={selectedCycleToUpdate}
        user={user}
      />
      <DeleteCycleModal
        isOpen={deleteCycleModal}
        setIsOpen={setDeleteCycleModal}
        data={selectedCycleToDelete}
        user={user}
      />
      {cycles ? (
        cycles.length > 0 ? (
          viewType === "list" ? (
            <div className="divide-y divide-brand-base">
              {cycles.map((cycle) => (
                <div className="hover:bg-brand-surface-2">
                  <div className="flex flex-col border-brand-base">
                    <SingleCycleList
                      key={cycle.id}
                      cycle={cycle}
                      handleDeleteCycle={() => handleDeleteCycle(cycle)}
                      handleEditCycle={() => handleEditCycle(cycle)}
                      handleAddToFavorites={() => handleAddToFavorites(cycle)}
                      handleRemoveFromFavorites={() => handleRemoveFromFavorites(cycle)}
                    />
                  </div>
                </div>
              ))}
            </div>
          ) : viewType === "board" ? (
            <div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
              {cycles.map((cycle) => (
                <SingleCycleCard
                  key={cycle.id}
                  cycle={cycle}
                  handleDeleteCycle={() => handleDeleteCycle(cycle)}
                  handleEditCycle={() => handleEditCycle(cycle)}
                  handleAddToFavorites={() => handleAddToFavorites(cycle)}
                  handleRemoveFromFavorites={() => handleRemoveFromFavorites(cycle)}
                />
              ))}
            </div>
          ) : (
            <CyclesListGanttChartView cycles={cycles ?? []} />
          )
        ) : (
          <EmptyState
            type="cycle"
            title="Create New Cycle"
            description="Sprint more effectively with Cycles by confining your project to a fixed amount of time. Create new cycle now."
            imgURL={emptyCycle}
          />
        )
      ) : viewType === "list" ? (
        <Loader className="space-y-4">
          <Loader.Item height="50px" />
          <Loader.Item height="50px" />
          <Loader.Item height="50px" />
        </Loader>
      ) : viewType === "board" ? (
        <Loader className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
          <Loader.Item height="200px" />
          <Loader.Item height="200px" />
          <Loader.Item height="200px" />
        </Loader>
      ) : (
        <Loader>
          <Loader.Item height="300px" />
        </Loader>
      )}
    </>
  );
};