import clsx from 'clsx';
import React, { PropsWithChildren } from 'react';
import { noop } from '../../../../helpers/utils';
import { SvgElement } from '../../../VisualElements/SvgElement';
import { ColumnSortKeys, SortData } from '../../List.model';
import classes from './ColumnLabel.scss';

interface ColumnLabelProps<T> {
  /** Column label */
  label?: string;
  /** Data object's property name associated with this column */
  propertyName: keyof T | undefined;

  /** If set to false, disables sorting for this column (default: true) */
  sortable?: boolean;
  /** If set, allow to directly specify which sorting enum value to use */
  columnSortKeys?: ColumnSortKeys;
  /** Defines how the list data should be sorted. */
  sortData?: SortData<T>;
  /** Callback to emit when a user clicks on this component. The name of the property and the order of the direction are sent back. */
  onSortChanged?: (sort: SortData<T>) => void;
}

export const ColumnLabel = <T,>({
  label,
  propertyName,
  sortable = true,
  columnSortKeys,
  sortData,
  onSortChanged = noop,
}: PropsWithChildren<ColumnLabelProps<T>>): JSX.Element => {
  /** Creates sort data object to be emitted back on change event. */
  const getSortDir = (propertyName: keyof T): SortData<T> => {
    if (sortData?.column === propertyName && sortData.direction === 'asc') {
      return {
        column: propertyName,
        direction: 'desc',
        columnSortKey: columnSortKeys?.descending,
      };
    } else {
      return {
        column: propertyName,
        direction: 'asc',
        columnSortKey: columnSortKeys?.ascending,
      };
    }
  };

  /** Determines if the current column is currently being used to sort and which direction. */
  const direction =
    sortData?.column === propertyName ? sortData?.direction : undefined;

  if (!propertyName || !sortable) {
    return (
      <div
        className={classes.container}
        data-test-id={`list-label:${String(propertyName)}`}
      >
        <span className={classes.label}>{label ?? propertyName}</span>
      </div>
    );
  } else {
    return (
      <div className={classes.container}>
        <div
          className={clsx(classes.clickWrapper, classes.sortable)}
          onClick={
            propertyName &&
            ((e) => {
              onSortChanged(getSortDir(propertyName));
              e.stopPropagation();
            })
          }
          data-test-id={`list-label:${String(propertyName)}`}
          data-test-sort-dir={direction ?? 'none'}
        >
          <span className={classes.label} title={label ?? String(propertyName)}>
            {label ?? propertyName}
          </span>
          <div className={classes.arrows}>
            <SvgElement viewBox="0 0 13 10">
              <path
                className={clsx({ [classes.sorted]: direction === 'asc' })}
                d="M1.5,7.3l4.8-5.7l5.2,5.7"
              ></path>
            </SvgElement>
            <SvgElement viewBox="0 0 13 10">
              <path
                className={clsx({ [classes.sorted]: direction === 'desc' })}
                d="M11.5,2.8L6.7,8.5L1.5,2.8"
              ></path>
            </SvgElement>
          </div>
        </div>
      </div>
    );
  }
};
