"use client";

import React, { useState, useCallback, useMemo } from "react";
import { DataGrid, GridPaginationModel } from "@mui/x-data-grid";
import { Box, Paper, Alert } from "@mui/material";
import DataTableHeader from "./DataTableHeader";
import StatusChangeDialog from "./StatusChangeDialog";
import Spinner from "@/app/components/Spinner/Spinner";
import {
  selectStatus,
  selectError,
  selectPagination,
  selectPaginationModel,
} from "@/app/redux/advanedSearch/selectors";
import { makeSelectEnhancedColumns } from "./re-selectors";
import { useDispatch, useSelector } from "react-redux";
import { DataRowBase } from "./types";
import { setPagination } from "@/app/redux/advanedSearch/advancedSearchSlice";
import { AppDispatch } from "@/app/redux/store";

interface DataTableProps<TRow extends DataRowBase> {
  rows: TRow[];
  extraColumns?: string[];
  enableStatusActions?: boolean;
  totalRows?: number;
}

const DataTable = <TRow extends DataRowBase>({
  rows: localRows,
  extraColumns,
  enableStatusActions = false,
  totalRows: totalRows,
}: DataTableProps<TRow>) => {
  const dispatch = useDispatch<AppDispatch>();
  const [showExtraColumns, setShowExtraColumns] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [selectedRowId, setSelectedRowId] = useState<number | null>(null);
  const [pendingStatus, setPendingStatus] = useState<string>("");
  const [reason, setReason] = useState<string>("");
  const [statusUpdateError, setStatusUpdateError] = useState<string | null>(
    null
  );
  const [isUpdatingStatus, setIsUpdatingStatus] = useState(false);

  const status = useSelector(selectStatus);
  const errorMessage = useSelector(selectError);
  const pagination = useSelector(selectPagination);
  const paginationModel = useSelector(selectPaginationModel);

  const handlePaginationModelChange = useCallback(
    (model: GridPaginationModel) => {
      console.log("model", model);
      const nextPage = model.page + 1;
      const nextLimit = model.pageSize;

      if (nextPage !== pagination.page || nextLimit !== pagination.limit) {
        dispatch(setPagination({ page: nextPage, limit: nextLimit }));
      }
    },
    [dispatch, pagination.page, pagination.limit]
  );

  const handleStatusChange = useCallback((rowId: number, newStatus: string) => {
    setSelectedRowId(rowId);
    setPendingStatus(newStatus);
    setModalOpen(true);
  }, []);

  const handleStatusSave = async () => {
    if (!selectedRowId || !pendingStatus) return;
    setStatusUpdateError(null);
    setIsUpdatingStatus(true);

    try {
      const payload = {
        data: {
          status: pendingStatus,
          notes: reason.trim(),
        },
        fields: ["Status", "Notes"],
      };

      const response = await fetch(
        `/api/dashboard/transactions/${selectedRowId}`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(payload),
        }
      );

      const result = await response.json();

      if (!response.ok) {
        throw new Error(
          result?.message || result?.error || "Failed to update transaction"
        );
      }

      setModalOpen(false);
      setReason("");
      setPendingStatus("");
      setStatusUpdateError(null);
      setSelectedRowId(null);
    } catch (err) {
      setStatusUpdateError(
        err instanceof Error ? err.message : "Failed to update transaction"
      );
    } finally {
      setIsUpdatingStatus(false);
    }
  };

  const selectEnhancedColumns = useMemo(makeSelectEnhancedColumns, []);

  const enhancedColumns = useSelector(state =>
    selectEnhancedColumns(state, {
      enableStatusActions,
      extraColumns,
      showExtraColumns,
      localRows,
      handleStatusChange,
    })
  );
  return (
    <>
      {status === "loading" && <Spinner size="small" color="#fff" />}
      {status === "failed" && (
        <Alert severity="error">
          {errorMessage || "Failed to load transactions."}
        </Alert>
      )}
      <Paper sx={{ width: "100%", overflowX: "hidden" }}>
        <DataTableHeader
          extraColumns={extraColumns}
          showExtraColumns={showExtraColumns}
          onToggleExtraColumns={() => setShowExtraColumns(prev => !prev)}
          onOpenExport={() => {}}
        />

        <Box sx={{ width: "85vw" }}>
          <Box sx={{ minWidth: 1200 }}>
            <DataGrid
              rows={localRows}
              columns={enhancedColumns}
              paginationModel={paginationModel}
              onPaginationModelChange={handlePaginationModelChange}
              paginationMode={totalRows ? "server" : "client"}
              rowCount={totalRows}
              pageSizeOptions={[10, 25, 50, 100]}
              sx={{
                border: 0,
                cursor: "pointer",
                "& .MuiDataGrid-cell": {
                  py: 1,
                  textAlign: "center",
                  justifyContent: "center",
                  display: "flex",
                  alignItems: "center",
                },
                "& .MuiDataGrid-columnHeader": {
                  textAlign: "center",
                  justifyContent: "center",
                },
              }}
            />
          </Box>
        </Box>

        <StatusChangeDialog
          open={modalOpen}
          newStatus={pendingStatus}
          reason={reason}
          setReason={setReason}
          handleClose={() => {
            setModalOpen(false);
            setReason("");
            setPendingStatus("");
            setStatusUpdateError(null);
            setSelectedRowId(null);
          }}
          handleSave={handleStatusSave}
          isSubmitting={isUpdatingStatus}
          errorMessage={statusUpdateError}
        />
      </Paper>
    </>
  );
};

// Memoize to avoid unnecessary re-renders
export default React.memo(DataTable);
