"use client";

import { useMemo } from "react";

import type { GridColDef } from "@mui/x-data-grid";

import { DataTable, DataTableNumberCell } from "@/components/ui/data-table";

import type { CdcIssueMatrixRow } from "./cdc-issue-matrix-data";
import {
  getCdcIssueMatrixColumns,
  type CdcIssueMatrixColumn,
} from "./cdc-issue-matrix-table-config";
import {
  CdcIssueMatrixTableCell,
  type PlenaryEscalationControl,
} from "./cdc-issue-matrix-table-cells";
import type {
  MinistryEditControl,
  StatusEditControl,
} from "./cdc-issue-matrix-row-editors";
import {
  cdcIssueMatrixText,
  type IssueMatrixLanguage,
} from "./cdc-issue-matrix-i18n";

const PAGE_SIZE = 8;
const ROW_HEIGHT = 74;
const HEADER_HEIGHT = 56;

type CdcIssueMatrixTableProps = {
  rows: CdcIssueMatrixRow[];
  language: IssueMatrixLanguage;
  loading?: boolean;
  error?: string | null;
  showRemark?: boolean;
  plenaryEscalationControl?: PlenaryEscalationControl;
  ministryEditControl?: MinistryEditControl;
  statusEditControl?: StatusEditControl;
  onEdit?: (row: CdcIssueMatrixRow) => void;
  onRemove?: (row: CdcIssueMatrixRow) => void;
};

function getColumnWidth(column: CdcIssueMatrixColumn) {
  const width = Number.parseInt(column.width.replace("px", ""), 10);

  return Number.isNaN(width) ? 180 : width;
}

// Everything a cell may need, kept in one object so the column builder does not
// grow another positional parameter each time a column becomes editable.
type CdcIssueMatrixCellOptions = {
  rows: CdcIssueMatrixRow[];
  language: IssueMatrixLanguage;
  plenaryEscalationControl?: PlenaryEscalationControl;
  ministryEditControl?: MinistryEditControl;
  statusEditControl?: StatusEditControl;
  onEdit?: (row: CdcIssueMatrixRow) => void;
  onRemove?: (row: CdcIssueMatrixRow) => void;
};

function toDataGridColumn(
  column: CdcIssueMatrixColumn,
  options: CdcIssueMatrixCellOptions,
): GridColDef<CdcIssueMatrixRow> {
  const { rows, language } = options;
  const width = getColumnWidth(column);
  const isActionColumn = column.key === "action";
  const isCenteredColumn =
    column.key === "id" ||
    column.key === "workingGroup" ||
    column.key === "plenaryEscalation" ||
    column.key === "status" ||
    isActionColumn;

  return {
    field: column.key,
    headerName: column.label,
    width,
    minWidth: width,
    align: isCenteredColumn ? "center" : "left",
    headerAlign: isCenteredColumn ? "center" : "left",
    sortable: !isActionColumn,
    filterable: !isActionColumn,
    renderCell: (params) =>
      column.key === "id" ? (
        <DataTableNumberCell
          value={
            rows.length -
            (params.api.state.pagination.paginationModel.page *
              params.api.state.pagination.paginationModel.pageSize +
              params.api.getRowIndexRelativeToVisibleRows(params.row.id))
          }
        />
      ) : (
        <CdcIssueMatrixTableCell
          key={`${params.row.id}-${options.ministryEditControl?.selectionResetKey ?? 0}`}
          value={params.value ?? ""}
          columnKey={String(column.key)}
          image={
            column.key === "primaryAgency"
              ? (params.row.primaryAgencyImage ?? undefined)
              : undefined
          }
          language={language}
          row={params.row}
          plenaryEscalationControl={options.plenaryEscalationControl}
          ministryEditControl={options.ministryEditControl}
          statusEditControl={options.statusEditControl}
          onEdit={options.onEdit}
          onRemove={options.onRemove}
        />
      ),
  };
}

export function CdcIssueMatrixTable({
  rows,
  language,
  loading = false,
  error = null,
  showRemark = false,
  plenaryEscalationControl,
  ministryEditControl,
  statusEditControl,
  onEdit,
  onRemove,
}: CdcIssueMatrixTableProps) {
  const text = cdcIssueMatrixText[language] ?? cdcIssueMatrixText.en;
  const columns = useMemo(
    () =>
      getCdcIssueMatrixColumns(language)
        .filter((column) => showRemark || column.key !== "remark")
        .map((column) =>
          toDataGridColumn(column, {
            rows,
            language,
            plenaryEscalationControl,
            ministryEditControl,
            statusEditControl,
            onEdit,
            onRemove,
          }),
        ),
    [
      language,
      rows,
      showRemark,
      plenaryEscalationControl,
      ministryEditControl,
      statusEditControl,
      onEdit,
      onRemove,
    ],
  );

  return (
    <DataTable
      fillAvailableHeight
      rows={rows}
      columns={columns}
      getRowId={(row) => row.id}
      loading={loading}
      error={error}
      enableColumnMenu
      emptyMessage={text.noData}
      pageSize={PAGE_SIZE}
      rowHeight={ROW_HEIGHT}
      columnHeaderHeight={HEADER_HEIGHT}
      dataGridSx={{
        "& .MuiDataGrid-columnHeaderTitle": {
          lineHeight: 1.25,
          overflow: "visible",
          whiteSpace: "normal",
        },
        "& .MuiDataGrid-cell": {
          overflow: "hidden",
        },
        "& .MuiDataGrid-cell[data-field='workingGroup']": {
          alignItems: "center",
          justifyContent: "center",
          py: 1.25,
        },
      }}
    />
  );
}
