import React from "react";

import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";

import { mutate } from "swr";

// services
import cyclesService from "services/cycles.service";
// hooks
import useToast from "hooks/use-toast";
// ui
import { CustomMenu, LinearProgressIndicator, Tooltip } from "components/ui";
import { Disclosure, Transition } from "@headlessui/react";
// icons
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
import { TargetIcon } from "components/icons";
import {
  ChevronDownIcon,
  LinkIcon,
  PencilIcon,
  StarIcon,
  TrashIcon,
} from "@heroicons/react/24/outline";
// helpers
import { getDateRangeStatus, renderShortDateWithYearFormat } from "helpers/date-time.helper";
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
// types
import {
  CompletedCyclesResponse,
  CurrentAndUpcomingCyclesResponse,
  DraftCyclesResponse,
  ICycle,
} from "types";
// fetch-keys
import {
  CYCLE_COMPLETE_LIST,
  CYCLE_CURRENT_AND_UPCOMING_LIST,
  CYCLE_DRAFT_LIST,
} from "constants/fetch-keys";

type TSingleStatProps = {
  cycle: ICycle;
  handleEditCycle: () => void;
  handleDeleteCycle: () => void;
  isCompleted?: boolean;
};

const stateGroups = [
  {
    key: "backlog_issues",
    title: "Backlog",
    color: "#dee2e6",
  },
  {
    key: "unstarted_issues",
    title: "Unstarted",
    color: "#26b5ce",
  },
  {
    key: "started_issues",
    title: "Started",
    color: "#f7ae59",
  },
  {
    key: "cancelled_issues",
    title: "Cancelled",
    color: "#d687ff",
  },
  {
    key: "completed_issues",
    title: "Completed",
    color: "#09a953",
  },
];

export const SingleCycleCard: React.FC<TSingleStatProps> = ({
  cycle,
  handleEditCycle,
  handleDeleteCycle,
  isCompleted = false,
}) => {
  const router = useRouter();
  const { workspaceSlug, projectId } = router.query;

  const { setToastAlert } = useToast();

  const endDate = new Date(cycle.end_date ?? "");
  const startDate = new Date(cycle.start_date ?? "");

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

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

    switch (cycleStatus) {
      case "current":
      case "upcoming":
        mutate<CurrentAndUpcomingCyclesResponse>(
          CYCLE_CURRENT_AND_UPCOMING_LIST(projectId as string),
          (prevData) => ({
            current_cycle: (prevData?.current_cycle ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? true : c.is_favorite,
            })),
            upcoming_cycle: (prevData?.upcoming_cycle ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? true : c.is_favorite,
            })),
          }),
          false
        );
        break;
      case "completed":
        mutate<CompletedCyclesResponse>(
          CYCLE_COMPLETE_LIST(projectId as string),
          (prevData) => ({
            completed_cycles: (prevData?.completed_cycles ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? true : c.is_favorite,
            })),
          }),
          false
        );
        break;
      case "draft":
        mutate<DraftCyclesResponse>(
          CYCLE_DRAFT_LIST(projectId as string),
          (prevData) => ({
            draft_cycles: (prevData?.draft_cycles ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? true : c.is_favorite,
            })),
          }),
          false
        );
        break;
    }

    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 = () => {
    if (!workspaceSlug || !projectId || !cycle) return;

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

    switch (cycleStatus) {
      case "current":
      case "upcoming":
        mutate<CurrentAndUpcomingCyclesResponse>(
          CYCLE_CURRENT_AND_UPCOMING_LIST(projectId as string),
          (prevData) => ({
            current_cycle: (prevData?.current_cycle ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? false : c.is_favorite,
            })),
            upcoming_cycle: (prevData?.upcoming_cycle ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? false : c.is_favorite,
            })),
          }),
          false
        );
        break;
      case "completed":
        mutate<CompletedCyclesResponse>(
          CYCLE_COMPLETE_LIST(projectId as string),
          (prevData) => ({
            completed_cycles: (prevData?.completed_cycles ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? false : c.is_favorite,
            })),
          }),
          false
        );
        break;
      case "draft":
        mutate<DraftCyclesResponse>(
          CYCLE_DRAFT_LIST(projectId as string),
          (prevData) => ({
            draft_cycles: (prevData?.draft_cycles ?? []).map((c) => ({
              ...c,
              is_favorite: c.id === cycle.id ? false : c.is_favorite,
            })),
          }),
          false
        );
        break;
    }

    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.",
        });
      });
  };

  const handleCopyText = () => {
    const originURL =
      typeof window !== "undefined" && window.location.origin ? window.location.origin : "";

    copyTextToClipboard(
      `${originURL}/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`
    ).then(() => {
      setToastAlert({
        type: "success",
        title: "Link Copied!",
        message: "Cycle link copied to clipboard.",
      });
    });
  };

  const progressIndicatorData = stateGroups.map((group, index) => ({
    id: index,
    name: group.title,
    value:
      cycle.total_issues > 0
        ? ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100
        : 0,
    color: group.color,
  }));

  return (
    <div>
      <div className="flex flex-col rounded-[10px] bg-white text-xs shadow">
        <Link href={`/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`}>
          <a className="w-full">
            <div className="flex h-full flex-col gap-4 rounded-b-[10px] p-4">
              <div className="flex items-start justify-between gap-1">
                <Tooltip tooltipContent={cycle.name} position="top-left">
                  <h3 className="break-all text-lg font-semibold">
                    {truncateText(cycle.name, 75)}
                  </h3>
                </Tooltip>
                {cycle.is_favorite ? (
                  <button
                    onClick={(e) => {
                      e.preventDefault();
                      handleRemoveFromFavorites();
                    }}
                  >
                    <StarIcon className="h-4 w-4 text-orange-400" fill="#f6ad55" />
                  </button>
                ) : (
                  <button
                    onClick={(e) => {
                      e.preventDefault();
                      handleAddToFavorites();
                    }}
                  >
                    <StarIcon className="h-4 w-4 " color="#858E96" />
                  </button>
                )}
              </div>

              <div className="flex items-center justify-start gap-5">
                <div className="flex items-start gap-1 ">
                  <CalendarDaysIcon className="h-4 w-4 text-gray-900" />
                  <span className="text-gray-400">Start :</span>
                  <span>{renderShortDateWithYearFormat(startDate)}</span>
                </div>
                <div className="flex items-start gap-1 ">
                  <TargetIcon className="h-4 w-4 text-gray-900" />
                  <span className="text-gray-400">End :</span>
                  <span>{renderShortDateWithYearFormat(endDate)}</span>
                </div>
              </div>

              <div className="flex items-center justify-between mt-4">
                <div className="flex items-center gap-2.5">
                  {cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
                    <Image
                      src={cycle.owned_by.avatar}
                      height={16}
                      width={16}
                      className="rounded-full"
                      alt={cycle.owned_by.first_name}
                    />
                  ) : (
                    <span className="flex h-5 w-5 items-center justify-center rounded-full bg-gray-800 capitalize  text-white">
                      {cycle.owned_by.first_name.charAt(0)}
                    </span>
                  )}
                  <span className="text-gray-900">{cycle.owned_by.first_name}</span>
                </div>
                <div className="flex items-center">
                  {!isCompleted && (
                    <button
                      onClick={(e) => {
                        e.preventDefault();
                        handleEditCycle();
                      }}
                      className="flex cursor-pointer items-center rounded p-1 duration-300 hover:bg-gray-100"
                    >
                      <span>
                        <PencilIcon className="h-4 w-4" />
                      </span>
                    </button>
                  )}

                  <CustomMenu width="auto" verticalEllipsis>
                    {!isCompleted && (
                      <CustomMenu.MenuItem
                        onClick={(e) => {
                          e.preventDefault();
                          handleDeleteCycle();
                        }}
                      >
                        <span className="flex items-center justify-start gap-2">
                          <TrashIcon className="h-4 w-4" />
                          <span>Delete cycle</span>
                        </span>
                      </CustomMenu.MenuItem>
                    )}
                    <CustomMenu.MenuItem
                      onClick={(e) => {
                        e.preventDefault();
                        handleCopyText();
                      }}
                    >
                      <span className="flex items-center justify-start gap-2">
                        <LinkIcon className="h-4 w-4" />
                        <span>Copy cycle link</span>
                      </span>
                    </CustomMenu.MenuItem>
                  </CustomMenu>
                </div>
              </div>
            </div>
          </a>
        </Link>

        <div className="flex h-full flex-col rounded-b-[10px]">
          <Disclosure>
            {({ open }) => (
              <div
                className={`flex h-full w-full flex-col border-t border-gray-200 bg-gray-100 ${
                  open ? "" : "flex-row"
                }`}
              >
                <div className="flex w-full items-center gap-2 px-4 py-1">
                  <span>Progress</span>
                  <LinearProgressIndicator data={progressIndicatorData} />
                  <Disclosure.Button>
                    <span className="p-1">
                      <ChevronDownIcon
                        className={`h-3 w-3 ${open ? "rotate-180 transform" : ""}`}
                        aria-hidden="true"
                      />
                    </span>
                  </Disclosure.Button>
                </div>
                <Transition show={open}>
                  <Disclosure.Panel>
                    <div className="overflow-hidden rounded-b-md bg-white py-3 shadow">
                      <div className="col-span-2 space-y-3 px-4">
                        <div className="space-y-3 text-xs">
                          {stateGroups.map((group) => (
                            <div
                              key={group.key}
                              className="flex items-center justify-between gap-2"
                            >
                              <div className="flex  items-center gap-2">
                                <span
                                  className="block h-2 w-2 rounded-full"
                                  style={{
                                    backgroundColor: group.color,
                                  }}
                                />
                                <h6 className="text-xs">{group.title}</h6>
                              </div>
                              <div>
                                <span>
                                  {cycle[group.key as keyof ICycle] as number}{" "}
                                  <span className="text-gray-500">
                                    -{" "}
                                    {cycle.total_issues > 0
                                      ? `${Math.round(
                                          ((cycle[group.key as keyof ICycle] as number) /
                                            cycle.total_issues) *
                                            100
                                        )}%`
                                      : "0%"}
                                  </span>
                                </span>
                              </div>
                            </div>
                          ))}
                        </div>
                      </div>
                    </div>
                  </Disclosure.Panel>
                </Transition>
              </div>
            )}
          </Disclosure>
        </div>
      </div>
    </div>
  );
};