"use client";

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

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

import ChevronLeftRoundedIcon from "@mui/icons-material/ChevronLeftRounded";
import ChevronRightRoundedIcon from "@mui/icons-material/ChevronRightRounded";
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 {
  AdminEvaluationRow,
} from "../types/evaluation-form.types";

import {
  MoreIcon,
} 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";
}

type Props = {
  rows:
    AdminEvaluationRow[];

  loading?: boolean;

  onView?: (
    row:
      AdminEvaluationRow,
  ) => void;

  /**
   * Admin only.
   *
   * If undefined:
   * Edit action will not be displayed.
   */
  onEdit?: (
    row:
      AdminEvaluationRow,
  ) => void;

  pageSize?: number;
};

type ActionMenuState = {
  row:
    AdminEvaluationRow;

  top:
    number;

  left:
    number;
};

export function EvaluationSubmissionsTable({
  rows,
  loading = false,
  onView,
  onEdit,
  pageSize = 10,
}: Props) {
  const theme =
    useTheme();

  const {
    language,
  } =
    useAppLanguage();

  const lang =
    normalizeEvaluationFormLanguage(
      language,
    );

  const text =
    evaluationFormText[
      lang
    ];

  const uiFontClass =
    getEvaluationFormFontClass(
      lang,
    );

  /**
   * Only show Edit when parent
   * provides onEdit.
   *
   * Admin -> onEdit exists
   * Other roles -> undefined
   */
  const canEdit =
    typeof onEdit ===
    "function";

  const [
    page,
    setPage,
  ] =
    useState(1);

  const [
    actionMenu,
    setActionMenu,
  ] =
    useState<ActionMenuState | null>(
      null,
    );

  const totalPages =
    Math.max(
      1,
      Math.ceil(
        rows.length /
          pageSize,
      ),
    );

  const currentPage =
    Math.min(
      page,
      totalPages,
    );

  const visibleRows =
    useMemo(() => {
      const start =
        (currentPage -
          1) *
        pageSize;

      return rows.slice(
        start,
        start +
          pageSize,
      );
    }, [
      rows,
      currentPage,
      pageSize,
    ]);

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

    function closeMenu() {
      setActionMenu(
        null,
      );
    }

    function handleOutsideClick(
      event:
        PointerEvent,
    ) {
      const target =
        event.target as HTMLElement | null;

      if (
        target?.closest(
          "[data-evaluation-menu]",
        ) ||
        target?.closest(
          "[data-evaluation-action]",
        )
      ) {
        return;
      }

      closeMenu();
    }

    document.addEventListener(
      "pointerdown",
      handleOutsideClick,
    );

    window.addEventListener(
      "resize",
      closeMenu,
    );

    window.addEventListener(
      "scroll",
      closeMenu,
      true,
    );

    return () => {
      document.removeEventListener(
        "pointerdown",
        handleOutsideClick,
      );

      window.removeEventListener(
        "resize",
        closeMenu,
      );

      window.removeEventListener(
        "scroll",
        closeMenu,
        true,
      );
    };
  }, [
    actionMenu,
  ]);

  function formatDate(
    value:
      string | null,
  ) {
    if (!value) {
      return "-";
    }

    const date =
      new Date(
        value,
      );

    if (
      Number.isNaN(
        date.getTime(),
      )
    ) {
      return "-";
    }

    return new Intl.DateTimeFormat(
      lang === "kh"
        ? "km-KH"
        : "en-US",
      {
        month:
          "short",

        day:
          "numeric",

        year:
          "numeric",
      },
    ).format(
      date,
    );
  }

  function getStatusLabel(
    status:
      AdminEvaluationRow["status"],
  ) {
    if (
      status ===
      "Reviewed"
    ) {
      return text.reviewedStatus;
    }

    if (
      status ===
      "Completed"
    ) {
      return text.completedStatus;
    }

    return text.pendingReviewStatus;
  }

  function getStatusColor(
    status:
      AdminEvaluationRow["status"],
  ) {
    if (
      status ===
      "Completed"
    ) {
      return theme.palette.success.main;
    }

    if (
      status ===
      "Reviewed"
    ) {
      return theme.palette.info.main;
    }

    return theme.palette.warning.main;
  }

  function openActionMenu(
    event:
      MouseEvent<HTMLButtonElement>,

    row:
      AdminEvaluationRow,
  ) {
    const rect =
      event.currentTarget.getBoundingClientRect();

    const width =
      150;

    setActionMenu({
      row,

      top:
        rect.bottom +
        6,

      left:
        Math.min(
          window.innerWidth -
            width -
            10,

          Math.max(
            10,
            rect.right -
              width,
          ),
        ),
    });
  }

  function goToPage(
    nextPage:
      number,
  ) {
    if (
      nextPage <
        1 ||
      nextPage >
        totalPages
    ) {
      return;
    }

    setPage(
      nextPage,
    );

    setActionMenu(
      null,
    );
  }

  const headerBackground =
    theme.palette.mode ===
    "dark"
      ? alpha(
          theme.palette.common.white,
          0.06,
        )
      : alpha(
          theme.palette.primary.main,
          0.06,
        );

  const cellStyle = {
    padding:
      "15px 14px",

    color:
      theme.palette.text.primary,

    borderBottom:
      `1px solid ${theme.palette.divider}`,
  };

  return (
    <>
      <Box
        className={
          uiFontClass
        }
        sx={{
          width:
            "100%",

          minHeight: {
            xs:
              420,

            md:
              "calc(100dvh - 100px)",
          },

          display:
            "flex",

          flexDirection:
            "column",

          overflow:
            "hidden",

          bgcolor:
            "background.paper",

          color:
            "text.primary",

          border:
            "1px solid",

          borderColor:
            "divider",

          borderRadius:
            2,
        }}
      >
        <Box
          sx={{
            width:
              "100%",

            overflowX:
              "auto",

            flexShrink:
              0,
          }}
        >
          <table
            style={{
              width:
                "100%",

              minWidth:
                900,

              tableLayout:
                "fixed",

              borderCollapse:
                "collapse",
            }}
          >
            <colgroup>
              <col
                style={{
                  width:
                    "5%",
                }}
              />

              <col
                style={{
                  width:
                    "38%",
                }}
              />

              <col
                style={{
                  width:
                    "10%",
                }}
              />

              <col
                style={{
                  width:
                    "15%",
                }}
              />

              <col
                style={{
                  width:
                    "13%",
                }}
              />

              <col
                style={{
                  width:
                    "13%",
                }}
              />

              <col
                style={{
                  width:
                    "6%",
                }}
              />
            </colgroup>

            <thead>
              <tr>
                {[
                  text.no,
                  text.progressReport,
                  text.totalIssues,
                  text.submittedBy,
                  text.submittedDate,
                  text.status,
                  text.actions,
                ].map(
                  (
                    label,
                    index,
                  ) => (
                    <th
                      key={`${index}-${label}`}
                      style={{
                        padding:
                          "13px 14px",

                        textAlign:
                          "left",

                        whiteSpace:
                          "nowrap",

                        color:
                          theme.palette.text.primary,

                        background:
                          headerBackground,

                        borderBottom:
                          `1px solid ${theme.palette.divider}`,

                        fontSize:
                          11,

                        fontWeight:
                          700,
                      }}
                    >
                      {
                        label
                      }
                    </th>
                  ),
                )}
              </tr>
            </thead>

            <tbody>
              {loading ? (
                <tr>
                  <td
                    colSpan={
                      7
                    }
                    style={{
                      padding:
                        "35px",

                      textAlign:
                        "center",

                      color:
                        theme.palette.text.secondary,
                    }}
                  >
                    {
                      text.loading
                    }
                  </td>
                </tr>
              ) : null}

              {!loading &&
              rows.length ===
                0 ? (
                <tr>
                  <td
                    colSpan={
                      7
                    }
                    style={{
                      padding:
                        "35px",

                      textAlign:
                        "center",

                      color:
                        theme.palette.text.secondary,
                    }}
                  >
                    {
                      text.noData
                    }
                  </td>
                </tr>
              ) : null}

              {!loading &&
                visibleRows.map(
                  (
                    row,
                    index,
                  ) => {
                    const rowNumber =
                      (currentPage -
                        1) *
                        pageSize +
                      index +
                      1;

                    const statusColor =
                      getStatusColor(
                        row.status,
                      );

                    const titleIsKhmer =
                      containsKhmer(
                        row.progressReportTitle,
                      );

                    return (
                      <tr
                        key={
                          row.id
                        }
                      >
                        <td
                          style={
                            cellStyle
                          }
                        >
                          {
                            rowNumber
                          }
                        </td>

                        <td
                          style={{
                            ...cellStyle,

                            padding:
                              titleIsKhmer
                                ? "10px 14px"
                                : "15px 14px",
                          }}
                        >
                          <div
                            lang={
                              getContentLanguage(
                                row.progressReportTitle,
                              )
                            }
                            className={
                              getContentFontClass(
                                row.progressReportTitle,
                              )
                            }
                            title={
                              row.progressReportTitle
                            }
                            style={{
                              width:
                                "100%",

                              overflow:
                                "hidden",

                              textOverflow:
                                "ellipsis",

                              whiteSpace:
                                "nowrap",

                              color:
                                theme.palette.text.primary,

                              fontSize:
                                titleIsKhmer
                                  ? 14
                                  : 12.5,

                              fontWeight:
                                600,

                              lineHeight:
                                titleIsKhmer
                                  ? 1.9
                                  : 1.5,
                            }}
                          >
                            {
                              row.progressReportTitle
                            }
                          </div>
                        </td>

                        <td
                          style={
                            cellStyle
                          }
                        >
                          {
                            row.totalIssues
                          }
                        </td>

                        <td
                          style={
                            cellStyle
                          }
                        >
                          {
                            row.submittedBy
                          }
                        </td>

                        <td
                          style={{
                            ...cellStyle,

                            whiteSpace:
                              "nowrap",
                          }}
                        >
                          {formatDate(
                            row.submittedDate,
                          )}
                        </td>

                        <td
                          style={
                            cellStyle
                          }
                        >
                          <span
                            style={{
                              display:
                                "inline-flex",

                              padding:
                                "5px 9px",

                              borderRadius:
                                6,

                              color:
                                statusColor,

                              background:
                                alpha(
                                  statusColor,
                                  theme.palette.mode ===
                                    "dark"
                                    ? 0.18
                                    : 0.1,
                                ),

                              fontSize:
                                11,

                              fontWeight:
                                700,

                              whiteSpace:
                                "nowrap",
                            }}
                          >
                            {getStatusLabel(
                              row.status,
                            )}
                          </span>
                        </td>

                        <td
                          style={
                            cellStyle
                          }
                        >
                          <button
                            type="button"
                            data-evaluation-action
                            aria-label="Evaluation actions"
                            onClick={(
                              event,
                            ) =>
                              openActionMenu(
                                event,
                                row,
                              )
                            }
                            style={{
                              width:
                                32,

                              height:
                                32,

                              display:
                                "grid",

                              placeItems:
                                "center",

                              border:
                                `1px solid ${theme.palette.divider}`,

                              borderRadius:
                                6,

                              background:
                                theme.palette.background.paper,

                              color:
                                theme.palette.text.secondary,

                              cursor:
                                "pointer",
                            }}
                          >
                            <MoreIcon
                              size={
                                17
                              }
                            />
                          </button>
                        </td>
                      </tr>
                    );
                  },
                )}
            </tbody>
          </table>
        </Box>

        <Box
          sx={{
            flex:
              1,

            minHeight:
              30,
          }}
        />

        {!loading &&
        rows.length >
          0 ? (
          <Box
            sx={{
              minHeight:
                72,

              px:
                2.5,

              py:
                1.5,

              display:
                "grid",

              gridTemplateColumns:
                "1fr auto 1fr",

              alignItems:
                "center",

              gap:
                1,

              bgcolor:
                "background.paper",

              borderTop:
                "1px solid",

              borderColor:
                "divider",

              flexShrink:
                0,
            }}
          >
            <Box>
              <Box
                component="button"
                type="button"
                disabled={
                  currentPage <=
                  1
                }
                onClick={() =>
                  goToPage(
                    currentPage -
                      1,
                  )
                }
                sx={{
                  minWidth:
                    120,

                  height:
                    42,

                  px:
                    1.5,

                  display:
                    "inline-flex",

                  alignItems:
                    "center",

                  justifyContent:
                    "center",

                  gap:
                    0.5,

                  border:
                    "1px solid",

                  borderColor:
                    "divider",

                  borderRadius:
                    1.5,

                  bgcolor:
                    "background.paper",

                  color:
                    currentPage <=
                    1
                      ? "text.disabled"
                      : "text.primary",

                  cursor:
                    currentPage <=
                    1
                      ? "not-allowed"
                      : "pointer",

                  fontWeight:
                    600,
                }}
              >
                <ChevronLeftRoundedIcon
                  sx={{
                    fontSize:
                      18,
                  }}
                />

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

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

                alignItems:
                  "center",

                gap:
                  0.5,
              }}
            >
              {Array.from(
                {
                  length:
                    totalPages,
                },

                (
                  _,
                  index,
                ) =>
                  index +
                  1,
              ).map(
                (
                  pageNumber,
                ) => (
                  <Box
                    key={
                      pageNumber
                    }
                    component="button"
                    type="button"
                    onClick={() =>
                      goToPage(
                        pageNumber,
                      )
                    }
                    sx={{
                      width:
                        46,

                      height:
                        46,

                      display:
                        "grid",

                      placeItems:
                        "center",

                      border:
                        0,

                      borderRadius:
                        1.5,

                      bgcolor:
                        currentPage ===
                        pageNumber
                          ? "primary.main"
                          : "transparent",

                      color:
                        currentPage ===
                        pageNumber
                          ? "primary.contrastText"
                          : "text.secondary",

                      fontWeight:
                        700,

                      cursor:
                        "pointer",
                    }}
                  >
                    {
                      pageNumber
                    }
                  </Box>
                ),
              )}
            </Box>

            <Box
              sx={{
                justifySelf:
                  "end",
              }}
            >
              <Box
                component="button"
                type="button"
                disabled={
                  currentPage >=
                  totalPages
                }
                onClick={() =>
                  goToPage(
                    currentPage +
                      1,
                  )
                }
                sx={{
                  minWidth:
                    100,

                  height:
                    42,

                  px:
                    1.5,

                  display:
                    "inline-flex",

                  alignItems:
                    "center",

                  justifyContent:
                    "center",

                  gap:
                    0.5,

                  border:
                    "1px solid",

                  borderColor:
                    "divider",

                  borderRadius:
                    1.5,

                  bgcolor:
                    "background.paper",

                  color:
                    currentPage >=
                    totalPages
                      ? "text.disabled"
                      : "text.primary",

                  cursor:
                    currentPage >=
                    totalPages
                      ? "not-allowed"
                      : "pointer",

                  fontWeight:
                    600,
                }}
              >
                {
                  text.next
                }

                <ChevronRightRoundedIcon
                  sx={{
                    fontSize:
                      18,
                  }}
                />
              </Box>
            </Box>
          </Box>
        ) : null}
      </Box>

      {/* ==========================================
          ACTION MENU
          ========================================== */}
      {actionMenu ? (
        <Box
          data-evaluation-menu
          className={
            uiFontClass
          }
          sx={{
            position:
              "fixed",

            top:
              actionMenu.top,

            left:
              actionMenu.left,

            width:
              150,

            zIndex:
              9999,

            p:
              0.6,

            bgcolor:
              "background.paper",

            color:
              "text.primary",

            border:
              "1px solid",

            borderColor:
              "divider",

            borderRadius:
              1.5,

            boxShadow:
              theme.shadows[8],
          }}
        >
          {/* ==========================================
              VIEW - ALL ROLES
              ========================================== */}
          <Box
            component="button"
            type="button"
            onClick={() => {
              const row =
                actionMenu.row;

              setActionMenu(
                null,
              );

              onView?.(
                row,
              );
            }}
            sx={{
              width:
                "100%",

              height:
                38,

              px:
                1,

              display:
                "flex",

              alignItems:
                "center",

              gap:
                1,

              border:
                0,

              borderRadius:
                1,

              bgcolor:
                "transparent",

              color:
                "text.primary",

              cursor:
                "pointer",

              "&:hover": {
                bgcolor:
                  "action.hover",
              },
            }}
          >
            <EyeViewIcon
              sx={{
                fontSize:
                  18,

                color:
                  "primary.main",
              }}
            />

            {
              text.view
            }
          </Box>

          {/* ==========================================
              EDIT - ADMIN ONLY

              UI/STYLE SAME AS OLD.
              Only visibility is controlled by onEdit.
              ========================================== */}
          {canEdit ? (
            <Box
              component="button"
              type="button"
              onClick={() => {
                const row =
                  actionMenu.row;

                setActionMenu(
                  null,
                );

                onEdit?.(
                  row,
                );
              }}
              sx={{
                width:
                  "100%",

                height:
                  38,

                px:
                  1,

                display:
                  "flex",

                alignItems:
                  "center",

                gap:
                  1,

                border:
                  0,

                borderRadius:
                  1,

                bgcolor:
                  "transparent",

                color:
                  "text.primary",

                cursor:
                  "pointer",

                "&:hover": {
                  bgcolor:
                    "action.hover",
                },
              }}
            >
              <EditOutlinedIcon
                sx={{
                  fontSize:
                    18,

                  color:
                    "warning.main",
                }}
              />

              {
                text.edit
              }
            </Box>
          ) : null}
        </Box>
      ) : null}
    </>
  );
}