import React, { ReactNode } from 'react';
import './Table.scss';
import Checkbox from '../Checkbox';
import { isFunction } from '../../assets/utils/functionUtils';
import classNames from 'classnames';
import NoData from '../NoData/NoData';

interface ColumnsProps {
  /**
   * column name
   */
  header: string;
  /**
   * data key for particular column
   */
  accessor: string;
  /**
   * className for a column
   */
  className?: string;
  /**
   * width of a column
   */
  width?: number;
  /**
   * data for the column
   */
  cell?: (e: any) => JSX.Element | string | ReactNode;

  onClick?: (colum: string, row?: DataProps) => void;
}
interface DataProps {
  /**
   * data for each row
   */
  [key: string]: any;
}
interface SelectedItemProps {
  /**
   * selected row object | All selected flag
   */
  [key: string]: string | number | boolean;
}
export interface TableProps {
  /**
   * Data for table
   */
  data: Array<number | string | DataProps>;
  /**
   * Column details for table
   */
  columns: Array<any>;
  /**
   * Header type to have different background color
   */
  headerType: 'default' | 'primary' | 'secondary';
  /**
   * withFixedHeader prop to have non-scrollable fixed table header
   */
  withFixedHeader?: boolean;
  /**
   * borderWithRadius prop to have table with border 1px and borderRadius 5px
   */
  borderWithRadius?: boolean;
  /**
   * Check box feature to select the row
   */
  withCheckbox?: boolean;
  /**
   * Event for checkbox onClick
   */
  onSelect?: (e: object, arg: SelectedItemProps) => void;
  /**
   * Check box feature to select the row
   */
  allSelected?: boolean;
  /**
   * send true to show partial checkbox in the header
   */
  partialSelected?: boolean;
  /**
   * send true to disable the checkbox in the header
   */
  headerCheckboxDisabled?: boolean;
  /**
   * The content that to be displayed if no data not found
   */
  noDataContent: string | ReactNode;
  /**
   * Image that to be displayed if you don't have data
   */
  noDataImage?: string;
  /**
   * Size of the image that to be displayed if you don't have data
   */
  noDataImageSize?: 'x-large' | 'large' | 'medium' | 'small' | 'x-small';
  /**
   *  Height of the table in string
   */
  height?: string;
  /**
   *  classNames for the table container
   */
  className?: string;
}
const Table = ({
  data = [],
  columns = [],
  headerType,
  withCheckbox,
  onSelect,
  allSelected,
  partialSelected = false,
  withFixedHeader = true,
  borderWithRadius = false,
  headerCheckboxDisabled = false,
  noDataContent,
  noDataImage,
  noDataImageSize,
  height = '100%',
  className = '',
}: TableProps) => {
  const prepareData = (dataObj: any, columnObj: ColumnsProps) => {
    let cellData = dataObj[columnObj.accessor];
    if (columnObj.cell) {
      return columnObj.cell({
        value: cellData,
        row: dataObj,
        column: columnObj.accessor,
      });
    } else if (columnObj.accessor) {
      return cellData;
    } else if (cellData && typeof cellData !== 'object') {
      return cellData;
    } else {
      return '--';
    }
  };
  const onSelectClick = (e: object, item: SelectedItemProps) => {
    if (onSelect) {
      onSelect(e, item);
    }
  };

  const hanleOnclick = (column: ColumnsProps, row: DataProps) => {
    if (column.onClick && isFunction(column.onClick)) {
      column?.onClick(column.accessor, row);
    }
  };
  if (!(data.length >= 0)) return null;
  return (
    <div
      style={{ height: height }}
      className={classNames(className, {
        'ff-fixed-header-table': withFixedHeader,
        'border-borderRadius': borderWithRadius,
      })}
    >
      <table className={classNames(`ff-table`)} cellSpacing={0}>
        <thead
          className={classNames({
            'ff-fixed-header': withFixedHeader,
          })}
        >
          <tr>
            {columns.map((column, index) => (
              <th
                className={headerType && `${headerType}-bg`}
                key={column.header}
                style={{ width: column?.width }}
              >
                <div>
                  {index === 0 && withCheckbox && (
                    <span className="ff-table-checkbox">
                      <Checkbox
                        onChange={(e) => {
                          onSelectClick(e, { allSelected: e.target.checked });
                        }}
                        checked={
                          allSelected !== undefined ? allSelected : false
                        }
                        partial={!!partialSelected}
                        disabled={headerCheckboxDisabled}
                      />
                    </span>
                  )}

                  {column.header}
                </div>
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {data.length > 0 &&
            data.map((row: any, index: number) => (
              <tr key={row.id || index}>
                {columns.map((column, i) => {
                  return (
                    <td
                      key={column.accessor + i}
                      onClick={() => hanleOnclick(column, row)}
                      className={classNames(column.className, {
                        'clickable-cell': column.onClick,
                      })}
                    >
                      <div>
                        {i === 0 && withCheckbox && (
                          <span className="ff-table-checkbox">
                            <Checkbox
                              onChange={(e) => {
                                onSelectClick(e, row);
                              }}
                              checked={row.checked}
                              disabled={!!row.disabled}
                            />
                          </span>
                        )}
                        {prepareData(row, column)}
                      </div>
                    </td>
                  );
                })}
              </tr>
            ))}
        </tbody>
      </table>
      {data.length <= 0 && (
        <div
          className="no-data-content"
          style={{ height: `calc(${height} - 50px)` }}
        >
          <NoData
            image={noDataImage ? noDataImage : 'no_data_found'}
            content={noDataContent}
            size={noDataImageSize}
          />
        </div>
      )}
    </div>
  );
};

export default Table;
