"use client";

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

import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";
import type { GridPaginationModel } from "@mui/x-data-grid";

import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import { DataTable } from "@/components/ui/data-table";
import { ToastNotification } from "@/components/ui/toast-notification";
import { usePermissions } from "@/features/auth/hook/use-permissions";
import { APP_PERMISSIONS } from "@/features/auth/permissions";
import { EditIssueDialog } from "@/features/pswg/working-group-issues/components/create-issuses";
import {
  WG_ISSUES_PAGE_SIZE,
  type WgIssuesViewMode,
} from "@/features/pswg/working-group-issues/components/table/wg-issues-table-config";
import { getWgIssuesTableColumns } from "@/features/pswg/working-group-issues/components/table/wg-issues-table-columns";
import {
  ActionCell,
  AgencyCell,
  ReferenceCell,
  StatusBadge,
  type WgIssueActionAccess,
  type WgIssueActionHandlers,
} from "@/features/pswg/working-group-issues/components/table/wg-issues-table-cells";
import { WgIssuesTableFooter } from "@/features/pswg/working-group-issues/components/table/wg-issues-table-footer";
import { useDeleteWorkingGroupIssue } from "@/features/pswg/working-group-issues/hook/use-working-group-issues";
import {
  wgAIssueRows,
  type IssueRow,
} from "@/features/pswg/working-group-issues/wg-issues-data";
import {
  tWgIssues,
  translateWgIssuesText,
  type WgIssuesLanguage,
} from "@/features/pswg/working-group-issues/wg-issues-i18n";

function getOptionalValue(
  row: IssueRow,
  keys: string[],
  fallback = "Not available",
): string {
  const rowRecord = row as unknown as Record<string, unknown>;

  for (const key of keys) {
    const value = rowRecord[key];

    if (typeof value === "string" && value.trim().length > 0) {
      return value;
    }

    if (typeof value === "number" && Number.isFinite(value)) {
      return String(value);
    }
  }

  return fallback;
}

function GridInfoItem({
  label,
  children,
  labelWidth = 130,
  valueAlign = "left",
}: {
  label: string;
  children: ReactNode;
  labelWidth?: number;
  valueAlign?: "left" | "right" | "center";
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  return (
    <Box
      sx={{
        display: "grid",
        gridTemplateColumns: `${labelWidth}px minmax(0, 1fr)`,
        alignItems: "center",
        columnGap: 1.5,
        minWidth: 0,
      }}
    >
      <Typography
        sx={{
          color: isDark ? alpha("#ffffff", 0.6) : "#717680",
          fontSize: 12,
          fontWeight: 500,
          whiteSpace: "nowrap",
        }}
      >
        {label}
      </Typography>

      <Box
        sx={{
          minWidth: 0,
          width: "100%",
          display: "flex",
          alignItems: "center",
          justifyContent:
            valueAlign === "right"
              ? "flex-end"
              : valueAlign === "center"
                ? "center"
                : "flex-start",
        }}
      >
        {children}
      </Box>
    </Box>
  );
}

function GridText({
  value,
  noWrap = true,
}: {
  value: string;
  noWrap?: boolean;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  return (
    <Typography
      noWrap={noWrap}
      sx={{
        color: isDark ? "#ffffff" : "#252b37",
        fontSize: 12,
        fontWeight: 500,
        lineHeight: 1.5,
        ...(noWrap
          ? {}
          : {
              display: "-webkit-box",
              WebkitLineClamp: 4,
              WebkitBoxOrient: "vertical",
              overflow: "hidden",
            }),
      }}
    >
      {value}
    </Typography>
  );
}

function SectionLabel({ children }: { children: ReactNode }) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  return (
    <Typography
      sx={{
        mb: 0.75,
        color: isDark ? alpha("#ffffff", 0.6) : "#717680",
        fontSize: 12,
        fontWeight: 500,
      }}
    >
      {children}
    </Typography>
  );
}

function WgIssueGridCard({
  access,
  row,
  language,
  handlers,
}: {
  access: WgIssueActionAccess;
  row: IssueRow;
  language: WgIssuesLanguage;
  handlers: WgIssueActionHandlers;
}) {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  const submittedDate = getOptionalValue(
    row,
    ["submittedDate", "submitted_date", "createdAt", "created_at"],
    "../../....",
  );

  const fileLabel = getOptionalValue(
    row,
    ["file", "attachment", "issueReference", "solutionReference"],
    "",
  );

  return (
    <Paper
      elevation={0}
      sx={{
        borderRadius: "12px",
        border: `1px solid ${isDark ? alpha("#ffffff", 0.1) : "#f5f5f5"}`,
        bgcolor: isDark ? "#111827" : "#ffffff",
        px: { xs: 2, md: 2.5 },
        py: { xs: 2, md: 2.25 },
      }}
    >
      <Box
        sx={{
          display: "flex",
          alignItems: "flex-start",
          justifyContent: "space-between",
          gap: 2,
        }}
      >
        <Typography
          sx={{
            color: isDark ? "#ffffff" : "#252b37",
            fontSize: 15,
            fontWeight: 600,
            lineHeight: 1.4,
          }}
        >
          {row.issue}
        </Typography>

        <ActionCell
          access={access}
          row={row}
          language={language}
          {...handlers}
        />
      </Box>

      <Box
        sx={{
          mt: 2.25,
          display: "grid",
          gridTemplateColumns: {
            xs: "1fr",
            md: "minmax(0, 1.05fr) minmax(0, 0.75fr) minmax(0, 1fr)",
          },
          columnGap: { xs: 2, md: 4, lg: 5 },
          rowGap: 2.25,
          alignItems: "start",
        }}
      >
        <Box sx={{ minWidth: 0 }}>
          <GridInfoItem
            label={`${tWgIssues(language, "issueCategory")} :`}
            labelWidth={135}
          >
            <GridText value={translateWgIssuesText(language, row.category)} />
          </GridInfoItem>
        </Box>

        <Box sx={{ minWidth: 0 }}>
          <GridInfoItem
            label={`${tWgIssues(language, "submittedDate")} :`}
            labelWidth={135}
          >
            <GridText value={submittedDate} />
          </GridInfoItem>
        </Box>

        <Box sx={{ minWidth: 0 }}>
          <GridInfoItem
            label={`${tWgIssues(language, "file")} :`}
            labelWidth={65}
          >
            {fileLabel ? (
              <ReferenceCell label={fileLabel} />
            ) : (
              <GridText value={tWgIssues(language, "notAvailable")} />
            )}
          </GridInfoItem>
        </Box>

        <Box sx={{ minWidth: 0 }}>
          <GridInfoItem
            label={`${tWgIssues(language, "primaryAgency")} :`}
            labelWidth={135}
          >
            <AgencyCell
              agency={row.primaryAgency}
              logo={row.primaryAgencyLogo}
            />
          </GridInfoItem>
        </Box>

        <Box sx={{ minWidth: 0 }}>
          <GridInfoItem
            label={`${tWgIssues(language, "status")} :`}
            labelWidth={135}
          >
            <StatusBadge status={row.status} language={language} />
          </GridInfoItem>
        </Box>

        <Box sx={{ display: { xs: "none", md: "block" } }} />

        <Box
          sx={{
            minWidth: 0,
            gridColumn: {
              xs: "1",
              md: "1 / span 2",
            },
          }}
        >
          <SectionLabel>
            {tWgIssues(language, "issueDescription")}
          </SectionLabel>

          <GridText
            value={translateWgIssuesText(language, row.description)}
            noWrap={false}
          />
        </Box>

        <Box sx={{ minWidth: 0 }}>
          <SectionLabel>
            {tWgIssues(language, "recommendation")}
          </SectionLabel>

          <GridText
            value={translateWgIssuesText(language, row.recommendation)}
            noWrap={false}
          />
        </Box>
      </Box>
    </Paper>
  );
}

type WgAIssuesTableProps = {
  language: WgIssuesLanguage;
  rows?: IssueRow[];
  viewMode?: WgIssuesViewMode;
};

export function WgAIssuesTable({
  language,
  rows = wgAIssueRows,
  viewMode = "list",
}: WgAIssuesTableProps) {
  const router = useRouter();
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";
  const { can } = usePermissions();
  const deleteIssueMutation = useDeleteWorkingGroupIssue();

  // The issue pending removal in the confirm dialog (null = closed).
  const [removeTarget, setRemoveTarget] = useState<IssueRow | null>(null);
  const [editTarget, setEditTarget] = useState<IssueRow | null>(null);
  // Success toast shown after a remove or edit.
  const [toastMessage, setToastMessage] = useState<string | null>(null);

  // Menu actions open the matching detail, edit, or confirmation UI.
  const actionHandlers = useMemo<WgIssueActionHandlers>(
    () => ({
      onViewDetail: (row) => router.push(`/pswg/wg-issues/${row.id}`),
      onEdit: (row) => setEditTarget(row),
      onRemove: (row) => setRemoveTarget(row),
    }),
    [router],
  );

  const actionAccess = useMemo<WgIssueActionAccess>(
    () => ({
      canViewDetail: can(APP_PERMISSIONS.workingGroupIssue.read),
      canEdit: can(APP_PERMISSIONS.workingGroupIssue.update),
      canSendRequest: false,
      canRemove: can(APP_PERMISSIONS.workingGroupIssue.delete),
    }),
    [can],
  );

  // Delete the targeted issue. React Query invalidation refreshes the list
  // automatically; this handler only shows the toast.
  const confirmRemove = useCallback(async () => {
    if (!removeTarget) {
      return;
    }

    try {
      await deleteIssueMutation.mutateAsync(Number(removeTarget.id));
      setRemoveTarget(null);
      setToastMessage(tWgIssues(language, "issueRemoved"));
    } catch (error) {
      setRemoveTarget(null);
      setToastMessage(
        error instanceof Error
          ? error.message
          : tWgIssues(language, "removeFailed"),
      );
    }
  }, [removeTarget, language, deleteIssueMutation]);

  const handleIssueSaved = useCallback(() => {
    setToastMessage(tWgIssues(language, "issueUpdated"));
  }, [language]);

  const columns = useMemo(
    () => getWgIssuesTableColumns(language, actionHandlers, actionAccess),
    [language, actionHandlers, actionAccess],
  );

  const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({
    page: 0,
    pageSize: WG_ISSUES_PAGE_SIZE,
  });

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

  const paginatedRows = useMemo(() => {
    const start = paginationModel.page * paginationModel.pageSize;
    const end = start + paginationModel.pageSize;

    return rows.slice(start, end);
  }, [paginationModel.page, paginationModel.pageSize, rows]);

  const footer = (
    <WgIssuesTableFooter
      language={language}
      page={paginationModel.page}
      pageCount={pageCount}
      onPrevious={() =>
        setPaginationModel((current) => ({
          ...current,
          page: Math.max(0, current.page - 1),
        }))
      }
      onNext={() =>
        setPaginationModel((current) => ({
          ...current,
          page: Math.min(pageCount - 1, current.page + 1),
        }))
      }
      onSelectPage={(pageIndex) =>
        setPaginationModel((current) => ({
          ...current,
          page: pageIndex,
        }))
      }
    />
  );

  // Shared dialogs/toast rendered in both list and grid views.
  const dialogs = (
    <>
      {editTarget ? (
        <EditIssueDialog
          issueId={editTarget.id}
          onSaved={handleIssueSaved}
          open
          onClose={() => setEditTarget(null)}
        />
      ) : null}

      <ConfirmDialog
        open={Boolean(removeTarget)}
        title={tWgIssues(language, "removeIssue")}
        description={
          <>
            {tWgIssues(language, "removeIssueQuestion")}{" "}
            <Box
              component="strong"
              sx={{ fontWeight: 700, color: "text.primary" }}
            >
              {removeTarget?.issue}
            </Box>
            ?
            <br />
            {tWgIssues(language, "removeIssueUndone")}
          </>
        }
        confirmLabel={tWgIssues(language, "removeIssue")}
        cancelLabel={tWgIssues(language, "cancel")}
        loading={deleteIssueMutation.isPending}
        onConfirm={confirmRemove}
        onCancel={() => setRemoveTarget(null)}
      />

      <ToastNotification
        open={Boolean(toastMessage)}
        message={toastMessage ?? ""}
        autoHideDuration={3000}
        onClose={() => setToastMessage(null)}
      />
    </>
  );

  if (viewMode === "grid") {
    return (
      <>
        <Box>
          <Box
            sx={{
              display: "flex",
              flexDirection: "column",
              gap: 2.5,
            }}
          >
            {paginatedRows.map((row) => (
              <WgIssueGridCard
                access={actionAccess}
                key={row.id}
                row={row}
                language={language}
                handlers={actionHandlers}
              />
            ))}
          </Box>

          <Paper
            elevation={0}
            sx={{
              mt: 2,
              borderRadius: "12px",
              border: `1px solid ${isDark ? alpha("#ffffff", 0.12) : "#e9eaeb"}`,
              overflow: "hidden",
              bgcolor: isDark ? "#111827" : "#ffffff",
            }}
          >
            {footer}
          </Paper>
        </Box>

        {dialogs}
      </>
    );
  }

  return (
    <>
      <DataTable
        fillAvailableHeight
        rows={rows}
        columns={columns}
        getRowId={(row) => row.id}
        enableColumnMenu
        emptyMessage=""
        pageSize={WG_ISSUES_PAGE_SIZE}
        rowHeight={74}
        columnHeaderHeight={56}
        dataGridSx={{
          "& .MuiDataGrid-columnHeaderTitle": {
            lineHeight: 1.25,
            overflow: "visible",
            whiteSpace: "normal",
          },
          "& .MuiDataGrid-cell": {
            overflow: "hidden",
          },
        }}
      />

      {dialogs}
    </>
  );
}
