import {
  h,
  defineComponent,
  inject,
  getCurrentInstance,
  onMounted,
  nextTick,
  ref,
} from 'vue';
import IvueIcon from '../../ivue-icon/index.vue';

import useUtils from './utils';
import useStyle from './styles';
import useEvent from './events';
import useTableLayoutObserver from '../table-layout-observer';

// 过滤组件
import FilterPanel from '../table/filter-panel.vue';

// ts
import { TableContextKey } from '../table/defaults';
import type { TableColumnCtx } from '../table-column/defaults';
import type { PropType } from 'vue';
import type {
  TableHeader,
  FilterPanelInstance,
  TableHeaderProps,
} from './types';

const prefixCls = 'ivue-table';

export default defineComponent({
  props: {
    /**
     * 列是否固定在左侧或者右侧。 true 表示固定在左侧
     *
     * @type {String}
     */
    fixed: {
      type: String,
      default: '',
    },
    /**
     * store
     *
     * @type {Object}
     */
    store: {
      required: true,
      type: Object as PropType<TableHeaderProps['store']>,
    },
    /**
     * 是否带有纵向边框
     *
     * @type {Boolean}
     */
    border: {
      type: Boolean,
      default: false,
    },
    /**
     * 默认的排序列的 prop 和顺序。
     *
     * @type {Object}
     */
    defaultSort: {
      type: Object as PropType<TableHeaderProps['defaultSort']>,
      default: () => {
        return {
          prop: '',
          order: '',
        };
      },
    },
    /**
     * tooltip点击是否阻止当前事件在捕获和冒泡阶段的进一步传播
     *
     * @type {Boolean}
     */
    tooltipStop: {
      type: Boolean,
    },
  },
  setup(props: TableHeaderProps, { emit }) {
    // vm
    const vm = getCurrentInstance() as TableHeader;

    // inject
    const IvueTable = inject(TableContextKey);

    // data

    // 过滤的列节点
    const filterPanels = ref<Record<number, FilterPanelInstance>>({});

    const {
      // 获取当前列的行数
      columnRows,
      isGroup,
    } = useUtils(props);

    const {
      // 头部行样式
      getHeaderCellClass,
      getHeaderCellStyle,
      getHeaderRowStyle,
      getHeaderRowClass,
    } = useStyle(props);

    // 事件
    const {
      handleSortClick,
      handleHeaderClick,
      handleMouseDown,
      handleMouseMove,
      handleMouseOut,
    } = useEvent(props, emit);

    // 布局改变监听
    const { handleColumnsChange, handleScrollableWidthChange } =
      useTableLayoutObserver(IvueTable);

    vm.state = {
      handleColumnsChange,
      handleScrollableWidthChange,
    };

    vm.filterPanels = filterPanels;

    // methods

    // 渲染排序
    const renderSortable = (column) => {
      // 是否有排序
      if (!column.sortable) {
        return null;
      }

      return h(
        'span',
        {
          class: `${prefixCls}-header--sortable`,
        },
        [
          // 上按钮
          h(
            IvueIcon,
            {
              class: `${prefixCls}-header--ascending`,
              onClick: ($event: Event) => {
                handleSortClick($event, column, 'ascending');
              },
            },
            {
              default: () => 'arrow_drop_up',
            }
          ),
          // 下按钮
          h(
            IvueIcon,
            {
              class: `${prefixCls}-header--descending`,
              onClick: ($event: Event) => {
                handleSortClick($event, column, 'descending');
              },
            },
            {
              default: () => 'arrow_drop_down',
            }
          ),
        ]
      );
    };

    // 渲染头部
    const renderHeader = (column, cellIndex: number) => {
      // 是否有头部
      if (!column.renderHeader) {
        return column.label;
      }

      return h('span', {}, [
        column.renderHeader({
          column,
          $index: cellIndex,
          store: props.store,
          _self: vm.$parent,
        }),
      ]);
    };

    // 渲染过滤
    const renderFilter = (column: TableColumnCtx) => {
      if (!column.filterable) {
        return null;
      }

      return h(FilterPanel, {
        // 当前列
        column,
        // store
        store: props.store,
        // 过滤弹出框的定位
        placement: column.filterPlacement,
        // tooltip点击是否阻止当前事件在捕获和冒泡阶段的进一步传播
        tooltipStop: props.tooltipStop,
        // 更新列数据
        upDataColumn: (key: string, value: boolean) => {
          column[key] = value;
        },
      });
    };

    // 渲染 th
    const renderTh = (
      list: TableColumnCtx[],
      rowSpan: number,
      rowIndex: number
    ) => {
      return list.map((column: TableColumnCtx, cellIndex: number) => {
        // 规定单元格可横跨的行数
        if (column.rowSpan > rowSpan) {
          rowSpan = column.rowSpan;
        }

        return h(
          'th',
          {
            // class
            class: getHeaderCellClass(rowIndex, cellIndex, list, column),
            // style
            style: getHeaderCellStyle(rowIndex, cellIndex, list, column),
            // 规定单元格可横跨的列数。
            colspan: column.colSpan,
            // 规定单元格可横跨的行数
            rowspan: column.rowSpan,
            // key
            key: `${column.id}-thead`,
            onClick: ($event: Event) => {
              // 头部点击
              handleHeaderClick($event, column);
            },
            // 鼠标按下
            onMousedown: ($event: MouseEvent) => {
              handleMouseDown($event, column);
            },
            // 鼠标移动
            onMousemove: ($event: MouseEvent) => {
              handleMouseMove($event, column);
            },
            // 鼠标退出
            onMouseout: () => {
              handleMouseOut();
            },
          },
          [
            // cell
            h(
              'div',
              {
                class: [
                  'cell',
                  // 是否有选择过滤
                  column.filteredValue && column.filteredValue.length > 0
                    ? 'highlight'
                    : '',
                ],
              },
              h(
                'div',
                {
                  class: 'cell-content',
                },
                [
                  // 渲染头部
                  renderHeader(column, cellIndex),
                  // 排序
                  renderSortable(column),
                  // 渲染过滤
                  renderFilter(column),
                ]
              )
            ),
          ]
        );
      });
    };

    // onMounted
    onMounted(() => {
      nextTick(() => {
        const { prop, order } = props.defaultSort;

        IvueTable?.store.commit('sort', { prop, order, init: true });
      });
    });

    return {
      // data
      filterPanels,

      // computed
      isGroup,
      columnRows,

      // methods
      renderTh,
      handleColumnsChange,
      getHeaderRowStyle,
      getHeaderRowClass,
    };
  },
  render() {
    const {
      columnRows,
      renderTh,
      isGroup,
      getHeaderRowStyle,
      getHeaderRowClass,
    } = this;

    const rowSpan = 1;

    return h(
      'thead',
      {
        class: {
          ['is-group']: isGroup,
        },
      },
      columnRows.map((item: TableColumnCtx, rowIndex: number) => {
        return h(
          'tr',
          {
            class: getHeaderRowClass(rowIndex),
            style: getHeaderRowStyle(rowIndex),
            key: rowIndex,
          },
          renderTh(item, rowSpan, rowIndex)
        );
      })
    );
  },
});
