/**
 * Copyright (c) 2023-present Plane Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import { useMemo, useRef, useState } from "react";
import { CalendarDays, MoreHorizontal } from "lucide-react";
import { observer } from "mobx-react";
import { useTranslation } from "@plane/i18n";
import { useOutsideClickDetector } from "@plane/hooks";
import { PriorityIcon, StateGroupIcon } from "@plane/propel/icons";
import type { IIssueDisplayProperties, TIssue } from "@plane/types";
import { Avatar } from "@plane/ui";
import { cn, getFileURL, renderFormattedDate, renderFormattedPayloadDate } from "@plane/utils";
import { DateDropdown } from "@/components/dropdowns/date";
import { ButtonAvatars } from "@/components/dropdowns/member/avatar";
import { MemberDropdown } from "@/components/dropdowns/member/dropdown";
import { PriorityDropdown } from "@/components/dropdowns/priority";
import { StateDropdown } from "@/components/dropdowns/state/dropdown";
import { useMember } from "@/hooks/store/use-member";
import { useProject } from "@/hooks/store/use-project";
import { useProjectState } from "@/hooks/store/use-project-state";
import { usePlatformOS } from "@/hooks/use-platform-os";
import type { TRenderQuickActions } from "../list/list-view-types";

type Props = {
  cardRef: React.RefObject<HTMLElement>;
  issue: TIssue;
  displayProperties: IIssueDisplayProperties | undefined;
  updateIssue: ((projectId: string | null, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
  quickActions: TRenderQuickActions;
  isReadOnly: boolean;
  isActive: boolean;
};

const basePillClasses =
  "inline-flex items-center gap-1.5 rounded-full border-0 px-2.5 py-1 text-[11px] font-medium shadow-none outline-none transition-colors";

export const InternalContourKanbanCard = observer(function InternalContourKanbanCard(props: Props) {
  const { cardRef, issue, updateIssue, quickActions, isReadOnly, isActive } = props;
  const { t } = useTranslation();
  const { isMobile } = usePlatformOS();
  const { getUserDetails } = useMember();
  const { getProjectById } = useProject();
  const { getStateById, getProjectStateIds } = useProjectState();

  const menuActionRef = useRef<HTMLDivElement | null>(null);
  const [isMenuActive, setIsMenuActive] = useState(false);

  const creatorDetails = useMemo(() => {
    if (issue.created_by_detail) return issue.created_by_detail;
    if (issue.created_by && getUserDetails(issue.created_by)) return getUserDetails(issue.created_by);
    if (issue.created_by_display_name || issue.created_by_avatar_url) {
      return {
        id: issue.created_by,
        display_name: issue.created_by_display_name ?? t("common.none"),
        avatar_url: issue.created_by_avatar_url ?? "",
        first_name: "",
        last_name: "",
        is_bot: false,
      };
    }
    return undefined;
  }, [
    getUserDetails,
    issue.created_by,
    issue.created_by_avatar_url,
    issue.created_by_detail,
    issue.created_by_display_name,
    t,
  ]);

  const sourceContourName = issue.source_project_name ?? getProjectById(issue.project_id)?.name ?? t("common.none");
  const selectedState = getStateById(issue.state_id);
  const projectStateIds = issue.project_id ? getProjectStateIds(issue.project_id) : [];
  const foregroundClasses = isActive ? "text-[#111111]" : "text-white";
  const subtleTextClasses = isActive ? "text-[#2F4721]" : "text-[#B3B3B8]";
  const pillBackgroundClasses =
    isActive ? "bg-black/10 text-[#111111]" : "bg-[rgb(var(--nodedc-card-passive-rgb))] text-white";
  const iconBubbleClasses = isActive ? "bg-black text-[rgb(var(--nodedc-card-active-rgb))]" : "bg-[#111214] text-white";
  const statusIconColor = selectedState?.color ?? (isActive ? "#111111" : "var(--text-color-primary)");

  const handleEventPropagation = (e: React.MouseEvent) => {
    e.stopPropagation();
    e.preventDefault();
  };

  useOutsideClickDetector(menuActionRef, () => setIsMenuActive(false));

  const creatorName = creatorDetails?.display_name ?? t("common.none");
  const dueDateLabel = issue.target_date ? renderFormattedDate(issue.target_date, "d MMM, yyyy") : t("common.none");

  const customActionButton = (
    <div
      ref={menuActionRef}
      className={cn(
        "flex h-8 w-8 cursor-pointer items-center justify-center rounded-full p-1 transition-colors",
        isActive
          ? "bg-black text-[rgb(var(--nodedc-card-active-rgb))] hover:bg-black/90"
          : "bg-[#111214] text-white hover:bg-[#0A0B0C]",
        isMenuActive && (isActive ? "bg-black/90" : "bg-[#0A0B0C]")
      )}
      onClick={() => setIsMenuActive(!isMenuActive)}
    >
      <MoreHorizontal className="h-3.5 w-3.5" />
    </div>
  );

  return (
    <div className={cn("relative flex min-h-[220px] flex-col px-1", foregroundClasses)}>
      <div className="space-y-0.5">
        <div className="flex items-center justify-between gap-3">
          <div className="flex min-w-0 flex-1 items-center gap-3">
            <div className="shrink-0">
              <Avatar
                src={getFileURL(creatorDetails?.avatar_url ?? "")}
                name={creatorName}
                size="md"
                showTooltip={!isMobile}
              />
            </div>
            <div className={cn("truncate text-body-sm-medium leading-5", foregroundClasses)}>{creatorName}</div>
          </div>

          <div className="flex shrink-0 items-center gap-2" onClick={handleEventPropagation}>
            {quickActions({
              issue,
              parentRef: cardRef,
              customActionButton,
            })}
            <PriorityDropdown
              value={issue.priority}
              onChange={(priority) => updateIssue?.(issue.project_id ?? null, issue.id, { priority })}
              disabled={isReadOnly || !updateIssue}
              button={
                <div
                  className={cn(
                    "flex h-8 w-8 items-center justify-center rounded-full border-0 shadow-none outline-none",
                    iconBubbleClasses
                  )}
                >
                  <PriorityIcon priority={issue.priority} className="h-3.5 w-3.5" />
                </div>
              }
            />
            <StateDropdown
              projectId={issue.project_id ?? undefined}
              stateIds={projectStateIds ?? []}
              value={issue.state_id}
              onChange={(stateId) => updateIssue?.(issue.project_id ?? null, issue.id, { state_id: stateId })}
              disabled={isReadOnly || !updateIssue}
              button={
                <div className={cn("flex h-8 w-8 items-center justify-center rounded-full", iconBubbleClasses)}>
                  <StateGroupIcon
                    stateGroup={selectedState?.group ?? "backlog"}
                    color={statusIconColor}
                    className="h-3.5 w-3.5"
                    percentage={selectedState?.order}
                  />
                </div>
              }
            />
          </div>
        </div>

        <div className={cn("truncate -mt-0.5 pl-8 text-[11px] font-medium leading-4", subtleTextClasses)}>
          {sourceContourName}
        </div>
      </div>

      <div className="flex flex-1 items-center justify-center px-5 py-4 text-center">
        <div className="line-clamp-4 max-w-full text-lg font-semibold leading-6">{issue.name}</div>
      </div>

      <div className="flex items-center justify-between gap-3">
        <MemberDropdown
          projectId={issue.project_id ?? undefined}
          value={issue.assignee_ids}
          onChange={(assigneeIds) => updateIssue?.(issue.project_id ?? null, issue.id, { assignee_ids: assigneeIds })}
          disabled={isReadOnly || !updateIssue}
          button={
            <div className={cn(basePillClasses, pillBackgroundClasses, "min-h-9 pl-1 pr-2")}>
              <ButtonAvatars showTooltip={false} userIds={issue.assignee_ids} size="sm" />
            </div>
          }
        />

        <div className="flex items-center justify-end">
          <DateDropdown
            value={issue.target_date}
            onChange={(targetDate) =>
              updateIssue?.(issue.project_id ?? null, issue.id, {
                target_date: targetDate ? renderFormattedPayloadDate(targetDate) : null,
              })
            }
            disabled={isReadOnly || !updateIssue}
            button={
              <div className={cn(basePillClasses, pillBackgroundClasses)}>
                <CalendarDays className="h-3.5 w-3.5" />
                <span className="truncate">{dueDateLabel}</span>
              </div>
            }
          />
        </div>
      </div>
    </div>
  );
});
