import { Table, Transfer } from 'antd'
import type { ColumnsType, TableRowSelection } from 'antd/es/table/interface'
import type { TransferProps } from 'antd/es/transfer'
import difference from 'lodash/difference'

import { DataType } from './helpers'

interface TableTransferProps
  extends Pick<
    TransferProps<DataType>,
    'dataSource' | 'targetKeys' | 'onChange'
  > {
  loading?: boolean
  mode?: 'edit' | 'view'
}

/**
 * Customize Table Transfer
 */
export const TableTransfer = ({
  mode = 'edit',
  loading,
  ...transferProps
}: TableTransferProps) => {
  const editable = mode === 'edit'

  return (
    <Transfer
      titles={['Unassigned Privileges', 'Assigned Privileges']}
      disabled={loading}
      showSearch
      {...(editable
        ? {}
        : { showSelectAll: false, operationStyle: { visibility: 'hidden' } })}
      filterOption={(inputValue, item) =>
        item.resource_uri.includes(inputValue)
      }
      locale={{
        searchPlaceholder: 'Please input Resouce URI to filter',
        notFoundContent: 'No Privileges'
      }}
      rowKey={(row) => row.id}
      {...transferProps}
    >
      {({
        filteredItems,
        onItemSelectAll,
        onItemSelect,
        selectedKeys: transferSelectedKeys
      }) => {
        const rowSelection: TableRowSelection<DataType> = {
          onSelectAll(selected, selectedRows) {
            const tableSelectedKeys = selectedRows.map((row) => row.id)

            // Exclude disabled rows
            const diffKeys = selected
              ? difference(tableSelectedKeys, transferSelectedKeys)
              : difference(transferSelectedKeys, tableSelectedKeys)

            // Update transferSelectedKeys
            onItemSelectAll(diffKeys, selected)
          },
          onSelect(row, selected) {
            // Update transferSelectedKeys
            onItemSelect(row.id, selected)
          },
          // Use transferSelectedKeys to console table rows selection
          selectedRowKeys: transferSelectedKeys
        }

        const columns: ColumnsType<DataType> = [
          {
            title: 'Resource URI',
            dataIndex: 'resource_uri',
            width: 200,
            render: (value) => (
              <span style={{ wordBreak: 'break-all' }}>{value}</span>
            )
          },
          {
            title: 'System',
            dataIndex: 'system',
            filters: Array.from(
              new Set(filteredItems.map((item) => item.system))
            ).map((value) => ({
              value: value,
              text: value
            })),
            onFilter: (value, record) => record.system === value
          },
          {
            title: 'Description',
            dataIndex: 'description'
          }
        ]

        return (
          <Table
            rowSelection={editable ? rowSelection : undefined}
            columns={columns}
            dataSource={filteredItems}
            loading={loading}
            size="small"
            scroll={{ y: 400 }}
            pagination={{ defaultPageSize: 5, showSizeChanger: false }}
          />
        )
      }}
    </Transfer>
  )
}
