import classNames from 'classnames';
import React from 'react';

export interface IColumn<T> {
  label: string | React.ReactNode;
  field?: string;
  className?: string;
  component?: (item: T) => React.ReactNode;
  append?: (item: T) => React.ReactNode;
}

interface IProps<T> {
  columns: IColumn<T>[];
  className?: string;
  placeholder?: string | React.ReactNode;
  bodyClassName?: string;
  itemClassName?: string;
  rowClassName?: string;
  headerClassName?: string;

  data: T[];
  onItemClick?: (item: T) => void;
  itemKey?: (item: T) => string;
}

export const Table = <T extends object>({
  data,
  columns,
  className,
  onItemClick,
  placeholder = 'Нет содержимого',
  bodyClassName = '',
  itemClassName = '',
  rowClassName = '',
  headerClassName = '',
  itemKey,
}: IProps<T>) => {
  return (
    <div className={classNames(className, 'flex flex-col border-t border-b')}>
      <div className='flex h-8 items-center border-b px-5 bg-table-header text-table-text rounded-lg'>
        {columns.map((field, index) => (
          <div
            key={index}
            className={classNames(
              field.className,
              headerClassName,
              'h-full flex items-center py-[15px] first:rounded-tl-lg first:rounded-bl-lg last:rounded-tr-lg last:rounded-br-lg',
            )}
          >
            {field.label}
          </div>
        ))}
      </div>

      <div className={classNames(bodyClassName)}>
        {data.map((el, index) => (
          <div
            key={itemKey ? itemKey(el) : index}
            className={classNames(
              'h-8 flex items-center cursor-pointer px-5 text-table-text',
              {
                'bg-table-body-2 hover:bg-table-body-2-hover': index % 2,
                'bg-table-body-1 hover:bg-table-body-1-hover': !(index % 2),
              },
              rowClassName,
            )}
            onClick={() => onItemClick?.(el)}
          >
            {columns.map((col, index) => {
              const value = !col.component
                ? col.field
                  ? (el as any)[col.field]
                  : null
                : col.component(el);
              const key = ['string', 'number'].includes(typeof value) ? value.toString() : '';

              return (
                <div
                  key={`${index}`}
                  className={classNames(
                    col.className,
                    'h-full flex items-center justify-between px-3',
                    {
                      'border-r': index !== columns.length - 1,
                      'pr-10': index === 0,
                    },
                    itemClassName,
                  )}
                >
                  {value}

                  {col.append && col.append(el)}
                </div>
              );
            })}
          </div>
        ))}
      </div>

      {data.length == 0 && (
        <div className='h-20 flex justify-center items-center'>
          <span className='text-gray-500'>{placeholder}</span>
        </div>
      )}
    </div>
  );
};
