"use client";
import { useState } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import {
  Button,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  FormControl,
  Select,
  MenuItem,
  FormControlLabel,
  Checkbox,
  Stack,
  Paper,
  TextField,
  Box,
  IconButton,
} from "@mui/material";
import FileUploadIcon from "@mui/icons-material/FileUpload";
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import AdvancedSearch from "../AdvancedSearch/AdvancedSearch";
import SearchFilters from "@/app/components/searchFilter/SearchFilters";
import { exportData } from "@/app/utils/exportData";
import StatusChangeDialog from "./StatusChangeDialog";
import { IDataTable } from "./types";

interface IDataTableProps<TRow, TColumn> {
  data: IDataTable<TRow, TColumn>;
}

export type TWithId = { id: number };

const DataTable = <TRow extends TWithId, TColumn extends GridColDef>({
  data,
}: IDataTableProps<TRow, TColumn>) => {
  const { tableRows, tableColumns, tableSearchLabels, extraColumns } = data;
  const router = useRouter();
  const searchParams = useSearchParams();

  const [rows, setRows] = useState<TRow[]>(tableRows);
  const [open, setOpen] = useState(false);
  const [fileType, setFileType] = useState<"csv" | "xls" | "xlsx">("csv");
  const [onlyCurrentTable, setOnlyCurrentTable] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [selectedRowId, setSelectedRowId] = useState<number | null>(null);
  const [newStatus, setNewStatus] = useState<string>("");
  const [reason, setReason] = useState<string>("");
  const [showExtraColumns, setShowExtraColumns] = useState(false);

  const filters = Object.fromEntries(searchParams.entries());

  const handleClickField = (field: string, value: string) => {
    const params = new URLSearchParams(searchParams.toString());
    params.set(field, value);
    router.push(`?${params.toString()}`);
    router.refresh();
  };

  const handleStatusChange = (id: number, newStatus: string) => {
    setSelectedRowId(id);
    setNewStatus(newStatus);
    setModalOpen(true);
  };

  const handleStatusSave = () => {
    console.log(
      `Status changed for row with ID ${selectedRowId}. New status: ${newStatus}. Reason: ${reason}`,
    );

    setRows(
      rows.map((row) =>
        row.id === selectedRowId ? { ...row, status: newStatus } : row,
      ),
    );
    setModalOpen(false);
    setReason("");
  };

  const getColumnsWithDropdown = (columns: TColumn[]): GridColDef[] => {
    return columns.map((col) => {
      if (col.field === "status") {
        return {
          ...col,
          renderCell: (params: GridRenderCellParams) => {
            const value = params.value?.toLowerCase();
            let bgColor = "#e0e0e0";
            let textColor = "#000";

            switch (value) {
              case "completed":
                bgColor = "#d0f0c0";
                textColor = "#1b5e20";
                break;
              case "pending":
                bgColor = "#fff4cc";
                textColor = "#9e7700";
                break;
              case "inprogress":
                bgColor = "#cce5ff";
                textColor = "#004085";
                break;
              case "error":
                bgColor = "#ffcdd2";
                textColor = "#c62828";
                break;
            }

            return (
              <Box
                sx={{
                  backgroundColor: bgColor,
                  color: textColor,
                  px: 1.5,
                  py: 0.5,
                  borderRadius: 1,
                  fontWeight: 500,
                  textTransform: "capitalize",
                  display: "inline-block",
                  width: "100%",
                  textAlign: "center",
                }}
              >
                {params.value}
              </Box>
            );
          },
        };
      }

      if (col.field === "userId") {
        return {
          ...col,
          renderCell: (params: GridRenderCellParams) => (
            <Box
              sx={{
                display: "flex",
                alignItems: "center",
                justifyContent: "flex-start",
                gap: 0.5,
                width: "100%",
                px: 1,
              }}
            >
              <span>{params.value}</span>
              <IconButton
                href={`/users/${params.value}`}
                target="_blank"
                size="small"
                onClick={(e) => e.stopPropagation()}
                sx={{ p: 0.5 }}
              >
                <OpenInNewIcon fontSize="small" />
              </IconButton>
            </Box>
          ),
        };
      }

      if (col.field === "actions") {
        return {
          ...col,
          renderCell: (params: GridRenderCellParams) => {
            const row = tableRows.find((r) => r.id === params.id) as {
              id: number;
              status?: string;
              options?: { value: string; label: string }[];
            };

            const options = row?.options;
            if (!options) return params.value;

            return (
              <Select
                value={params.value ?? row.status}
                onChange={(e) =>
                  handleStatusChange(params.id as number, e.target.value)
                }
                size="small"
                sx={{
                  width: "100%",
                  "& .MuiOutlinedInput-notchedOutline": { border: "none" },
                  "& .MuiSelect-select": { py: 0.5 },
                }}
                onClick={(e) => e.stopPropagation()}
              >
                {options.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            );
          },
        };
      }

      return col;
    });
  };

  let filteredColumns = tableColumns;
  if (extraColumns && extraColumns.length > 0) {
    filteredColumns = showExtraColumns
      ? tableColumns
      : tableColumns.filter((col) => !extraColumns.includes(col.field));
  }

  return (
    <Paper sx={{ width: "calc(100vw - 300px)", overflowX: "hidden" }}>
      <Stack
        direction="row"
        justifyContent="space-between"
        alignItems="center"
        p={2}
        flexWrap="wrap"
        gap={2}
      >
        <TextField
          label="Search"
          variant="outlined"
          size="small"
          onChange={(e) => console.log(`setSearchQuery(${e.target.value})`)}
          sx={{ width: 300 }}
        />
        <AdvancedSearch labels={tableSearchLabels} />
        <SearchFilters filters={filters} />
        <Button
          variant="outlined"
          startIcon={<FileUploadIcon />}
          onClick={() => setOpen(true)}
        >
          Export
        </Button>
        {extraColumns && extraColumns.length > 0 && (
          <Button
            variant="outlined"
            onClick={() => setShowExtraColumns((prev) => !prev)}
          >
            {showExtraColumns ? "Hide Extra Columns" : "Show Extra Columns"}
          </Button>
        )}
      </Stack>

      <Box sx={{ width: "calc(100vw - 300px)", overflowX: "auto" }}>
        <Box sx={{ minWidth: 1200 }}>
          <DataGrid
            rows={tableRows}
            columns={getColumnsWithDropdown(filteredColumns)}
            initialState={{
              pagination: { paginationModel: { pageSize: 50 } },
            }}
            pageSizeOptions={[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",
              },
            }}
            onCellClick={(params) => {
              if (params.field !== "actions") {
                handleClickField(params.field, params.value as string);
              }
            }}
          />
        </Box>
      </Box>

      <StatusChangeDialog
        open={modalOpen}
        newStatus={newStatus}
        reason={reason}
        setReason={setReason}
        handleClose={() => setModalOpen(false)}
        handleSave={handleStatusSave}
      />

      <Dialog open={open} onClose={() => setOpen(false)}>
        <DialogTitle>Export Transactions</DialogTitle>
        <DialogContent>
          <FormControl fullWidth sx={{ mt: 2 }}>
            <Select
              value={fileType}
              onChange={(e) =>
                setFileType(e.target.value as "csv" | "xls" | "xlsx")
              }
            >
              <MenuItem value="csv">CSV</MenuItem>
              <MenuItem value="xls">XLS</MenuItem>
              <MenuItem value="xlsx">XLSX</MenuItem>
            </Select>
          </FormControl>
          <FormControlLabel
            control={
              <Checkbox
                checked={onlyCurrentTable}
                onChange={(e) => setOnlyCurrentTable(e.target.checked)}
              />
            }
            label="Only export current table"
            sx={{ mt: 2 }}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setOpen(false)}>Cancel</Button>
          <Button
            variant="contained"
            onClick={() =>
              exportData(
                tableRows,
                tableColumns,
                fileType,
                onlyCurrentTable,
                setOpen,
              )
            }
          >
            Export
          </Button>
        </DialogActions>
      </Dialog>
    </Paper>
  );
};

export default DataTable;
