"use client";

import {
  useEffect,
  useMemo,
  useState,
  type ChangeEvent,
  type ReactNode,
} from "react";

import {
  usePathname,
} from "next/navigation";

import Box from "@mui/material/Box";
import Rating from "@mui/material/Rating";

import EditOutlinedIcon from "@mui/icons-material/EditOutlined";

import {
  alpha,
  useTheme,
} from "@mui/material/styles";

import {
  useAppLanguage,
} from "@/components/providers/app-language-provider";

import {
  evaluationFormText,
  getEvaluationFormFontClass,
  normalizeEvaluationFormLanguage,
} from "../../evaluation-form-i18n";

import type {
  EvaluationFormData,
  EvaluationItem,
  EvaluationItemEvaluation,
  UpdateEvaluationFormPayload,
} from "../../types/evaluation-form.types";

import {
  CloseIcon,
} from "../evaluation-icons";
import { EyeViewIcon } from "@/components/ui/icon";

function containsKhmer(
  value: unknown,
): boolean {
  if (
    value === null ||
    value === undefined
  ) {
    return false;
  }

  return /[\u1780-\u17FF]/.test(
    String(value),
  );
}

function getContentFontClass(
  value: unknown,
): "font-kh" | "font-en" {
  return containsKhmer(
    value,
  )
    ? "font-kh"
    : "font-en";
}

function getContentLanguage(
  value: unknown,
): "km" | "en" {
  return containsKhmer(
    value,
  )
    ? "km"
    : "en";
}

export type EvaluationDetailMode =
  | "view"
  | "edit";

type Props = {
  open:
    boolean;

  mode:
    EvaluationDetailMode;

  data:
    EvaluationFormData | null;

  saving?: boolean;

  error?:
    string | null;

  /*
   * Keep this prop so old parent code
   * does not get TypeScript error.
   *
   * But actual permission is checked
   * from pathname below.
   */
  canEdit?: boolean;

  onClose:
    () => void;

  onModeChange?: (
    mode:
      EvaluationDetailMode,
  ) => void;

  onSave?: (
    payload:
      UpdateEvaluationFormPayload,
  ) =>
    | void
    | Promise<void>;
};

type EditableItem = {
  issueId:
    number;

  isResolved:
    boolean | null;

  rating:
    number;

  feedback:
    string;
};

function getEvaluation(
  item:
    EvaluationItem,
): EvaluationItemEvaluation | null {
  const value =
    item.evaluation as
      | EvaluationItemEvaluation
      | EvaluationItemEvaluation[]
      | null
      | undefined;

  if (
    Array.isArray(
      value,
    )
  ) {
    return value[0] ?? null;
  }

  return value ?? null;
}

function normalizeRating(
  value: unknown,
): number {
  const rating =
    Number(value);

  if (
    !Number.isInteger(
      rating,
    ) ||
    rating < 1 ||
    rating > 5
  ) {
    return 0;
  }

  return rating;
}

function createEditableItems(
  data:
    EvaluationFormData,
): EditableItem[] {
  return data.items.map(
    (item) => {
      const evaluation =
        getEvaluation(
          item,
        );

      return {
        issueId:
          item.issueId,

        isResolved:
          evaluation
            ? evaluation.isResolved
            : null,

        rating:
          normalizeRating(
            evaluation?.rating,
          ),

        feedback:
          evaluation?.feedback ??
          "",
      };
    },
  );
}

function ModeButton({
  active,
  disabled = false,
  label,
  icon,
  onClick,
}: {
  active:
    boolean;

  disabled?:
    boolean;

  label:
    string;

  icon:
    ReactNode;

  onClick:
    () => void;
}) {
  const theme =
    useTheme();

  return (
    <Box
      component="button"
      type="button"
      disabled={
        disabled
      }
      onClick={
        onClick
      }
      sx={{
        minWidth:
          82,

        height:
          36,

        px:
          1.3,

        display:
          "inline-flex",

        alignItems:
          "center",

        justifyContent:
          "center",

        gap:
          0.7,

        border:
          "1px solid",

        borderColor:
          active
            ? "primary.main"
            : "divider",

        borderRadius:
          1.5,

        bgcolor:
          active
            ? alpha(
                theme.palette.primary.main,
                theme.palette.mode ===
                  "dark"
                  ? 0.18
                  : 0.08,
              )
            : "background.paper",

        color:
          active
            ? "primary.main"
            : "text.primary",

        fontWeight:
          700,

        cursor:
          disabled
            ? "not-allowed"
            : "pointer",

        opacity:
          disabled
            ? 0.5
            : 1,
      }}
    >
      {icon}

      {label}
    </Box>
  );
}

function DetailContent({
  mode,
  data,
  saving = false,
  error = null,
  canEdit = false,
  onClose,
  onModeChange,
  onSave,
}: Omit<
  Props,
  "open"
> & {
  data:
    EvaluationFormData;
}) {
  const theme =
    useTheme();

  const {
    language,
  } =
    useAppLanguage();

  const lang =
    normalizeEvaluationFormLanguage(
      language,
    );

  const text =
    evaluationFormText[
      lang
    ];

  const uiFontClass =
    getEvaluationFormFontClass(
      lang,
    );

  const [
    editableItems,
    setEditableItems,
  ] =
    useState<EditableItem[]>(
      () =>
        createEditableItems(
          data,
        ),
    );

  const overview =
    useMemo(() => {
      let resolved =
        0;

      let notResolved =
        0;

      let notEvaluated =
        0;

      data.items.forEach(
        (item) => {
          const evaluation =
            getEvaluation(
              item,
            );

          if (!evaluation) {
            notEvaluated +=
              1;

            return;
          }

          if (
            evaluation.isResolved
          ) {
            resolved +=
              1;
          } else {
            notResolved +=
              1;
          }
        },
      );

      return {
        resolved,
        notResolved,
        notEvaluated,
      };
    }, [
      data,
    ]);

  const canSave =
    useMemo(
      () =>
        canEdit &&
        editableItems.length >
          0 &&
        editableItems.every(
          (item) =>
            item.isResolved !==
              null &&
            Number.isInteger(
              item.rating,
            ) &&
            item.rating >=
              1 &&
            item.rating <=
              5 &&
            item.feedback
              .trim()
              .length >
              0,
        ),
      [
        canEdit,
        editableItems,
      ],
    );

  function updateItem(
    issueId:
      number,

    patch:
      Partial<EditableItem>,
  ) {
    if (!canEdit) {
      return;
    }

    setEditableItems(
      (current) =>
        current.map(
          (item) =>
            item.issueId ===
            issueId
              ? {
                  ...item,
                  ...patch,
                }
              : item,
        ),
    );
  }

  function cancelEdit() {
    if (!canEdit) {
      return;
    }

    setEditableItems(
      createEditableItems(
        data,
      ),
    );

    onModeChange?.(
      "view",
    );
  }

  async function save() {
    if (
      !canEdit ||
      saving ||
      !canSave
    ) {
      return;
    }

    await onSave?.({
      evaluations:
        editableItems.map(
          (item) => ({
            issueId:
              item.issueId,

            isResolved:
              item.isResolved ===
              true,

            rating:
              item.rating,

            feedback:
              item.feedback.trim(),
          }),
        ),
    });
  }

  const cardBackground =
    theme.palette.mode ===
    "dark"
      ? alpha(
          theme.palette.common.white,
          0.025,
        )
      : theme.palette.background.paper;

  const metricData = [
    {
      value:
        overview.resolved,

      label:
        text.resolved,

      color:
        theme.palette.success.main,
    },

    {
      value:
        overview.notResolved,

      label:
        text.notResolved,

      color:
        theme.palette.error.main,
    },

    {
      value:
        overview.notEvaluated,

      label:
        text.notEvaluated,

      color:
        theme.palette.text.secondary,
    },

    {
      value:
        data.totalIssues,

      label:
        text.totalIssues,

      color:
        theme.palette.primary.main,
    },
  ];

  return (
    <Box
      className={
        uiFontClass
      }
      sx={{
        position:
          "relative",

        zIndex:
          1,

        width: {
          xs:
            "100%",

          sm:
            650,

          lg:
            780,
        },

        maxWidth:
          "100vw",

        height:
          "100dvh",

        display:
          "flex",

        flexDirection:
          "column",

        bgcolor:
          "background.paper",

        color:
          "text.primary",

        borderLeft:
          "1px solid",

        borderColor:
          "divider",

        boxShadow:
          theme.palette.mode ===
          "dark"
            ? "-18px 0 50px rgba(0,0,0,.40)"
            : "-18px 0 50px rgba(15,23,42,.15)",
      }}
    >
      {/* HEADER */}
      <Box
        sx={{
          minHeight:
            84,

          px:
            2.2,

          display:
            "flex",

          alignItems:
            "center",

          justifyContent:
            "space-between",

          gap:
            1.2,

          flexShrink:
            0,

          bgcolor:
            "background.paper",

          borderBottom:
            "1px solid",

          borderColor:
            "divider",
        }}
      >
        <Box
          sx={{
            minWidth:
              0,
          }}
        >
          <Box
            sx={{
              color:
                "text.primary",

              fontSize:
                20,

              fontWeight:
                800,

              lineHeight:
                1.4,
            }}
          >
            {mode ===
            "edit"
              ? text.editTitle
              : text.detailTitle}
          </Box>

          <Box
            sx={{
              mt:
                0.2,

              color:
                "text.secondary",

              fontSize:
                11,

              lineHeight:
                1.5,
            }}
          >
            {mode ===
            "edit"
              ? text.editSubtitle
              : text.detailSubtitle}
          </Box>
        </Box>

        <Box
          sx={{
            display:
              "flex",

            alignItems:
              "center",

            gap:
              0.7,

            flexShrink:
              0,
          }}
        >
          {/* VIEW - ALL ROLES */}
          <ModeButton
            active={
              mode ===
              "view"
            }
            disabled={
              saving
            }
            label={
              text.view
            }
            icon={
              <EyeViewIcon
                sx={{
                  fontSize:
                    17,
                }}
              />
            }
            onClick={() =>
              onModeChange?.(
                "view",
              )
            }
          />

          {/* EDIT - ADMIN ONLY */}
          {canEdit ? (
            <ModeButton
              active={
                mode ===
                "edit"
              }
              disabled={
                saving
              }
              label={
                text.edit
              }
              icon={
                <EditOutlinedIcon
                  sx={{
                    fontSize:
                      17,
                  }}
                />
              }
              onClick={() =>
                onModeChange?.(
                  "edit",
                )
              }
            />
          ) : null}

          <Box
            component="button"
            type="button"
            disabled={
              saving
            }
            onClick={
              onClose
            }
            sx={{
              width:
                36,

              height:
                36,

              display:
                "grid",

              placeItems:
                "center",

              border:
                0,

              borderRadius:
                1,

              bgcolor:
                "transparent",

              color:
                "text.secondary",

              cursor:
                saving
                  ? "not-allowed"
                  : "pointer",

              "&:hover": {
                bgcolor:
                  "action.hover",
              },
            }}
          >
            <CloseIcon
              size={
                20
              }
            />
          </Box>
        </Box>
      </Box>

      {/* BODY */}
      <Box
        sx={{
          flex:
            1,

          minHeight:
            0,

          overflowY:
            "auto",

          p:
            2,

          bgcolor:
            "background.default",
        }}
      >
        {error ? (
          <Box
            sx={{
              mb:
                1.5,

              p:
                1.2,

              borderRadius:
                1.5,

              color:
                "error.main",

              bgcolor:
                alpha(
                  theme.palette.error.main,
                  0.08,
                ),

              border:
                "1px solid",

              borderColor:
                alpha(
                  theme.palette.error.main,
                  0.25,
                ),
            }}
          >
            {error}
          </Box>
        ) : null}

        {/* PROGRESS REPORT INFO */}
        <Box
          sx={{
            p:
              1.7,

            border:
              "1px solid",

            borderColor:
              "divider",

            borderRadius:
              2,

            bgcolor:
              cardBackground,
          }}
        >
          <Box
            sx={{
              color:
                "text.secondary",

              fontSize:
                10.5,

              fontWeight:
                700,
            }}
          >
            {
              text.progressReport
            }
          </Box>

          <Box
            component="div"
            lang={
              getContentLanguage(
                data.assignment
                  .progressReport
                  .title,
              )
            }
            className={
              getContentFontClass(
                data.assignment
                  .progressReport
                  .title,
              )
            }
            sx={{
              mt:
                0.4,

              color:
                "text.primary",

              fontSize:
                containsKhmer(
                  data.assignment
                    .progressReport
                    .title,
                )
                  ? 15
                  : 14,

              fontWeight:
                700,

              lineHeight:
                containsKhmer(
                  data.assignment
                    .progressReport
                    .title,
                )
                  ? 1.9
                  : 1.5,
            }}
          >
            {
              data.assignment
                .progressReport
                .title
            }
          </Box>

          <Box
            sx={{
              mt:
                1.5,

              display:
                "grid",

              gridTemplateColumns:
                "repeat(2, minmax(0, 1fr))",

              gap:
                1.25,
            }}
          >
            {[
              {
                label:
                  text.year,

                value:
                  data.assignment
                    .progressReport
                    .year,
              },

              {
                label:
                  text.semester,

                value:
                  data.assignment
                    .progressReport
                    .semester,
              },

              {
                label:
                  text.ministry,

                value:
                  data.assignment
                    .ministry
                    .name,
              },

              {
                label:
                  text.assignmentStatus,

                value:
                  data.assignment
                    .status,
              },
            ].map(
              (info) => (
                <Box
                  key={
                    info.label
                  }
                >
                  <Box
                    sx={{
                      color:
                        "text.secondary",

                      fontSize:
                        9.5,
                    }}
                  >
                    {
                      info.label
                    }
                  </Box>

                  <Box
                    component="div"
                    lang={
                      getContentLanguage(
                        info.value,
                      )
                    }
                    className={
                      getContentFontClass(
                        info.value,
                      )
                    }
                    sx={{
                      mt:
                        0.2,

                      color:
                        "text.primary",

                      fontSize:
                        12,

                      fontWeight:
                        700,

                      lineHeight:
                        containsKhmer(
                          info.value,
                        )
                          ? 1.8
                          : 1.5,
                    }}
                  >
                    {
                      info.value
                    }
                  </Box>
                </Box>
              ),
            )}
          </Box>
        </Box>

        {/* OVERVIEW */}
        <Box
          sx={{
            mt:
              1.6,
          }}
        >
          <Box
            sx={{
              mb:
                0.8,

              color:
                "text.primary",

              fontSize:
                13,

              fontWeight:
                800,
            }}
          >
            {
              text.overview
            }
          </Box>

          <Box
            sx={{
              display:
                "grid",

              gridTemplateColumns: {
                xs:
                  "repeat(2, minmax(0, 1fr))",

                sm:
                  "repeat(4, minmax(0, 1fr))",
              },

              gap:
                0.8,
            }}
          >
            {metricData.map(
              (metric) => (
                <Box
                  key={
                    metric.label
                  }
                  sx={{
                    p:
                      1.15,

                    minWidth:
                      0,

                    border:
                      "1px solid",

                    borderColor:
                      "divider",

                    borderRadius:
                      1.5,

                    bgcolor:
                      cardBackground,
                  }}
                >
                  <Box
                    sx={{
                      color:
                        metric.color,

                      fontSize:
                        21,

                      fontWeight:
                        800,

                      lineHeight:
                        1,
                    }}
                  >
                    {
                      metric.value
                    }
                  </Box>

                  <Box
                    sx={{
                      mt:
                        0.45,

                      color:
                        "text.secondary",

                      fontSize:
                        9.5,

                      lineHeight:
                        1.5,
                    }}
                  >
                    {
                      metric.label
                    }
                  </Box>
                </Box>
              ),
            )}
          </Box>
        </Box>

        <Box
          sx={{
            mt:
              1.8,

            mb:
              0.9,

            color:
              "text.primary",

            fontSize:
              13,

            fontWeight:
              800,
          }}
        >
          {text.issues} (
          {data.totalIssues})
        </Box>

        {/* ISSUES */}
        <Box
          sx={{
            display:
              "flex",

            flexDirection:
              "column",

            gap:
              1,
          }}
        >
          {data.items.map(
            (
              item,
              index,
            ) => {
              const evaluation =
                getEvaluation(
                  item,
                );

              const editable =
                editableItems.find(
                  (
                    current,
                  ) =>
                    current.issueId ===
                    item.issueId,
                );

              const issueTitleKhmer =
                containsKhmer(
                  item.title,
                );

              return (
                <Box
                  key={
                    item.issueId
                  }
                  sx={{
                    p:
                      1.5,

                    border:
                      "1px solid",

                    borderColor:
                      "divider",

                    borderRadius:
                      1.7,

                    bgcolor:
                      cardBackground,
                  }}
                >
                  <Box
                    sx={{
                      display:
                        "flex",

                      alignItems:
                        "flex-start",

                      justifyContent:
                        "space-between",

                      gap:
                        1,
                    }}
                  >
                    <Box
                      sx={{
                        minWidth:
                          0,

                        flex:
                          1,
                      }}
                    >
                      <Box
                        sx={{
                          color:
                            "primary.main",

                          fontSize:
                            10,

                          fontWeight:
                            800,
                        }}
                      >
                        {text.issue}{" "}
                        {index +
                          1}
                      </Box>

                      <Box
                        component="div"
                        lang={
                          getContentLanguage(
                            item.title,
                          )
                        }
                        className={
                          getContentFontClass(
                            item.title,
                          )
                        }
                        sx={{
                          mt:
                            0.25,

                          color:
                            "text.primary",

                          fontSize:
                            issueTitleKhmer
                              ? 14
                              : 13,

                          fontWeight:
                            700,

                          lineHeight:
                            issueTitleKhmer
                              ? 1.9
                              : 1.5,
                        }}
                      >
                        {
                          item.title
                        }
                      </Box>
                    </Box>

                    {mode ===
                      "view" &&
                    evaluation ? (
                      <Box
                        component="span"
                        sx={{
                          px:
                            1,

                          py:
                            0.5,

                          flexShrink:
                            0,

                          borderRadius:
                            1,

                          bgcolor:
                            alpha(
                              evaluation.isResolved
                                ? theme.palette.success.main
                                : theme.palette.error.main,
                              theme.palette.mode ===
                                "dark"
                                ? 0.18
                                : 0.1,
                            ),

                          color:
                            evaluation.isResolved
                              ? "success.main"
                              : "error.main",

                          fontSize:
                            10.5,

                          fontWeight:
                            700,
                        }}
                      >
                        {evaluation.isResolved
                          ? text.resolved
                          : text.notResolved}
                      </Box>
                    ) : null}
                  </Box>

                  {/* TAGS */}
                  <Box
                    sx={{
                      mt:
                        0.8,

                      display:
                        "flex",

                      flexWrap:
                        "wrap",

                      gap:
                        0.6,
                    }}
                  >
                    {[
                      item.category
                        .name,

                      item.status
                        .name,

                      item.workingGroup
                        .name,
                    ].map(
                      (value) => (
                        <Box
                          key={
                            value
                          }
                          component="span"
                          lang={
                            getContentLanguage(
                              value,
                            )
                          }
                          className={
                            getContentFontClass(
                              value,
                            )
                          }
                          sx={{
                            px:
                              0.9,

                            py:
                              0.4,

                            borderRadius:
                              1,

                            bgcolor:
                              "action.hover",

                            color:
                              "text.secondary",

                            fontSize:
                              9.5,
                          }}
                        >
                          {
                            value
                          }
                        </Box>
                      ),
                    )}
                  </Box>

                  {/* GOVERNMENT AGENCIES */}
                  {item
                    .governmentAgencies
                    .length >
                  0 ? (
                    <Box
                      sx={{
                        mt:
                          1,
                      }}
                    >
                      <Box
                        sx={{
                          color:
                            "text.secondary",

                          fontSize:
                            9.5,

                          fontWeight:
                            700,
                        }}
                      >
                        {
                          text.governmentAgencies
                        }
                      </Box>

                      <Box
                        sx={{
                          mt:
                            0.5,

                          display:
                            "flex",

                          flexWrap:
                            "wrap",

                          gap:
                            0.5,
                        }}
                      >
                        {item.governmentAgencies.map(
                          (
                            agency,
                          ) => (
                            <Box
                              key={`${item.issueId}-${agency.stakeholder.id}`}
                              component="span"
                              lang={
                                getContentLanguage(
                                  agency
                                    .stakeholder
                                    .name,
                                )
                              }
                              className={
                                getContentFontClass(
                                  agency
                                    .stakeholder
                                    .name,
                                )
                              }
                              sx={{
                                px:
                                  0.8,

                                py:
                                  0.35,

                                border:
                                  "1px solid",

                                borderColor:
                                  "divider",

                                borderRadius:
                                  1,

                                bgcolor:
                                  "action.hover",

                                color:
                                  "text.secondary",

                                fontSize:
                                  9.5,
                              }}
                            >
                              {
                                agency
                                  .stakeholder
                                  .name
                              }
                            </Box>
                          ),
                        )}
                      </Box>
                    </Box>
                  ) : null}

                  {mode ===
                  "view" ? (
                    <>
                      {/* RESULT */}
                      <Box
                        sx={{
                          mt:
                            1,

                          pt:
                            1,

                          borderTop:
                            "1px solid",

                          borderColor:
                            "divider",
                        }}
                      >
                        <Box
                          sx={{
                            color:
                              "text.secondary",

                            fontSize:
                              9.5,

                            fontWeight:
                              700,
                          }}
                        >
                          {
                            text.evaluationResult
                          }
                        </Box>

                        <Box
                          sx={{
                            mt:
                              0.3,

                            color:
                              !evaluation
                                ? "text.secondary"
                                : evaluation.isResolved
                                  ? "success.main"
                                  : "error.main",

                            fontSize:
                              11.5,

                            fontWeight:
                              700,
                          }}
                        >
                          {!evaluation
                            ? text.notEvaluated
                            : evaluation.isResolved
                              ? text.resolved
                              : text.notResolved}
                        </Box>
                      </Box>

                      {/* RATING */}
                      <Box
                        sx={{
                          mt:
                            1,
                        }}
                      >
                        <Box
                          sx={{
                            color:
                              "text.secondary",

                            fontSize:
                              9.5,

                            fontWeight:
                              700,
                          }}
                        >
                          Rating
                        </Box>

                        <Box
                          sx={{
                            mt:
                              0.35,

                            display:
                              "flex",

                            alignItems:
                              "center",

                            gap:
                              0.8,
                          }}
                        >
                          <Rating
                            value={
                              normalizeRating(
                                evaluation
                                  ?.rating,
                              )
                            }
                            max={
                              5
                            }
                            precision={
                              1
                            }
                            readOnly
                            size="small"
                            sx={{
                              color:
                                "#F79009",

                              "& .MuiRating-iconFilled":
                                {
                                  color:
                                    "#F79009",
                                },

                              "& .MuiRating-iconEmpty":
                                {
                                  color:
                                    theme.palette.mode ===
                                    "dark"
                                      ? "#667085"
                                      : "#D0D5DD",
                                },
                            }}
                          />

                          <Box
                            sx={{
                              color:
                                "text.secondary",

                              fontSize:
                                10.5,

                              fontWeight:
                                700,
                            }}
                          >
                            {normalizeRating(
                              evaluation
                                ?.rating,
                            ) >
                            0
                              ? `${normalizeRating(
                                  evaluation
                                    ?.rating,
                                )}/5`
                              : "Not rated"}
                          </Box>
                        </Box>
                      </Box>

                      {/* FEEDBACK */}
                      <Box
                        sx={{
                          mt:
                            1,
                        }}
                      >
                        <Box
                          sx={{
                            color:
                              "text.secondary",

                            fontSize:
                              9.5,

                            fontWeight:
                              700,
                          }}
                        >
                          {
                            text.feedback
                          }
                        </Box>

                        <Box
                          component="div"
                          lang={
                            getContentLanguage(
                              evaluation
                                ?.feedback,
                            )
                          }
                          className={
                            getContentFontClass(
                              evaluation
                                ?.feedback ||
                                text.noFeedback,
                            )
                          }
                          sx={{
                            mt:
                              0.3,

                            color:
                              evaluation
                                ?.feedback
                                ? "text.primary"
                                : "text.secondary",

                            fontSize:
                              containsKhmer(
                                evaluation
                                  ?.feedback,
                              )
                                ? 13
                                : 11.5,

                            lineHeight:
                              containsKhmer(
                                evaluation
                                  ?.feedback,
                              )
                                ? 1.9
                                : 1.6,

                            whiteSpace:
                              "pre-wrap",

                            overflowWrap:
                              "anywhere",
                          }}
                        >
                          {evaluation
                            ?.feedback ||
                            text.noFeedback}
                        </Box>
                      </Box>
                    </>
                  ) : (
                    <>
                      {/* EDIT STATUS */}
                      <Box
                        sx={{
                          mt:
                            1.2,

                          pt:
                            1,

                          borderTop:
                            "1px solid",

                          borderColor:
                            "divider",
                        }}
                      >
                        <Box
                          sx={{
                            mb:
                              0.7,

                            color:
                              "text.primary",

                            fontSize:
                              11,

                            fontWeight:
                              700,
                          }}
                        >
                          {
                            text.evaluationResult
                          }

                          <Box
                            component="span"
                            sx={{
                              ml:
                                0.3,

                              color:
                                "error.main",
                            }}
                          >
                            *
                          </Box>
                        </Box>

                        <Box
                          sx={{
                            display:
                              "flex",

                            flexDirection:
                              "column",

                            gap:
                              0.8,
                          }}
                        >
                          <Box
                            component="label"
                            sx={{
                              display:
                                "flex",

                              alignItems:
                                "center",

                              gap:
                                1,

                              color:
                                "text.primary",

                              fontSize:
                                12,

                              cursor:
                                "pointer",
                            }}
                          >
                            <input
                              type="radio"
                              name={`evaluation-${item.issueId}`}
                              checked={
                                editable
                                  ?.isResolved ===
                                true
                              }
                              onChange={() =>
                                updateItem(
                                  item.issueId,
                                  {
                                    isResolved:
                                      true,
                                  },
                                )
                              }
                            />

                            {
                              text.resolved
                            }
                          </Box>

                          <Box
                            component="label"
                            sx={{
                              display:
                                "flex",

                              alignItems:
                                "center",

                              gap:
                                1,

                              color:
                                "text.primary",

                              fontSize:
                                12,

                              cursor:
                                "pointer",
                            }}
                          >
                            <input
                              type="radio"
                              name={`evaluation-${item.issueId}`}
                              checked={
                                editable
                                  ?.isResolved ===
                                false
                              }
                              onChange={() =>
                                updateItem(
                                  item.issueId,
                                  {
                                    isResolved:
                                      false,
                                  },
                                )
                              }
                            />

                            {
                              text.notResolved
                            }
                          </Box>
                        </Box>
                      </Box>

                      <Box
                        sx={{
                          mt:
                            1.2,
                        }}
                      >
                        <Box
                          sx={{
                            mb:
                              0.7,

                            color:
                              "text.primary",

                            fontSize:
                              11,

                            fontWeight:
                              700,
                          }}
                        >
                          Rating

                          <Box
                            component="span"
                            sx={{
                              ml:
                                0.3,

                              color:
                                "error.main",
                            }}
                          >
                            *
                          </Box>
                        </Box>

                        <Box
                          sx={{
                            display:
                              "flex",

                            alignItems:
                              "center",

                            gap:
                              1,
                          }}
                        >
                          <Rating
                            name={`admin-evaluation-rating-${item.issueId}`}
                            value={
                              editable
                                ?.rating ??
                              0
                            }
                            max={
                              5
                            }
                            precision={
                              1
                            }
                            size="large"
                            onChange={(
                              _event,
                              newValue,
                            ) =>
                              updateItem(
                                item.issueId,
                                {
                                  rating:
                                    newValue ??
                                    0,
                                },
                              )
                            }
                            sx={{
                              color:
                                "#F79009",

                              "& .MuiRating-iconFilled":
                                {
                                  color:
                                    "#F79009",
                                },

                              "& .MuiRating-iconHover":
                                {
                                  color:
                                    "#FDB022",
                                },

                              "& .MuiRating-iconEmpty":
                                {
                                  color:
                                    theme.palette.mode ===
                                    "dark"
                                      ? "#667085"
                                      : "#D0D5DD",
                                },
                            }}
                          />

                          {(
                            editable
                              ?.rating ??
                            0
                          ) >
                          0 ? (
                            <Box
                              sx={{
                                color:
                                  "text.secondary",

                                fontSize:
                                  11,

                                fontWeight:
                                  700,
                              }}
                            >
                              {
                                editable
                                  ?.rating
                              }
                              /5
                            </Box>
                          ) : null}
                        </Box>
                      </Box>

                      <Box
                        sx={{
                          mt:
                            1.2,
                        }}
                      >
                        <Box
                          sx={{
                            mb:
                              0.6,

                            color:
                              "text.primary",

                            fontSize:
                              11,

                            fontWeight:
                              700,
                          }}
                        >
                          {
                            text.feedback
                          }

                          <Box
                            component="span"
                            sx={{
                              ml:
                                0.3,

                              color:
                                "error.main",
                            }}
                          >
                            *
                          </Box>
                        </Box>

                        <Box
                          component="textarea"
                          rows={
                            4
                          }
                          lang={
                            getContentLanguage(
                              editable
                                ?.feedback,
                            )
                          }
                          className={
                            getContentFontClass(
                              editable
                                ?.feedback ||
                                text.writeFeedback,
                            )
                          }
                          value={
                            editable
                              ?.feedback ??
                            ""
                          }
                          placeholder={
                            text.writeFeedback
                          }
                          onChange={(
                            event:
                              ChangeEvent<HTMLTextAreaElement>,
                          ) =>
                            updateItem(
                              item.issueId,
                              {
                                feedback:
                                  event
                                    .target
                                    .value,
                              },
                            )
                          }
                          sx={{
                            width:
                              "100%",

                            minHeight:
                              110,

                            p:
                              1.2,

                            boxSizing:
                              "border-box",

                            resize:
                              "vertical",

                            outline:
                              "none",

                            border:
                              "1px solid",

                            borderColor:
                              "divider",

                            borderRadius:
                              1.5,

                            bgcolor:
                              "background.paper",

                            color:
                              "text.primary",

                            fontSize:
                              containsKhmer(
                                editable
                                  ?.feedback,
                              )
                                ? 13
                                : 12,

                            lineHeight:
                              containsKhmer(
                                editable
                                  ?.feedback,
                              )
                                ? 1.9
                                : 1.6,

                            "&:focus": {
                              borderColor:
                                "primary.main",
                            },

                            "&::placeholder":
                              {
                                color:
                                  "text.disabled",

                                opacity:
                                  1,
                              },
                          }}
                        />
                      </Box>
                    </>
                  )}
                </Box>
              );
            },
          )}
        </Box>
      </Box>

      {/* FOOTER */}
      <Box
        sx={{
          minHeight:
            70,

          px:
            2.2,

          display:
            "flex",

          alignItems:
            "center",

          justifyContent:
            "flex-end",

          gap:
            1,

          flexShrink:
            0,

          bgcolor:
            "background.paper",

          borderTop:
            "1px solid",

          borderColor:
            "divider",
        }}
      >
        {mode ===
          "edit" &&
        canEdit ? (
          <>
            <Box
              component="button"
              type="button"
              disabled={
                saving
              }
              onClick={
                cancelEdit
              }
              sx={{
                minWidth:
                  120,

                height:
                  40,

                border:
                  "1px solid",

                borderColor:
                  "divider",

                borderRadius:
                  1.5,

                bgcolor:
                  "background.paper",

                color:
                  "text.primary",

                fontWeight:
                  600,

                cursor:
                  saving
                    ? "not-allowed"
                    : "pointer",
              }}
            >
              {
                text.cancel
              }
            </Box>

            <Box
              component="button"
              type="button"
              disabled={
                !canSave ||
                saving
              }
              onClick={() =>
                void save()
              }
              sx={{
                minWidth:
                  140,

                height:
                  40,

                border:
                  0,

                borderRadius:
                  1.5,

                bgcolor:
                  !canSave ||
                  saving
                    ? "action.disabledBackground"
                    : "primary.main",

                color:
                  !canSave ||
                  saving
                    ? "text.disabled"
                    : "primary.contrastText",

                fontWeight:
                  700,

                cursor:
                  !canSave ||
                  saving
                    ? "not-allowed"
                    : "pointer",
              }}
            >
              {saving
                ? text.saving
                : text.saveChanges}
            </Box>
          </>
        ) : (
          <Box
            component="button"
            type="button"
            onClick={
              onClose
            }
            sx={{
              minWidth:
                120,

              height:
                40,

              border:
                "1px solid",

              borderColor:
                "divider",

              borderRadius:
                1.5,

              bgcolor:
                "background.paper",

              color:
                "text.primary",

              fontWeight:
                600,

              cursor:
                "pointer",
            }}
          >
            {
              text.close
            }
          </Box>
        )}
      </Box>
    </Box>
  );
}

export function EvaluationViewDetail({
  open,
  mode,
  data,
  saving = false,
  error = null,
  onClose,
  onModeChange,
  onSave,
}: Props) {
  const pathname =
    usePathname();

  const canEdit =
    pathname ===
      "/admin" ||
    pathname.startsWith(
      "/admin/",
    );

  const safeMode:
    EvaluationDetailMode =
    canEdit
      ? mode
      : "view";

  const effectiveSaving =
    canEdit
      ? saving
      : false;

  useEffect(() => {
    if (!open) {
      return;
    }

    const previousOverflow =
      document.body.style
        .overflow;

    document.body.style.overflow =
      "hidden";

    function handleKeyDown(
      event:
        KeyboardEvent,
    ) {
      if (
        event.key ===
          "Escape" &&
        !effectiveSaving
      ) {
        onClose();
      }
    }

    window.addEventListener(
      "keydown",
      handleKeyDown,
    );

    return () => {
      document.body.style.overflow =
        previousOverflow;

      window.removeEventListener(
        "keydown",
        handleKeyDown,
      );
    };
  }, [
    open,
    effectiveSaving,
    onClose,
  ]);

  const contentKey =
    useMemo(() => {
      if (!data) {
        return `${safeMode}-empty`;
      }

      const versions =
        data.items.map(
          (item) => {
            const evaluation =
              getEvaluation(
                item,
              );

            return [
              item.issueId,
              evaluation?.updatedAt ?? "",
              evaluation?.isResolved ?? "",
              normalizeRating(
                evaluation?.rating,
              ),
              evaluation?.feedback ?? "",
            ].join("-");
          },
        );

      return [
        safeMode,
        ...versions,
      ].join("|");
    }, [
      data,
      safeMode,
    ]);

  if (!open) {
    return null;
  }

  return (
    <Box
      sx={{
        position:
          "fixed",

        inset:
          0,

        zIndex:
          1600,

        display:
          "flex",

        justifyContent:
          "flex-end",
      }}
    >
      <Box
        aria-hidden="true"
        onClick={() => {
          if (
            !effectiveSaving
          ) {
            onClose();
          }
        }}
        sx={{
          position:
            "absolute",

          inset:
            0,

          bgcolor:
            "rgba(15,23,42,.55)",
        }}
      />

      {data ? (
        <DetailContent
          key={
            contentKey
          }
          mode={
            safeMode
          }
          data={
            data
          }
          saving={
            effectiveSaving
          }
          error={
            error
          }

          canEdit={
            canEdit
          }
          onClose={
            onClose
          }

          onModeChange={
            canEdit
              ? onModeChange
              : undefined
          }

          onSave={
            canEdit
              ? onSave
              : undefined
          }
        />
      ) : null}
    </Box>
  );
}