"use client";

// The "⋮" row-actions dropdown for the progress-report table (Figma node
// 38506:497207). Every item is a visual placeholder for now — clicking one
// just closes the menu. Wire real handlers in once the backend exists.

import { useMemo, useState, type MouseEvent, type ReactNode } from "react";
import { useRouter } from "next/navigation";

import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import {
  CalendarAddNewIcon,
  ExportCommentIcon,
  EyeViewIcon,
  GenerateDraftDashboardIcon,
  GenerateFinalDashboardIcon,
  PencilEditIcon,
  PlenariesIcon,
  SetDeadlineIcon,
  UploadDraftSemesterIcon,
  WGIcon,
} from "@/components/ui/icon";

import type {
  ProgressReportActionsMenuLabels,
  ProgressReportCreateDialogLabels,
  ProgressReportCreateMeetingDialogLabels,
  ProgressReportSetDeadlineDialogLabels,
  ProgressReportUploadDraftSemesterDialogLabels,
} from "../../progress-report-i18n";
import type { ProgressReportRow } from "../../progress-report-data";
import type { ProgressReportMeetingSlot } from "../../service/progress-report-service";
import { CreateMeetingDialog } from "../create-meeting-dialog/create-meeting-dialog";
import type {
  CreateMeetingFormValues,
  CreateMeetingSubmitMode,
} from "../create-meeting-dialog/create-meeting-dialog-types";
import { CreateProgressReportDialog } from "../create-progress-report-dialog/create-progress-report-dialog";
import type {
  CreateProgressReportFormValues,
  CreateProgressReportSubmitMode,
} from "../create-progress-report-dialog/create-progress-report-dialog-types";
import {
  SetDeadlineDialog,
  type SetDeadlineSlot,
} from "../set-deadline-dialog/set-deadline-dialog";
import { UploadDraftSemesterDialog } from "../upload-draft-semester-dialog/upload-draft-semester-dialog";

export type ProgressReportRowActions = {
  editReport: (
    progressReportId: number,
    currentDeadline: string,
    firstDeadlineId: number | null,
    values: CreateProgressReportFormValues,
    mode: CreateProgressReportSubmitMode,
  ) => Promise<void>;
  createMeeting: (
    progressReportId: number,
    slot: ProgressReportMeetingSlot,
    values: CreateMeetingFormValues,
    mode: CreateMeetingSubmitMode,
  ) => Promise<void>;
  setDeadline: (
    progressReportId: number,
    slot: SetDeadlineSlot,
    deadlineId: number | null,
    deadline: string,
    shouldSend: boolean,
  ) => Promise<void>;
  uploadDraftSemester: (progressReportId: number, file: File) => Promise<void>;
};

type ProgressReportActionsMenuProps = {
  labels: ProgressReportActionsMenuLabels;
  editReportLabels: ProgressReportCreateDialogLabels;
  uploadDraftSemesterLabels: ProgressReportUploadDraftSemesterDialogLabels;
  createMeetingLabels: ProgressReportCreateMeetingDialogLabels;
  setDeadlineLabels: ProgressReportSetDeadlineDialogLabels;
  report: ProgressReportRow;
  rowActions: ProgressReportRowActions;
};

function toDateInputValue(value: string) {
  const date = value.match(/^\d{4}-\d{2}-\d{2}/)?.[0];
  return date ?? "";
}

const MENU_WIDTH = 272;
const MENU_MAX_HEIGHT = 280;
const MENU_ITEM_HEIGHT = 50;

// One row of the menu: icon + label, with an optional expand arrow
// and optional left indent (for the PSWG / Plenary sub-items).
function ActionMenuItem({
  icon,
  label,
  indented = false,
  expandArrow,
  disabled = false,
  onClick,
}: {
  icon: ReactNode;
  label: string;
  indented?: boolean;
  expandArrow?: ReactNode;
  disabled?: boolean;
  onClick: () => void;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const muted = isDark ? alpha("#ffffff", 0.72) : "#717680";

  return (
    <MenuItem
      onClick={onClick}
      disabled={disabled}
      sx={{
        height: MENU_ITEM_HEIGHT,
        minHeight: MENU_ITEM_HEIGHT,
        width: indented ? 218 : "100%",
        ml: indented ? "auto" : 0,
        px: indented ? 0 : "22px",
        pr: expandArrow ? "16px" : indented ? 0 : "22px",
        gap: indented ? 2 : 1,
        color: muted,
        fontSize: 13,
        fontWeight: 500,
      }}
    >
      <Box
        sx={{
          width: indented ? 20 : 24,
          height: indented ? 20 : 24,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          flexShrink: 0,
          color: muted,
          "& .MuiSvgIcon-root": {
            fontSize: indented ? 20 : 24,
          },
        }}
      >
        {icon}
      </Box>

      <Typography
        sx={{
          flex: 1,
          minWidth: 0,
          fontSize: indented ? 12 : 13,
          fontWeight: 500,
          color: muted,
        }}
        noWrap
      >
        {label}
      </Typography>

      {expandArrow}
    </MenuItem>
  );
}

export function ProgressReportActionsMenu({
  labels,
  editReportLabels,
  uploadDraftSemesterLabels,
  createMeetingLabels,
  setDeadlineLabels,
  report,
  rowActions,
}: ProgressReportActionsMenuProps) {
  const router = useRouter();
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  // Which element the menu is attached to; null means the menu is closed.
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
  // Open/closed state of the two expandable "Generate ..." sections.
  const [draftDashboardOpen, setDraftDashboardOpen] = useState(false);
  const [finalDashboardOpen, setFinalDashboardOpen] = useState(false);
  const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
  const [createMeetingOpen, setCreateMeetingOpen] = useState(false);
  const [setDeadlineOpen, setSetDeadlineOpen] = useState(false);
  const [editDialogOpen, setEditDialogOpen] = useState(false);

  const editInitialValues = useMemo(
    () => ({
      title: report.title,
      semester: report.semester,
      description: report.description,
      year: report.year,
      deadline: toDateInputValue(report.deadline),
    }),
    [
      report.deadline,
      report.description,
      report.semester,
      report.title,
      report.year,
    ],
  );
  const editDialogLabels = useMemo(
    () => ({
      ...editReportLabels,
      title: editReportLabels.editTitle,
      submitError: editReportLabels.editSubmitError,
    }),
    [editReportLabels],
  );

  const menuOpen = Boolean(anchorEl);
  const iconSize = { fontSize: 24 } as const;
  const subIconSize = { fontSize: 20 } as const;
  const muted = isDark ? alpha("#ffffff", 0.72) : "#717680";
  const arrowSx = {
    fontSize: 16,
    color: muted,
  } as const;

  const openMenu = (event: MouseEvent<HTMLElement>) => {
    setAnchorEl(event.currentTarget);
  };

  const closeMenu = () => {
    setAnchorEl(null);
    // Collapse the sections again so the menu opens fresh next time.
    setDraftDashboardOpen(false);
    setFinalDashboardOpen(false);
  };

  const viewDetail = () => {
    closeMenu();
    router.push(`/cdc-gpsf/progress-reports/${report.id}`);
  };

  const openEditReport = () => {
    closeMenu();
    setEditDialogOpen(true);
  };

  const openUploadDraftSemester = () => {
    closeMenu();
    setUploadDialogOpen(true);
  };

  const openCreateMeeting = () => {
    closeMenu();
    setCreateMeetingOpen(true);
  };

  const openSetDeadline = () => {
    closeMenu();
    setSetDeadlineOpen(true);
  };

  const defaultMeetingName =
    report.title && report.year
      ? `${report.title} | ${report.year}`
      : report.title || "";

  // Keep slot selection close to the dialogs. The backend validates whether
  // the selected workflow step is currently allowed.
  const nextMeetingSlot: ProgressReportMeetingSlot =
    report.firstMeeting === "-" ? "FIRST" : "SECOND";
  const nextDeadlineSlot: SetDeadlineSlot =
    report.secondDeadlineStatus === "SENT" ? "FINAL" : "SECOND";
  // An id means that slot already exists, so saving edits it instead.
  const nextDeadlineId =
    nextDeadlineSlot === "FINAL"
      ? report.finalDeadlineId
      : report.secondDeadlineId;

  return (
    <>
      <IconButton
        size="small"
        aria-label={labels.openMenu}
        aria-haspopup="menu"
        aria-expanded={menuOpen ? "true" : undefined}
        onClick={openMenu}
        sx={{
          color: "var(--mr-muted)",
          "&:hover": { color: "var(--mr-blue)" },
        }}
      >
        <MoreVertIcon sx={{ fontSize: 22 }} />
      </IconButton>

      <Menu
        anchorEl={anchorEl}
        open={menuOpen}
        onClose={closeMenu}
        anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
        transformOrigin={{ vertical: "top", horizontal: "right" }}
        slotProps={{
          paper: {
            sx: {
              mt: 0.5,
              width: MENU_WIDTH,
              minWidth: MENU_WIDTH,
              maxWidth: MENU_WIDTH,
              maxHeight: MENU_MAX_HEIGHT,
              overflow: "hidden",
              borderRadius: "12px",
              border: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#f5f5f5"}`,
              bgcolor: isDark ? "#101828" : "#ffffff",
              boxShadow: isDark
                ? "0 12px 30px rgba(0, 0, 0, 0.5)"
                : "0px 0px 10.6px rgba(0, 0, 0, 0.1)",
            },
          },
          list: {
            sx: {
              py: 0,
              maxHeight: MENU_MAX_HEIGHT,
              overflowY: "auto",
              overflowX: "hidden",
              "&::-webkit-scrollbar": {
                width: 6,
              },
              "&::-webkit-scrollbar-track": {
                bgcolor: isDark ? alpha("#ffffff", 0.08) : "#e9eaeb",
                borderRadius: "3px",
                my: "16px",
              },
              "&::-webkit-scrollbar-thumb": {
                bgcolor: isDark ? alpha("#ffffff", 0.28) : "#a4a7ae",
                borderRadius: "3px",
              },
            },
          },
        }}
      >
        <ActionMenuItem
          icon={<EyeViewIcon sx={iconSize} />}
          label={labels.viewDetail}
          onClick={viewDetail}
        />

        {report.status !== "Sent" ? (
          <ActionMenuItem
            icon={<PencilEditIcon sx={iconSize} />}
            label={labels.edit}
            onClick={openEditReport}
          />
        ) : null}

        <ActionMenuItem
          icon={<CalendarAddNewIcon sx={iconSize} />}
          label={labels.createMeeting}
          onClick={openCreateMeeting}
        />

        <ActionMenuItem
          icon={<SetDeadlineIcon sx={iconSize} />}
          label={labels.setDeadline}
          onClick={openSetDeadline}
        />

        <ActionMenuItem
          icon={<ExportCommentIcon sx={iconSize} />}
          label={labels.exportComment}
          onClick={closeMenu}
        />

        <ActionMenuItem
          icon={<UploadDraftSemesterIcon sx={iconSize} />}
          label={labels.uploadDraftSemester}
          onClick={openUploadDraftSemester}
        />

        {/* Expandable: Generate Draft Dashboard -> PSWG / Plenary */}
        <ActionMenuItem
          icon={<GenerateDraftDashboardIcon sx={iconSize} />}
          label={labels.generateDraftDashboard}
          expandArrow={
            draftDashboardOpen ? (
              <KeyboardArrowUpIcon sx={arrowSx} />
            ) : (
              <KeyboardArrowDownIcon sx={arrowSx} />
            )
          }
          onClick={() => setDraftDashboardOpen((open) => !open)}
        />
        {draftDashboardOpen && (
          <ActionMenuItem
            icon={<WGIcon sx={subIconSize} />}
            label={labels.pswg}
            indented
            onClick={closeMenu}
          />
        )}
        {draftDashboardOpen && (
          <ActionMenuItem
            icon={<PlenariesIcon sx={subIconSize} />}
            label={labels.plenary}
            indented
            onClick={closeMenu}
          />
        )}

        {/* Expandable: Generate Final Dashboard -> PSWG / Plenary */}
        <ActionMenuItem
          icon={<GenerateFinalDashboardIcon sx={iconSize} />}
          label={labels.generateFinalDashboard}
          expandArrow={
            finalDashboardOpen ? (
              <KeyboardArrowUpIcon sx={arrowSx} />
            ) : (
              <KeyboardArrowDownIcon sx={arrowSx} />
            )
          }
          onClick={() => setFinalDashboardOpen((open) => !open)}
        />
        {finalDashboardOpen && (
          <ActionMenuItem
            icon={<WGIcon sx={subIconSize} />}
            label={labels.pswg}
            indented
            onClick={closeMenu}
          />
        )}
        {finalDashboardOpen && (
          <ActionMenuItem
            icon={<PlenariesIcon sx={subIconSize} />}
            label={labels.plenary}
            indented
            onClick={closeMenu}
          />
        )}
      </Menu>

      <UploadDraftSemesterDialog
        open={uploadDialogOpen}
        labels={uploadDraftSemesterLabels}
        onClose={() => setUploadDialogOpen(false)}
        onUpload={(file) => rowActions.uploadDraftSemester(report.id, file)}
      />

      <CreateMeetingDialog
        open={createMeetingOpen}
        labels={createMeetingLabels}
        defaultName={defaultMeetingName}
        onClose={() => setCreateMeetingOpen(false)}
        onSubmit={(values, mode) =>
          rowActions.createMeeting(report.id, nextMeetingSlot, values, mode)
        }
      />

      <SetDeadlineDialog
        key={`${report.id}-${nextDeadlineSlot}-${report.secondDeadline}-${report.finalDeadline}`}
        open={setDeadlineOpen}
        labels={setDeadlineLabels}
        slot={nextDeadlineSlot}
        initialDate={toDateInputValue(
          nextDeadlineSlot === "FINAL"
            ? report.finalDeadline
            : report.secondDeadline,
        )}
        onClose={() => setSetDeadlineOpen(false)}
        onSave={(deadline) =>
          rowActions.setDeadline(
            report.id,
            nextDeadlineSlot,
            nextDeadlineId,
            deadline,
            false,
          )
        }
        onSend={(deadline) =>
          rowActions.setDeadline(
            report.id,
            nextDeadlineSlot,
            nextDeadlineId,
            deadline,
            true,
          )
        }
      />

      {editDialogOpen ? (
        <CreateProgressReportDialog
          open
          labels={editDialogLabels}
          initialValues={editInitialValues}
          existingAttachment={report.reportDoc}
          onClose={() => setEditDialogOpen(false)}
          onSubmit={(values, mode) =>
            rowActions.editReport(
              report.id,
              report.deadline,
              report.firstDeadlineId,
              values,
              mode,
            )
          }
        />
      ) : null}
    </>
  );
}
