/*
 * @Author: your name
 * @Date: 2022-01-11 16:03:24
 * @LastEditTime: 2023-03-03 16:12:49
 * @LastEditors: code4eat awesomedema@gmail.com
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /KC-MiddlePlatform/src/components/kcTable/index.tsx
 */

import React, { useState, useEffect, useRef, useMemo } from 'react';
import ProTable, { ActionType, ProColumns } from '@ant-design/pro-table';
import { message } from 'antd';
import { KCTableType } from './typing';
import './style.less';
import { useDrag, useDrop } from 'react-dnd';

const KCTable: React.FC<KCTableType.KCTableProps<any, { current?: number; pageSize?: number; [key: string]: any }>> = ({
  columns,
  reload,
  newVer,
  params,
  request,
  onChange,
  dragSort,
  dragSortKey,
  dragType,
  disabledDragKeys,
  onDragSortEnd,
  ...restProps
}) => {
  const [tableColumns, setTableColumns] = useState<ProColumns[]>([]);
  const actionRef = useRef<ActionType>();
  const type = dragType || 'KC_TABLE_ROW'; // 使用自定义类型或默认类型

  useEffect(() => {
    setTableColumns(
      columns.map((t) => ({
        hideInSearch: true,
        ...t,
      })),
    );
  }, [columns]);

  useEffect(() => {
    if (reload) {
      actionRef.current?.reload();
    }
  }, [reload]);

  // 处理分页变化
  const handleTableChange = (pagination: any, filters: any, sorter: any, extra: any) => {
    if (onChange) {
      onChange(pagination, filters, sorter, extra);
    }
  };

  const moveRow = React.useCallback((dragIndex: number, hoverIndex: number) => {
    if (!onDragSortEnd) {
      return;
    }
    const raw = (restProps as any).dataSource || [];
    // 仅当存在有效数组时才排序，防止非对象触发下游渲染问题
    if (!Array.isArray(raw) || raw.length === 0) {
      return;
    }
    const data = raw.map((x: any) => (x && typeof x === 'object' ? { ...x } : x));
    const newData = data.slice();
    const dragRow = newData[dragIndex];
    if (typeof dragRow !== 'object') {
      return;
    }
    newData.splice(dragIndex, 1);
    newData.splice(hoverIndex, 0, dragRow);
    // 避免在 rc-table 渲染周期内立即变更数据导致内部校验异常，异步派发
    setTimeout(() => onDragSortEnd(newData), 0);
  }, [onDragSortEnd, restProps, dragSort]);

  const components = useMemo(() => {
    if (!dragSort) {
      return undefined;
    }
    // 行组件：支持拖拽排序
    const DragRow: React.FC<any> = ({ className, style, index, record, children, moveRow: moveRowProp, ...rest }) => {
      const ref = useRef<HTMLTableRowElement>(null);
      
      // 获取行的 key，判断是否禁用拖拽
      const rowKeyValue = dragSortKey ? record?.[dragSortKey] : record?.id;
      const isDisabled = disabledDragKeys && disabledDragKeys.includes(rowKeyValue);

      const [, drop] = useDrop({
        accept: type,
        hover: (item: any, monitor: any) => {
          if (!ref.current) return;
          if (isDisabled) return; // 禁用行不响应 hover
          const dragIndex = item.index;
          const hoverIndex = index;
          if (dragIndex === hoverIndex) return;
          const clientOffset = monitor.getClientOffset();
          const hoverBoundingRect = ref.current.getBoundingClientRect();
          const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
          const hoverClientY = clientOffset ? clientOffset.y - hoverBoundingRect.top : 0;
          if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) return;
          if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) return;
          // 使用从 props 传入的 moveRow
          if (moveRowProp) {
            moveRowProp(dragIndex, hoverIndex);
          }
          item.index = hoverIndex;
        },
        collect: (monitor) => ({
          isOver: monitor.isOver(),
        }),
      });

      const [{ isDragging }, drag] = useDrag({
        type,
        item: { index },
        canDrag: () => {
          if (isDisabled) {
            message.warning('请先收起展开的行，再进行排序操作');
            return false;
          }
          return true;
        },
        collect: (monitor) => ({ isDragging: monitor.isDragging() }),
      });

      // 所有行都应用拖拽，这样才能触发 canDrag 回调显示提示
      drag(drop(ref));

      return (
        <tr 
          ref={ref} 
          className={className} 
          style={{ 
            opacity: isDragging ? 0.5 : 1, 
            cursor: isDisabled ? 'not-allowed' : 'move',
            ...style 
          }} 
          {...rest}
        >
          {children}
        </tr>
      );
    };

    return {
      body: {
        row: (props: any) => <DragRow {...props} />,
      },
    } as any;
  }, [dragSort, type, disabledDragKeys, dragSortKey]);

  if(newVer){
    return (
        <ProTable
          tableStyle={{
            border: '1px solid #DAE2F2',
            borderRadius:4
          }}
          toolBarRender={false}
          search={false}
          className="KCTable"
          actionRef={actionRef}
          columns={tableColumns}
          pagination={{
            defaultPageSize: 10,
            current: params?.current,
            pageSize: params?.pageSize
          }}
          onChange={handleTableChange}
          params={params}
          request={request}
          components={components}
          onRow={(record: any, index) => {
            if (!dragSort) return {} as any;
            return {
              index,
              record,
              moveRow,
            } as any;
          }}
          {...restProps}
        />
    );
  }else{
    return (
        <ProTable
          tableStyle={{
            border: '1px solid #DAE2F2',
            borderRadius:4
          }}
          className="KCTable"
          actionRef={actionRef}
          columns={tableColumns}
          pagination={{ 
            defaultPageSize: 10,
            current: params?.current,
            pageSize: params?.pageSize
          }}
          onChange={handleTableChange}
          params={params}
          request={request}
          components={components}
          onRow={(record: any, index) => {
            if (!dragSort) return {} as any;
            return {
              index,
              record,
              moveRow,
            } as any;
          }}
          {...restProps}
        />
    );
  }
};

export default KCTable;
