import React, { ChangeEvent, useCallback } from "react";
import { faSortAsc, faSortDesc } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Column from "./columns";
import Input, { InputType } from "./Input";

export interface TableHeaderProps<T> {
  sortColumn?: Column<T>;
  columns: Column<T>[];
  showDelete?: boolean;
  showEdit?: boolean;
  showAudit?: boolean;
  showSecondaryAudit?: boolean;
  onSort?: (sortColumn: Column<T>) => void;
  onSearch?: (name: string, value: string) => void;
}

export default function TableHeader<T>({
  sortColumn,
  columns,
  showEdit,
  showDelete,
  showAudit,
  showSecondaryAudit,
  onSort,
  onSearch,
}: TableHeaderProps<T>): JSX.Element {
  const columnsMatch = useCallback((left?: Column<T>, right?: Column<T>) => {
    return left?.key === right?.key;
  }, []);

  const raiseSort = useCallback(
    (column: Column<T>) => {
      let sc = sortColumn;

      if (sc) {
        if (columnsMatch(column, sc)) {
          sc.order = sc.order === "asc" ? "desc" : "asc";
        } else {
          sc = column;
          sc.order = "asc";
        }

        if (onSort) onSort(sc);
      }
    },
    [sortColumn, onSort, columnsMatch],
  );

  const renderSortIcon = useCallback(
    (column: Column<T>) => {
      if (!sortColumn) return null;
      if (!columnsMatch(column, sortColumn)) return null;
      return sortColumn.order === "asc" ? (
        <FontAwesomeIcon icon={faSortAsc} />
      ) : (
        <FontAwesomeIcon icon={faSortDesc} />
      );
    },
    [sortColumn, columnsMatch],
  );

  const changeSearch = useCallback(
    (e: ChangeEvent<HTMLInputElement>) => {
      if (onSearch) onSearch(e.target.name, e.target.value);
    },
    [onSearch],
  );

  const searchRow = onSearch ? (
    <tr>
      {columns.map((column) => (
        <th key={column.path || column.key}>
          {(column.searchable === undefined || column.searchable === true) && (
            <Input
              name={column.path || column.key}
              label={""}
              error={""}
              type={InputType.text}
              onChange={changeSearch}
            />
          )}
        </th>
      ))}
      {showEdit && <th></th>}
      {showDelete && <th></th>}
      {showAudit && <th></th>}
      {showAudit && showSecondaryAudit && <th></th>}
    </tr>
  ) : (
    <></>
  );

  return (
    <thead>
      <tr>
        {columns.map((column) => (
          <th
            className="text-nowrap"
            key={column.path || column.key}
            scope="col"
            onClick={() => raiseSort(column)}
          >
            {column.label} {renderSortIcon(column)}
          </th>
        ))}
        {showEdit && <th scope="col"></th>}
        {showDelete && <th scope="col"></th>}
        {showAudit && <th scope="col"></th>}
        {showAudit && showSecondaryAudit && <th scope="col"></th>}
      </tr>
      {searchRow}
    </thead>
  );
}
