"use client";

import { useState, type ReactNode } from "react";

import Box from "@mui/material/Box";
import Alert from "@mui/material/Alert";
import Drawer from "@mui/material/Drawer";
import IconButton from "@mui/material/IconButton";
import MenuItem from "@mui/material/MenuItem";
import Select from "@mui/material/Select";
import Typography from "@mui/material/Typography";
import { alpha, useTheme, type Theme } from "@mui/material/styles";

import CloseIcon from "@mui/icons-material/Close";

import { AppButton, AppSecondaryButton } from "@/components/ui/button";
import {
  getElevatedSelectMenuProps,
  getSelectSx,
} from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/add-dashboard-issue-dialog-styles";
import { EditorBox } from "@/features/ministry/dashboard/components/add-dashboard-issue-dialog/editor-box";

import type { MinistryProgressReportDecisionRow } from "./progress-report-decisions-data";
import type { MinistryProgressReportIssueRow } from "./progress-report-issues-data";

const DRAWER_Z_INDEX = 1750;
const SELECT_MENU_Z_INDEX = DRAWER_Z_INDEX + 100;

const COMMENT_TYPE_OPTIONS = [
  { value: "Suggestion", label: "Suggestion" },
  { value: "Complaint", label: "Complaint" },
  { value: "Question", label: "Question" },
] as const;

export type ProgressReportIssueComment = {
  id?: number;
  commentTypeId?: number;
  commentType: string;
  comment: string;
};

export type ProgressReportCommentSavePayload = {
  issue?: MinistryProgressReportIssueRow;
  decision?: MinistryProgressReportDecisionRow;
  commentTypeId?: number;
  commentType: string;
  comment: string;
  mode: "add" | "edit";
};

type CommentDrawerMode = "add" | "edit";

type Props = {
  open: boolean;
  issue?: MinistryProgressReportIssueRow | null;
  decision?: MinistryProgressReportDecisionRow | null;
  mode?: CommentDrawerMode;
  initialComment?: ProgressReportIssueComment | null;
  commentTypes?: Array<{ id: number; name: string }>;
  error?: string | null;
  onClose: () => void;
  onSave?: (payload: ProgressReportCommentSavePayload) => void | Promise<void>;
};

function RequiredFieldLabel({ children }: { children: ReactNode }) {
  return (
    <Typography
      sx={{
        fontSize: 13,
        fontWeight: 500,
        color: "#414651",
        mb: "14px",
        lineHeight: 1,
      }}
    >
      {children}
      <Typography component="span" sx={{ color: "#f04438" }}>
        *
      </Typography>
    </Typography>
  );
}

function getCommentSelectSx(theme: Theme) {
  return {
    ...getSelectSx(theme),
    height: 50,
    "& .MuiSelect-select": {
      height: 50,
      minHeight: "50px !important",
      py: 0,
      display: "flex",
      alignItems: "center",
      fontSize: 12,
      fontWeight: 500,
      color: "#181d27",
    },
    "& .MuiSelect-select.MuiSelect-displayEmpty": {
      color: "#a4a7ae",
    },
  };
}

function ProgressReportCommentDrawerContent({
  issue,
  decision,
  mode,
  initialComment,
  commentTypes,
  error,
  onClose,
  onSave,
}: {
  issue?: MinistryProgressReportIssueRow;
  decision?: MinistryProgressReportDecisionRow;
  mode: CommentDrawerMode;
  initialComment?: ProgressReportIssueComment | null;
  commentTypes?: Array<{ id: number; name: string }>;
  error?: string | null;
  onClose: () => void;
  onSave?: (payload: ProgressReportCommentSavePayload) => void | Promise<void>;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const selectMenuProps = getElevatedSelectMenuProps(theme, SELECT_MENU_Z_INDEX);
  const title = mode === "edit" ? "Edit Comment" : "Add Comment";

  const options =
    commentTypes && commentTypes.length > 0
      ? commentTypes.map((item) => ({
          value: String(item.id),
          label: item.name,
        }))
      : COMMENT_TYPE_OPTIONS;
  const usesCommentTypeIds = Boolean(commentTypes && commentTypes.length > 0);
  const [commentType, setCommentType] = useState(
    () =>
      (initialComment?.commentTypeId
        ? String(initialComment.commentTypeId)
        : initialComment?.commentType) ?? "",
  );
  const [comment, setComment] = useState(() => initialComment?.comment ?? "");
  const [saving, setSaving] = useState(false);

  const canSave = Boolean(commentType.trim()) && Boolean(comment.trim());

  async function handleSave() {
    if (!canSave) return;

    setSaving(true);

    try {
      const selectedOption = options.find(
        (option) => option.value === commentType,
      );

      await onSave?.({
        issue,
        decision,
        commentTypeId: usesCommentTypeIds ? Number(commentType) : undefined,
        commentType: selectedOption?.label ?? commentType,
        comment: comment.trim(),
        mode,
      });
      onClose();
    } catch {
      // The parent mutation displays its backend error inside this drawer.
      // Keep the drawer and entered values open so the user can retry.
    } finally {
      setSaving(false);
    }
  }

  return (
    <Box
      sx={{
        display: "flex",
        flexDirection: "column",
        height: "100%",
        minHeight: 0,
      }}
    >
      <Box
        sx={{
          height: 67,
          px: "22px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          borderBottom: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"}`,
          flexShrink: 0,
        }}
      >
        <Typography
          sx={{
            fontSize: 20,
            fontWeight: 500,
            color: "#0a0a0a",
            letterSpacing: "-0.4px",
            lineHeight: 1.2,
          }}
        >
          {title}
        </Typography>

        <IconButton onClick={onClose} size="small" sx={{ color: "#717680" }}>
          <CloseIcon sx={{ fontSize: 24 }} />
        </IconButton>
      </Box>

      <Box
        sx={{
          px: "18px",
          py: "22px",
          overflowY: "auto",
          flex: 1,
          minHeight: 0,
        }}
      >
        <Box sx={{ display: "grid", gap: "22px", maxWidth: 759 }}>
          <Box>
            <RequiredFieldLabel>Comment Type </RequiredFieldLabel>
            <Select
              fullWidth
              displayEmpty
              value={commentType}
              onChange={(event) => setCommentType(event.target.value)}
              renderValue={(selected) =>
                options.find((option) => option.value === String(selected))
                  ?.label ?? "Select comment type"
              }
              sx={getCommentSelectSx(theme)}
              MenuProps={selectMenuProps}
            >
              {options.map((option) => (
                <MenuItem key={option.value} value={option.value} sx={{ fontSize: 12 }}>
                  {option.label}
                </MenuItem>
              ))}
            </Select>
          </Box>

          <Box>
            <RequiredFieldLabel>Comment </RequiredFieldLabel>
            <Box
              sx={{
                "& > div": {
                  minHeight: 290,
                  borderWidth: "1.5px",
                  borderRadius: "8px",
                },
                "& textarea": {
                  fontSize: "13px !important",
                },
                "& textarea::placeholder": {
                  color: "#9f9f9f !important",
                },
              }}
            >
              <EditorBox
                placeholder="Write comment ........."
                value={comment}
                onChange={setComment}
              />
            </Box>
          </Box>

          {error ? <Alert severity="error">{error}</Alert> : null}
        </Box>
      </Box>

      <Box
        sx={{
          height: 84,
          px: "22px",
          display: "flex",
          alignItems: "center",
          justifyContent: "flex-end",
          gap: "22px",
          borderTop: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#f5f5f5"}`,
          flexShrink: 0,
          bgcolor: isDark ? "#101828" : "#ffffff",
        }}
      >
        <AppSecondaryButton
          onClick={onClose}
          sx={{
            minWidth: 150,
            width: 150,
            height: 40,
            borderColor: "#d5d7da",
            color: "#153858",
          }}
        >
          Cancel
        </AppSecondaryButton>

        <AppButton
          disabled={!canSave || saving}
          onClick={() => void handleSave()}
          sx={{
            minWidth: 149,
            width: 149,
            height: 40,
            bgcolor: canSave ? "#1a64a8" : "#717680",
            "&:hover": {
              bgcolor: canSave ? "#155a96" : "#717680",
            },
            "&.Mui-disabled": {
              bgcolor: "#717680",
              color: "#ffffff",
            },
          }}
        >
          {saving ? "Saving..." : "Save"}
        </AppButton>
      </Box>
    </Box>
  );
}

function ProgressReportCommentDrawerShell({
  open,
  issue,
  decision,
  mode,
  initialComment,
  commentTypes,
  error,
  onClose,
  onSave,
}: Props) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const drawerMode = mode ?? "add";
  const target = issue ?? decision;
  const targetKey = issue
    ? `issue-${issue.id}`
    : decision
      ? `decision-${decision.id}`
      : "none";

  return (
    <Drawer
      anchor="right"
      open={open && Boolean(target)}
      onClose={onClose}
      sx={{
        zIndex: DRAWER_Z_INDEX,
        "& .MuiBackdrop-root": { bgcolor: "rgba(0, 0, 0, 0.35)" },
        "& .MuiDrawer-paper": {
          width: { xs: "100vw", sm: 795 },
          maxWidth: "100vw",
          height: "100dvh",
          borderRadius: "12px 0 0 12px",
          overflow: "hidden",
          bgcolor: isDark ? "#101828" : "#ffffff",
          backgroundImage: "none",
          display: "flex",
          flexDirection: "column",
        },
      }}
    >
      {target ? (
        <ProgressReportCommentDrawerContent
          key={`${drawerMode}-${targetKey}-${initialComment?.commentType ?? ""}-${initialComment?.comment ?? ""}`}
          issue={issue ?? undefined}
          decision={decision ?? undefined}
          mode={drawerMode}
          initialComment={initialComment}
          commentTypes={commentTypes}
          error={error}
          onClose={onClose}
          onSave={onSave}
        />
      ) : null}
    </Drawer>
  );
}

export function ProgressReportAddCommentDrawer({
  open,
  issue,
  decision,
  commentTypes,
  error,
  onClose,
  onSave,
}: Omit<Props, "mode" | "initialComment">) {
  return (
    <ProgressReportCommentDrawerShell
      open={open}
      issue={issue}
      decision={decision}
      mode="add"
      commentTypes={commentTypes}
      error={error}
      onClose={onClose}
      onSave={onSave}
    />
  );
}

export function ProgressReportEditCommentDrawer({
  open,
  issue,
  decision,
  initialComment,
  commentTypes,
  error,
  onClose,
  onSave,
}: Omit<Props, "mode">) {
  return (
    <ProgressReportCommentDrawerShell
      open={open}
      issue={issue}
      decision={decision}
      mode="edit"
      initialComment={initialComment}
      commentTypes={commentTypes}
      error={error}
      onClose={onClose}
      onSave={onSave}
    />
  );
}

type ReadOnlyProgressReportComment = {
  commentType: string;
  comment: string;
  authorName?: string | null;
};

function toPlainText(value: string) {
  return value
    .replace(/<br\s*\/?>(\r?\n)?/gi, "\n")
    .replace(/<\/p>/gi, "\n")
    .replace(/<[^>]*>/g, "")
    .replace(/&nbsp;/gi, " ")
    .trim();
}

/**
 * Ministry users can read a CDC comment, but they cannot edit it.
 */
export function ProgressReportViewCommentDrawer({
  open,
  comment,
  onClose,
}: {
  open: boolean;
  comment: ReadOnlyProgressReportComment | null;
  onClose: () => void;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  return (
    <Drawer
      anchor="right"
      open={open && Boolean(comment)}
      onClose={onClose}
      sx={{
        zIndex: DRAWER_Z_INDEX,
        "& .MuiBackdrop-root": { bgcolor: "rgba(0, 0, 0, 0.35)" },
        "& .MuiDrawer-paper": {
          width: { xs: "100vw", sm: 795 },
          maxWidth: "100vw",
          height: "100dvh",
          borderRadius: "12px 0 0 12px",
          overflow: "hidden",
          bgcolor: isDark ? "#101828" : "#ffffff",
          backgroundImage: "none",
          display: "flex",
          flexDirection: "column",
        },
      }}
    >
      <Box
        sx={{
          height: 67,
          px: "22px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          borderBottom: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"}`,
          flexShrink: 0,
        }}
      >
        <Typography sx={{ fontSize: 20, fontWeight: 500, color: "#0a0a0a" }}>
          View Comment
        </Typography>
        <IconButton onClick={onClose} size="small" sx={{ color: "#717680" }}>
          <CloseIcon sx={{ fontSize: 24 }} />
        </IconButton>
      </Box>

      <Box sx={{ px: "18px", py: "22px", flex: 1, overflowY: "auto" }}>
        {comment ? (
          <Box sx={{ display: "grid", gap: "22px", maxWidth: 759 }}>
            <Box>
              <Typography
                sx={{
                  fontSize: 13,
                  fontWeight: 500,
                  color: "#414651",
                  mb: "14px",
                }}
              >
                Comment Type
              </Typography>
              <Box
                sx={{
                  minHeight: 50,
                  px: 1.75,
                  display: "flex",
                  alignItems: "center",
                  border: "1px solid #d5d7da",
                  borderRadius: "6px",
                  fontSize: 13,
                  color: "#181d27",
                }}
              >
                {comment.commentType || "-"}
              </Box>
            </Box>

            <Box>
              <Typography
                sx={{
                  fontSize: 13,
                  fontWeight: 500,
                  color: "#414651",
                  mb: "14px",
                }}
              >
                Comment
              </Typography>
              <Box
                sx={{
                  minHeight: 290,
                  p: 2,
                  border: "1.5px solid #d5d7da",
                  borderRadius: "8px",
                  color: "#181d27",
                  fontSize: 13,
                  lineHeight: 1.6,
                  whiteSpace: "pre-wrap",
                }}
              >
                {toPlainText(comment.comment) || "-"}
              </Box>
            </Box>

            {comment.authorName ? (
              <Typography sx={{ fontSize: 13, color: "#667085" }}>
                Commented by: {comment.authorName}
              </Typography>
            ) : null}
          </Box>
        ) : null}
      </Box>

      <Box
        sx={{
          height: 84,
          px: "22px",
          display: "flex",
          alignItems: "center",
          justifyContent: "flex-end",
          borderTop: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#f5f5f5"}`,
          flexShrink: 0,
        }}
      >
        <AppSecondaryButton
          onClick={onClose}
          sx={{ minWidth: 150, width: 150, height: 40 }}
        >
          Close
        </AppSecondaryButton>
      </Box>
    </Drawer>
  );
}

/** @deprecated Use ProgressReportCommentSavePayload */
export type ProgressReportAddCommentSavePayload = Omit<
  ProgressReportCommentSavePayload,
  "mode"
>;
