import type { ComputedRef } from 'vue';
import type { BasicTableProps } from '../types/table';
import { unref } from 'vue';
import { ROW_KEY } from '../const';
import { isString, isFunction } from '/@/utils/is';

interface Options {
  setSelectedRowKeys: (keys: string[]) => void;
  getSelectRowKeys: () => string[];
  clearSelectedRowKeys: () => void;
  emit: EmitType;
  getAutoCreateKey: ComputedRef<boolean | undefined>;
}

function getKey(
  record: Recordable,
  rowKey: string | ((record: Record<string, any>) => string) | undefined,
  autoCreateKey?: boolean
) {
  if (!rowKey || autoCreateKey) {
    return record[ROW_KEY];
  }
  if (isString(rowKey)) {
    return record[rowKey];
  }
  if (isFunction(rowKey)) {
    return record[rowKey(record)];
  }
  return null;
}

export function useCustomRow(
  propsRef: ComputedRef<BasicTableProps>,
  { setSelectedRowKeys, getSelectRowKeys, getAutoCreateKey, clearSelectedRowKeys, emit }: Options
) {
  const customRow = (record: Recordable, index: number) => {
    return {
      onClick: (e: Event) => {
        emit('row-click', record, index, e);
        e?.stopPropagation();
        const { rowSelection, rowKey, clickToRowSelect } = unref(propsRef);
        if (!rowSelection || !clickToRowSelect) return;
        const keys = getSelectRowKeys();
        const key = getKey(record, rowKey, unref(getAutoCreateKey));
        if (!key) return;

        const isCheckbox = rowSelection.type === 'checkbox';

        if (isCheckbox) {
          if (!keys.includes(key)) {
            setSelectedRowKeys([...keys, key]);
            return;
          }
          const keyIndex = keys.findIndex((item) => item === key);
          keys.splice(keyIndex, 1);
          setSelectedRowKeys(keys);
          return;
        }

        const isRadio = rowSelection.type === 'radio';
        if (isRadio) {
          if (!keys.includes(key)) {
            if (keys.length) {
              clearSelectedRowKeys();
            }
            setSelectedRowKeys([key]);
            return;
          }
          clearSelectedRowKeys();
        }
      },
      onDblclick: (event: Event) => {
        emit('row-dbClick', record, index, event);
      },
      onContextmenu: (event: Event) => {
        emit('row-contextmenu', record, index, event);
      },
      onMouseenter: (event: Event) => {
        emit('row-mouseenter', record, index, event);
      },
      onMouseleave: (event: Event) => {
        emit('row-mouseleave', record, index, event);
      },
    };
  };

  return {
    customRow,
  };
}
