import { createElement, FunctionComponent } from 'rax';
import View from "rax-view";
import Text from "rax-text";
import { getJustifyContent } from "./util";
import Icon from "@rax-ui/icon";
import { ColumnProps } from './interface';

const TableHeader: FunctionComponent<any> = (props: any) => {
  const {
    columns,
    onSort,
    bordered,
    sortIconRender,
    descIconRender,
    onClickDescIcon,
    styles,
  } = props;

  const onHeaderRow = (method: string, extraParam) => {
    const { onHeaderRow } = props;
    if (typeof onHeaderRow === "function") {
      const eventMap = onHeaderRow(columns, 0);
      if (eventMap && typeof eventMap[method] === "function") {
        return eventMap[method](extraParam);
      }
    }
    return null;
  }

  const onHeaderCell = (method: string, column: ColumnProps, extraParam) => {
    if (typeof column.onHeaderCell === "function") {
      const eventMap = column.onHeaderCell(column);
      if (eventMap && typeof eventMap[method] === "function") {
        return eventMap[method](extraParam);
      }
    }
    return null;
  }

  const onColumnDesc = (column: ColumnProps, event) => {
    event.stopPropagation();
    if (onClickDescIcon && typeof onClickDescIcon === "function") {
      onClickDescIcon(column, event);
    } else {
      alert(column.desc);
    }
  }

  const onSortFn = (column: ColumnProps, event) => {
    event.stopPropagation();
    if (onSort) {
      onSort(column);
    }
  }

  const renderDescIcon = (column: ColumnProps) => {
    let descIcon = null;
    if (column.desc != null && column.desc.length) {
      descIcon = (descIconRender && descIconRender(column)) || (
        <View style={styles.headerDesc} onClick={(event) => onColumnDesc(column, event)}>
          <Icon name="prompt" style={styles.headerDescIcon}/>
        </View>
      );
    }
    return descIcon;
  }

  const renderSortIcon = (column: ColumnProps) => {
    let { sortOrder } = column;
    if (!column.sorter) {
      return null;
    }
    const { styles, sortColumn, defaultSortDirections } = props;
    let { sortDirections } = column;
    if (!sortDirections) {
      sortDirections = defaultSortDirections;
    }

    if (sortColumn && column.key === sortColumn.key) {
      const sortColumnSortOrder = sortColumn.sortOrder;
      sortOrder = sortColumnSortOrder;
    }
    if (sortIconRender) {
      return (
        <View style={styles.sort} onClick={(event) => onSortFn(column, event)}>
          {sortIconRender(column, sortOrder)}
        </View>
      );
    }
    let ascIconStyle = { ...styles.sortIcon, ...styles.sortIconAsce };
    if (sortOrder && sortOrder === "ascend") {
      ascIconStyle = { ...ascIconStyle, ...styles.sortIconSelected };
    }
    let descIconStyle = { ...styles.sortIcon, ...styles.sortIconDesc };
    if (sortOrder && sortOrder === "descend") {
      descIconStyle = { ...descIconStyle, ...styles.sortIconSelected };
    }
    if (sortDirections) {
      if (sortDirections.indexOf("ascend") === -1) {
        ascIconStyle.opacity = 0;
      }
      if (sortDirections.indexOf("descend") === -1) {
        descIconStyle.opacity = 0;
      }
    }
    return (
      <View style={styles.sort} onClick={(event) => onSortFn(column, event)}>
        <Icon name="sort-ascend" style={ascIconStyle} />
        <Icon name="sort-descend" style={descIconStyle} />
      </View>
    );
  }

  const renderChildren = (column: ColumnProps) => {
    const children = [];
    if (column.children && Array.isArray(column.children)) {
      column.children.forEach((subColumn, index) => {
        const isLast = index === column.children.length - 1;
        children.push(renderHeaderCell(subColumn, isLast));
      });
    }
    return children.length >= 1 ? <View style={{ flexDirection: "row" }}>{children}</View> : null;
  }

  const renderHeaderCell = (column, isLast?: boolean) => {
    const justifyContent = getJustifyContent(column);
    const descIcon = renderDescIcon(column);
    const sortIcon = renderSortIcon(column);
    const children = renderChildren(column);
    const paddingLeft = column.hidden ? 0 : 20;
    let paddingRight = column.hidden ? 0 : 20;
    if (descIcon) {
      paddingRight = 0;
    }

    let widthStyle;
    if (column.width && column.width > 0) {
      widthStyle = { width: column.width };
    } else {
      widthStyle = { flex: column.flex || 1 };
    }
    let defaultStyle = {
      ...styles.cell,
      ...styles.headerMinHeight,
      ...styles.headerCellPadding,
      ...widthStyle
    };
    if (column.hidden) {
      defaultStyle.opacity = 0;
    } else if (bordered) {
      if (column.children && Array.isArray(column.children)) {
        defaultStyle = { ...defaultStyle, ...styles.rowBorder };
      } else {
        defaultStyle = { ...defaultStyle };
      }
    }
    defaultStyle.paddingLeft = paddingLeft;
    defaultStyle.paddingRight = paddingRight;
    defaultStyle.justifyContent = justifyContent;
    const customStyle = onHeaderCell("customStyle", column, defaultStyle);

    const titleDefaultStyle = styles.headerTitle;
    titleDefaultStyle.flexWrap = "nowrap";
    const titleCustomStyle = onHeaderCell("titleCustomStyle", column, titleDefaultStyle);

    let groupStyle = { ...styles.headerGroup, ...widthStyle };
    if (!isLast && bordered) {
      groupStyle = { ...groupStyle, ...styles.columnBorder };
    }
    return (
      <View class="table-header-cell" style={groupStyle} key={column.key}>
        <View
          onClick={(event) => {
            onHeaderCell("onClick", column, event);
            onSort(column, event);
          }}
          onAppear={(event) => { onHeaderCell("onAppear", column, event); }}
          onDisappear={(event) => { onHeaderCell("onDisappear", column, event); }}
          onLongPress={(event) => { onHeaderCell("onLongPress", column, event); }}
          style={customStyle || defaultStyle}
        >
          <Text style={titleCustomStyle || titleDefaultStyle}>{column.title}</Text>
          {sortIcon}
          {descIcon}
        </View>
        {children}
      </View>
    );
  }

  const headerCells = [];
  columns.forEach((column: ColumnProps) => {
    headerCells.push(renderHeaderCell(column));
  });

  const defaultStyle = {
    ...styles.header,
    ...styles.headerMinHeight
  };
  const customStyle = onHeaderRow("customStyle", defaultStyle);
  return (
    <View
      class="table-header"
      style={customStyle || defaultStyle}
      onClick={(event) => { onHeaderRow("onClick", event); }}
      onAppear={(event) => { onHeaderRow("onAppear", event); }}
      onDisappear={(event) => { onHeaderRow("onDisappear", event); }}
      onLongPress={(event) => { onHeaderRow("onLongPress", event); }}
    >
      {headerCells}
    </View>
  );
}

export default TableHeader;
