import { useEffect } from "react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
import { mutate } from "swr";
// services
// hooks
// components
// ui
import { CalendarDays, Download, RefreshCw } from "lucide-react";
import { Button, LayersIcon, TOAST_TYPE, setToast } from "@plane/ui";
// icons
import { CustomAnalyticsSidebarHeader, CustomAnalyticsSidebarProjectsList } from "components/analytics";
// helpers
// types
// fetch-keys
import { ANALYTICS } from "constants/fetch-keys";
import { cn } from "helpers/common.helper";
import { renderFormattedDate } from "helpers/date-time.helper";
import { useCycle, useModule, useProject, useUser, useWorkspace } from "hooks/store";
import { AnalyticsService } from "services/analytics.service";
import { IAnalyticsParams, IAnalyticsResponse, IExportAnalyticsFormData, IWorkspace } from "@plane/types";

type Props = {
  analytics: IAnalyticsResponse | undefined;
  params: IAnalyticsParams;
  isProjectLevel: boolean;
};

const analyticsService = new AnalyticsService();

export const CustomAnalyticsSidebar: React.FC<Props> = observer((props) => {
  const { analytics, params, isProjectLevel = false } = props;
  // router
  const router = useRouter();
  const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
  // store hooks
  const { currentUser } = useUser();
  const { workspaceProjectIds, getProjectById } = useProject();
  const { getWorkspaceById } = useWorkspace();

  const { fetchCycleDetails, getCycleById } = useCycle();
  const { fetchModuleDetails, getModuleById } = useModule();

  const projectDetails = projectId ? getProjectById(projectId.toString()) ?? undefined : undefined;

  const trackExportAnalytics = () => {
    if (!currentUser) return;

    const eventPayload: any = {
      workspaceSlug: workspaceSlug?.toString(),
      params: {
        x_axis: params.x_axis,
        y_axis: params.y_axis,
        group: params.segment,
        project: params.project,
      },
    };

    if (projectDetails) {
      const workspaceDetails = projectDetails.workspace as IWorkspace;

      eventPayload.workspaceId = workspaceDetails.id;
      eventPayload.workspaceName = workspaceDetails.name;
      eventPayload.projectId = projectDetails.id;
      eventPayload.projectIdentifier = projectDetails.identifier;
      eventPayload.projectName = projectDetails.name;
    }

    if (cycleDetails || moduleDetails) {
      const details = cycleDetails || moduleDetails;

      const currentProjectDetails = getProjectById(details?.project_id || "");
      const currentWorkspaceDetails = getWorkspaceById(details?.workspace_id || "");

      eventPayload.workspaceId = details?.workspace_id;
      eventPayload.workspaceName = currentWorkspaceDetails?.name;
      eventPayload.projectId = details?.project_id;
      eventPayload.projectIdentifier = currentProjectDetails?.identifier;
      eventPayload.projectName = currentProjectDetails?.name;
    }

    if (cycleDetails) {
      eventPayload.cycleId = cycleDetails.id;
      eventPayload.cycleName = cycleDetails.name;
    }

    if (moduleDetails) {
      eventPayload.moduleId = moduleDetails.id;
      eventPayload.moduleName = moduleDetails.name;
    }
  };

  const exportAnalytics = () => {
    if (!workspaceSlug) return;

    const data: IExportAnalyticsFormData = {
      x_axis: params.x_axis,
      y_axis: params.y_axis,
    };

    if (params.segment) data.segment = params.segment;
    if (params.project) data.project = params.project;

    analyticsService
      .exportAnalytics(workspaceSlug.toString(), data)
      .then((res) => {
        setToast({
          type: TOAST_TYPE.SUCCESS,
          title: "Success!",
          message: res.message,
        });

        trackExportAnalytics();
      })
      .catch(() =>
        setToast({
          type: TOAST_TYPE.ERROR,
          title: "Error!",
          message: "There was some error in exporting the analytics. Please try again.",
        })
      );
  };

  const cycleDetails = cycleId ? getCycleById(cycleId.toString()) : undefined;
  const moduleDetails = moduleId ? getModuleById(moduleId.toString()) : undefined;

  // fetch cycle details
  useEffect(() => {
    if (!workspaceSlug || !projectId || !cycleId || cycleDetails) return;

    fetchCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleId.toString());
  }, [cycleId, cycleDetails, fetchCycleDetails, projectId, workspaceSlug]);

  // fetch module details
  useEffect(() => {
    if (!workspaceSlug || !projectId || !moduleId || moduleDetails) return;

    fetchModuleDetails(workspaceSlug.toString(), projectId.toString(), moduleId.toString());
  }, [moduleId, moduleDetails, fetchModuleDetails, projectId, workspaceSlug]);

  const selectedProjects = params.project && params.project.length > 0 ? params.project : workspaceProjectIds;

  return (
    <div
      className={cn(
        "relative flex h-full w-full items-start justify-between gap-2 bg-custom-sidebar-background-100 px-5 py-4",
        !isProjectLevel ? "flex-col" : ""
      )}
    >
      <div className="flex flex-wrap items-center gap-2">
        <div className="flex items-center gap-1 rounded-md bg-custom-background-80 px-3 py-1 text-xs text-custom-text-200">
          <LayersIcon height={14} width={14} />
          {analytics ? analytics.total : "..."}
          <div className={cn(isProjectLevel ? "hidden md:block" : "")}>Issues</div>
        </div>
        {isProjectLevel && (
          <div className="flex items-center gap-1 rounded-md bg-custom-background-80 px-3 py-1 text-xs text-custom-text-200">
            <CalendarDays className="h-3.5 w-3.5" />
            {renderFormattedDate(
              (cycleId
                ? cycleDetails?.created_at
                : moduleId
                  ? moduleDetails?.created_at
                  : projectDetails?.created_at) ?? ""
            )}
          </div>
        )}
      </div>

      <div className={cn("h-full w-full overflow-hidden", isProjectLevel ? "hidden" : "block")}>
        <>
          {!isProjectLevel && selectedProjects && selectedProjects.length > 0 && (
            <CustomAnalyticsSidebarProjectsList projectIds={selectedProjects} />
          )}
          <CustomAnalyticsSidebarHeader />
        </>
      </div>

      <div className="flex flex-wrap items-center justify-end gap-2">
        <Button
          variant="neutral-primary"
          prependIcon={<RefreshCw className="h-3 w-3 md:h-3.5 md:w-3.5" />}
          onClick={() => {
            if (!workspaceSlug) return;

            mutate(ANALYTICS(workspaceSlug.toString(), params));
          }}
        >
          <div className={cn(isProjectLevel ? "hidden md:block" : "")}>Refresh</div>
        </Button>
        <Button variant="primary" prependIcon={<Download className="h-3.5 w-3.5" />} onClick={exportAnalytics}>
          <div className={cn(isProjectLevel ? "hidden md:block" : "")}>Export as CSV</div>
        </Button>
      </div>
    </div>
  );
});