import {
  Form,
  InputNumber,
  Space,
  Button,
  Input
} from 'antd'
import { MinusCircleOutlined, PlusOutlined, HolderOutlined } from '@ant-design/icons'
import HelpIcon from '../common/help-icon'
import { copy } from '../../common/clipboard'
import { useRef } from 'react'

const FormItem = Form.Item
const FormList = Form.List
const e = window.translate

export default function renderQm (form) {
  const focused = useRef(0)
  const dragIndexRef = useRef(null)

  function handleDragStart (e, index) {
    dragIndexRef.current = index
    e.target.closest('.ant-space-compact')?.classList.add('qm-field-dragging')
    e.dataTransfer.effectAllowed = 'move'
    e.dataTransfer.setData('text/plain', String(index))
  }

  function handleDragOver (e, index) {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
    const el = e.target.closest('.ant-space-compact')
    if (dragIndexRef.current !== index && el) {
      el.classList.add('qm-field-dragover')
    }
  }

  function handleDragLeave (e) {
    e.target.closest('.ant-space-compact')?.classList.remove('qm-field-dragover')
  }

  function handleDrop (e, index, form) {
    e.preventDefault()
    const el = e.target.closest('.ant-space-compact')
    el?.classList.remove('qm-field-dragover')
    const dragIndex = dragIndexRef.current
    if (dragIndex === null || dragIndex === index) {
      dragIndexRef.current = null
      return
    }
    const commands = form.getFieldValue('commands') || []
    const item = commands[dragIndex]
    const newCommands = [...commands]
    newCommands.splice(dragIndex, 1)
    newCommands.splice(index, 0, item)
    form.setFieldValue('commands', newCommands)
    dragIndexRef.current = null
  }

  function handleDragEnd (e) {
    const el = e.target.closest('.ant-space-compact')
    el?.classList.remove('qm-field-dragging')
    el?.classList.remove('qm-field-dragover')
    dragIndexRef.current = null
  }

  function renderItem (field, i, add, remove, form) {
    return (
      <Space.Compact
        align='center'
        className='width-100 mg2b'
        key={field.key}
        draggable
        onDragStart={(e) => handleDragStart(e, i)}
        onDragOver={(e) => handleDragOver(e, i)}
        onDragLeave={handleDragLeave}
        onDrop={(e) => handleDrop(e, i, form)}
        onDragEnd={handleDragEnd}
      >
        <HolderOutlined className='mg1r drag' />

        <Space.Addon>{e('delay')}</Space.Addon>
        <FormItem
          label=''
          name={[field.name, 'delay']}
          required
          noStyle
        >
          <InputNumber
            min={1}
            step={1}
            max={65535}
            placeholder={100}
            className='compact-input'
            suffix='ms'
          />
        </FormItem>
        <FormItem
          label=''
          name={[field.name, 'command']}
          required
          className='mg2x'
          noStyle
        >
          <Input.TextArea
            autoSize={{ minRows: 1 }}
            placeholder={e('quickCommand')}
            className='compact-input qm-input'
            onFocus={() => {
              focused.current = i
            }}
          />
        </FormItem>
        <Button
          icon={<MinusCircleOutlined />}
          onClick={() => remove(field.name)}
        />
      </Space.Compact>
    )
  }
  const commonCmds = [
    { cmd: 'ls', desc: 'List directory contents' },
    { cmd: 'cd', desc: 'Change the current directory' },
    { cmd: 'pwd', desc: 'Print the current working directory' },
    { cmd: 'cp', desc: 'Copy files and directories' },
    { cmd: 'mv', desc: 'Move/rename files and directories' },
    { cmd: 'rm', desc: 'Remove files or directories' },
    { cmd: 'mkdir', desc: 'Create new directories' },
    { cmd: 'rmdir', desc: 'Remove empty directories' },
    { cmd: 'touch', desc: 'Create empty files or update file timestamps' },
    { cmd: 'chmod', desc: 'Change file modes or Access Control Lists' },
    { cmd: 'chown', desc: 'Change file owner and group' },
    { cmd: 'cat', desc: 'Concatenate and display file content' },
    { cmd: 'echo', desc: 'Display message or variable value' },
    { cmd: 'grep', desc: 'Search text using patterns' },
    { cmd: 'find', desc: 'Search for files in a directory hierarchy' },
    { cmd: 'df', desc: 'Report file system disk space usage' },
    { cmd: 'du', desc: 'Estimate file space usage' },
    { cmd: 'top', desc: 'Display Linux tasks' },
    { cmd: 'ps', desc: 'Report a snapshot of current processes' },
    { cmd: 'kill', desc: 'Send a signal to a process' }
  ]

  const cmds = commonCmds.map(c => {
    return (
      <Button
        title={c.desc}
        type='text'
        key={c.cmd}
        size='small'
        onClick={() => {
          copy(c.cmd)
        }}
      >
        <b className='pointer'>{c.cmd}</b>
      </Button>
    )
  })
  const label = (
    <div>
      {e('quickCommands')}
      <HelpIcon
        title={cmds}
      />
    </div>
  )
  return (
    <FormItem label={label}>
      <FormList
        name='commands'
      >
        {
          (fields, { add, remove }, { errors }) => {
            return (
              <>
                {
                  fields.map((field, i) => {
                    return renderItem(field, i, add, remove, form)
                  })
                }
                <FormItem>
                  <Button
                    type='dashed'
                    onClick={() => add()}
                    icon={<PlusOutlined />}
                  >
                    {e('quickCommand')}
                  </Button>
                </FormItem>
              </>
            )
          }
        }
      </FormList>
    </FormItem>
  )
}
