import {
  ColumnDef,
  ColumnMeta,
  getCoreRowModel,
  getExpandedRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
} from "@tanstack/react-table";
import "./index.scss";
import { useEffect, useRef, useState } from "react";
import {
  CraftTablePaginationProps,
  CraftTableProps,
  TopbarOptionsProps,
} from "../types/table";
import { CraftTableFeatureProps } from "../types/table-options";
import { LoaderAnimation } from "../../assets/svg";
import Topbar from "./topbar";
import DefaultPagination from "./pagination/default";
import TableDND from "./table-dnd";
import Table from "./table";
import { useFullscreenPopoverContainer } from "../libs/hooks/useFullScreen";

interface CustomColumnMeta<T> extends ColumnMeta<T, unknown> {
  defaultPinned?: "left" | "right" | undefined;
}

function TableWrapper<T>({
  data = [],
  columns = [],
  tableStates,
  filterSettingStates,
  onSaveSettings,
  paginationOptions,
  featureOptions,
  topbarOptions,
  nestedComponent,
  loadingOptions = { isLoading: false },
  customRenderFn = {},
  // styleOptions,
  shouldHideColumn,
  emptyListComponent,
  filterOptions,
  activeTab,
}: CraftTableProps<T>) {
  if (!Array.isArray(data)) {
    throw new Error("data must be an array of objects.");
  }
  const [metaColumns, setMetaColumns] = useState<ColumnDef<T>[]>([]);

  useEffect(() => {
    if (columns?.length > 0) {
      const updatedColumns = columns
        ?.filter((col) => {
          const accessorKey =
            "accessorKey" in col
              ? (col as { accessorKey: string })?.accessorKey
              : undefined;
          return typeof shouldHideColumn === "function"
            ? !shouldHideColumn(accessorKey)
            : true;
        })
        ?.map((col, index) => {
          const id =
            "accessorKey" in col
              ? (col as { accessorKey: string })?.accessorKey
              : `col_${index}`;

          const cell = (ctx: any) => {
            if (col?.meta?.type === "custom" && col?.meta?.propName) {
              const customFn = customRenderFn?.[col?.meta?.propName];
              return typeof customFn === "function"
                ? customFn({
                    value: ctx?.getValue(),
                    row: ctx?.row,
                    table: ctx?.table?.getRowModel()?.rows,
                  })
                : ctx?.getValue();
            }

            if (typeof col?.cell === "function") {
              return col?.cell(ctx);
            }

            return ctx?.getValue();
          };

          return { ...col, id, cell };
        });

      setMetaColumns(updatedColumns);
    }
  }, [columns]);

  //For Default Column Pinning to work
  useEffect(() => {
    table.getAllLeafColumns().forEach((col) => {
      const where = (col.columnDef.meta as CustomColumnMeta<T>)
        ?.defaultPinned as "left" | "right" | undefined;
      if (where && !col.getIsPinned()) {
        col.pin(where);
      }
    });
  }, [tableStates?.columnPinning?.left, metaColumns]);

  const [columnOrder, setColumnOrder] = useState<string[]>(() =>
    metaColumns.map((c) => c.id!)
  );

  useEffect(() => {
    if (metaColumns.length > 0) {
      setColumnOrder(metaColumns.map((c) => c.id!));
    }
  }, [metaColumns]);

  const [isCompactTable, setIsCompactTable] = useState<boolean>(
    featureOptions?.compactTable ?? false
  );

  const tableRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setIsCompactTable(featureOptions?.compactTable ?? false);
  }, [featureOptions?.compactTable]);

  const craftPaginationOptions: CraftTablePaginationProps = {
    showPagination: true,
    paginationPosition: "bottom",
    paginationView: "full",

    ...paginationOptions,
  };

  const totalRows = craftPaginationOptions?.totalRows ?? data.length;
  const rowsPerPageArray = craftPaginationOptions?.rowsPerPageArray ?? [
    25, 50, 100, 150,
  ];
  const craftTopbarOptions: TopbarOptionsProps = {
    showColumnToggle: true,
    showCompactTableToggle: true,
    showChangeLayoutToggle: true,
    viewMoreToggle: true,
    showSearch: true,
    showSortingToggle: false,
    showFilterToggle: true,
    tableStates,

    // Add other conditions above topbarOptions
    ...topbarOptions,
  };

  const craftFeatureOptions: CraftTableFeatureProps = {
    enableTopbar: true,
    enableSorting: true,
    enableServerSidePagination: false,
    enableServerSideSorting: false,
    enableRowSelection: false,
    enableColumnResizing: true,
    enableColumnReordering: true,
    enableColumnPinning: true,
    enableMultiColumnSorting: true,
    compactTable: false,
    stickyHeader: true,
    enableWordBreakAll: false,
    striped: false,

    // Add other conditions above featureOptions
    ...featureOptions,
  };

  const {
    enableTopbar,
    enableRowSelection,
    enableServerSidePagination,
    enableServerSideSorting,
    enableSorting,
    enableColumnResizing,
    enableColumnReordering,
    enableColumnPinning,
    // enableMultiColumnSorting,
  } = craftFeatureOptions;

  const {
    sorting,
    setSorting,
    pagination,
    setPagination,
    rowSelection,
    setRowSelection,
    expanded,
    setExpanded,
  } = tableStates;

  const table = useReactTable({
    data,
    columns: metaColumns,
    state: {
      sorting,
      pagination,
      rowSelection,
      columnOrder,
      expanded,
    },

    getCoreRowModel: getCoreRowModel(),

    /** Sorting options start here */
    enableSorting: enableSorting,
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    manualSorting: enableServerSideSorting,
    // isMultiSortEvent: () => enableMultiColumnSorting || false,
    /** Sorting options end here */

    /** Pagination options start here */
    getPaginationRowModel: getPaginationRowModel(),
    onPaginationChange: setPagination,
    rowCount: totalRows,
    manualPagination: enableServerSidePagination,
    /** Pagination options end here */

    /** Row selection options start here */
    enableRowSelection: enableRowSelection,
    onRowSelectionChange: setRowSelection,
    /** Row selection options end here */

    /** Column Sizing options start here */
    enableColumnResizing: enableColumnResizing,
    columnResizeDirection: "ltr",
    columnResizeMode: "onChange",
    /** Column Sizing options end here */

    /** Column Ordering options start here */
    onColumnOrderChange: setColumnOrder,
    /** Column Ordering options end here */

    /** Column Pinning options end here */
    enableColumnPinning: enableColumnPinning,
    /** Column Pinning options end here */

    /** Row expanding options start here */
    getExpandedRowModel: getExpandedRowModel(),
    onExpandedChange: setExpanded,
    getSubRows: (row) => (row as { subRows?: T[] }).subRows ?? [],
    /** Row expanding options end here */
  });

  const { isLoading, loadingComponent, loaderText } = loadingOptions;
  const { isFullscreen } = useFullscreenPopoverContainer();

  const handleFullscreenToggle = () => {
    if (!document.fullscreenElement) {
      tableRef.current?.requestFullscreen().catch((err) => {
        console.error("Error attempting to enable fullscreen mode:", err);
      });
    } else {
      document.exitFullscreen();
    }
  };

  // const tableWrapperProps = {
  //   ...(styleOptions?.wrapperStyle && { style: styleOptions.wrapperStyle }),
  //   className: "ts__table__wrapper",
  // };
  // const emptyListComponentCondition = () => {
  //   if(isLoading) {}
  // }

  const showFilterCondition = filterOptions?.show;

  return (
    <div className="ts__table__container">
      <div
        className={`ts__table__layout ${
          showFilterCondition ? "has-filter" : ""
        }`}
      >
        {/* Main Table Area */}
        <div
          className={`ts__table__main ${isFullscreen ? "is-fullscreen" : ""}`}
          ref={tableRef}
        >
          {enableTopbar && (
            <Topbar
              table={table}
              topbarOptions={craftTopbarOptions}
              isCompactTable={isCompactTable}
              setIsCompactTable={setIsCompactTable}
              isFullscreen={isFullscreen}
              fullscreenToggle={handleFullscreenToggle}
              paginationComponent={
                craftPaginationOptions?.showPagination === true &&
                craftPaginationOptions?.paginationPosition === "top" ? (
                  <DefaultPagination
                    table={table}
                    rowsPerPageArray={rowsPerPageArray}
                    paginationOptions={craftPaginationOptions}
                  />
                ) : null
              }
              searchValue={craftTopbarOptions.searchValue}
              onSearchChange={craftTopbarOptions.onSearchChange}
              tableStates={tableStates}
              onFilterButtonClick={topbarOptions?.onFilterButtonClick}
            />
          )}

          {isLoading ? (
            loadingComponent ?? (
              <div className="ts__loader">
                <LoaderAnimation />
                {loaderText && <p>{loaderText}</p>}
              </div>
            )
          ) : !isLoading && data.length === 0 && emptyListComponent ? (
            emptyListComponent
          ) : (
            <div
              // {...tableWrapperProps}
              className={`ts__table__wrapper ${
                isFullscreen ? "is-fullscreen" : ""
              }`}
            >
              {enableColumnReordering ? (
                <TableDND
                  table={table}
                  activeTab={activeTab}
                  columnOrder={columnOrder}
                  featureOptions={craftFeatureOptions}
                  NestedComponent={nestedComponent}
                  setColumnOrder={setColumnOrder}
                  isCompactTable={isCompactTable}
                  tableStates={tableStates}
                  filterSettingStates={filterSettingStates}
                  onSaveSettings={onSaveSettings}
                />
              ) : (
                <Table
                  table={table}
                  activeTab={activeTab}
                  featureOptions={craftFeatureOptions}
                  NestedComponent={nestedComponent}
                  columnOrder={columnOrder}
                  setColumnOrder={setColumnOrder}
                  isCompactTable={isCompactTable}
                  tableStates={tableStates}
                  filterSettingStates={filterSettingStates}
                  onSaveSettings={onSaveSettings}
                />
              )}
            </div>
          )}

          {craftPaginationOptions?.showPagination === true &&
          craftPaginationOptions?.paginationPosition === "bottom" ? (
            <DefaultPagination
              table={table}
              rowsPerPageArray={rowsPerPageArray}
              paginationOptions={craftPaginationOptions}
            />
          ) : null}
        </div>

        <div
          className={`ts__table__filter ${
            showFilterCondition ? "show" : ""
          }`.trim()}
        >
          {filterOptions?.component && filterOptions?.component}
        </div>
      </div>
    </div>
  );
}

export default TableWrapper;
