/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { FunctionComponent } from "react";
import { CustomButtonProps } from "../FormInput/types";
import styles from "./styles/CrudMaker.module.scss";
import TitleAndSubtitle from "../TitleAndSubtitle/TitleAndSubtitle";
import { Button, MenuItem, Pagination, Select } from "@mui/material";
import FormInput, {
  CurrentFormInputProps as FormInputProps,
} from "../FormInput/FormInput";
import DynamicTable, {
  Column,
  DynamicTableTabsProps,
} from "../DynamicTable/DynamicTable";
import { BasicModelStructure } from "@/types/main/types";
import { calculateTotalPages } from "@/lib/utils/paginationUtils";

interface ColumnProps<T> {
  id: keyof T | string;
  label: string;
  render?: (row: T) => React.ReactNode;
}

export interface CrudMakerProps<T> {
  buttons?: CustomButtonProps[];
  filters?: FormInputProps[];
  data: T[];
  columns: ColumnProps<T>[];
  title: string;
  tableName: string;
  tabsIndex?: number;
  tabs?: DynamicTableTabsProps[];
  loading?: boolean;
  hideTableOnBreakpoint?: boolean;
  ResponsiveComponent?: FunctionComponent<unknown>;
  noPagination?: boolean;
  responsiveProps?: any;
  page?: number;
  totalPages?: number;
  pageSize?: number;
  setPageSize?: (val: number) => any;
  setPage?: (val: number) => any;
}

const CrudMaker = <T extends BasicModelStructure>({
  buttons,
  filters,
  data,
  columns,
  title,
  tableName,
  tabs,
  tabsIndex,
  loading,
  hideTableOnBreakpoint,
  ResponsiveComponent,
  noPagination,
  setPageSize,
  setPage,
  totalPages,
  pageSize,
  page,
  responsiveProps,
}: CrudMakerProps<T>): React.ReactElement => {
  return (
    <div className={styles.container}>
      <TitleAndSubtitle
        title={title}
        subtitle={tableName}
        style={{ alignItems: "flex-start" }}
      />
      {buttons && buttons.length > 0 && (
        <div className={styles.buttons}>
          {buttons.map((d, index) => {
            return (
              <div
                key={"filter" + "-" + index}
                className={styles.buttonContainer}
                style={{
                  minWidth: hideTableOnBreakpoint
                    ? d?.minWidth ?? "fit-content"
                    : undefined,
                  maxWidth: d?.maxWidth,
                }}
              >
                <Button key={index} {...d} />
              </div>
            );
          })}
        </div>
      )}
      {filters && filters.length > 0 && (
        <div className={styles.filters}>
          {filters.map((d, index) => {
            return (
              <div
                key={"filter" + "-" + index}
                className={styles.filterContainer}
                style={{
                  minWidth: hideTableOnBreakpoint
                    ? d?.minWidth ?? "fit-content"
                    : undefined,
                  maxWidth: d?.maxWidth,
                }}
              >
                <FormInput {...d} />
              </div>
            );
          })}
        </div>
      )}
      {columns && columns.length > 0 && data && (
        <>
          {!hideTableOnBreakpoint && (
            <DynamicTable
              columns={columns as Column<T>[]}
              data={data}
              tabs={tabs}
              loading={loading}
              tabsIndex={tabsIndex}
            />
          )}
          {hideTableOnBreakpoint && ResponsiveComponent && (
            <>
              {data.map((d, index) => {
                return (
                  <ResponsiveComponent
                    key={index}
                    {...({
                      item: d,
                      tabIndex: tabsIndex,
                      ...(responsiveProps ?? {}),
                    } as any)}
                  />
                );
              })}
            </>
          )}
        </>
      )}
      {!noPagination && data.length > 0 && (
        <div className={styles.paginationContainer}>
          {calculateTotalPages(totalPages ?? 0, pageSize ?? 10) > 0 && (
            <Pagination
              count={calculateTotalPages(totalPages ?? 0, pageSize ?? 10)}
              color="primary"
              page={page}
              onChange={(_, page) => {
                if (setPage) setPage(page);
              }}
            />
          )}
          {typeof pageSize == "number" &&
            setPageSize &&
            totalPages &&
            totalPages > 0 && (
              <Select
                value={pageSize}
                size="small"
                onChange={(event) => setPageSize(event.target.value as number)}
              >
                {[5, 10, 20, 50, 100].map((p) => {
                  return (
                    <MenuItem key={p} value={p}>
                      {p}
                    </MenuItem>
                  );
                })}
              </Select>
            )}
        </div>
      )}
    </div>
  );
};

export default CrudMaker;
