import { useCallback, useEffect, useMemo, useState } from "react"
import { Button, Form, Modal, Input } from 'antd'
import { CloseOutlined, PlusOutlined, RotateRightOutlined } from '@ant-design/icons'
import style from './style.module.scss'
import { title, compass } from './board'
import ReactEditeTable, { InputEditor } from 'react-edit-table'
import { alert } from 'utils'

import type { Board, BoardShape, ShapeType, ExtractShape } from "./board"
import type { ComponentType } from 'react'
import { useSelector } from "store"
import { usePathData } from "router"


// import { Select } from 'antd'
// import InputColor from 'react-input-color';
// const ColorInput = ({ shape }: { shape: BoardShape }) => (
//   <Form.Item label="颜色" className={style['def-color-item']}>
//     <InputColor 
//       initialValue={shape.data.color || '#000'} 
//       onChange={(color) => shape.setColor(color.rgba)}
//     />
//   </Form.Item>
// )

// const sizeOptions = [6,7,8,9,10,11,12,13,14,16,18,20,28,36,48,72]
//   .map(size => ({ label: `${size}px`, value: size }))
// const FontSizeInput = ({ shape }: { shape: ExtractShape<'fontSize'> }) => (
//   <Form.Item label="字号">
//     <Select
//       defaultValue={shape.data.fontSize}
//       style={{ width: 80 }}
//       onChange={(size) => shape.setFontSize(size)}
//       options={sizeOptions}
//     />
//   </Form.Item>
// )


const TextInput = ({ shape }: { shape: ExtractShape<'text'> }) => {
  const [text, setText] = useState(shape.data.text)
  const onChang = () => {
    shape.setText(text)
    // if (text !== shape.data.text) {
    //   shape.setText(text)
    // }
  }
  return (
    <Form.Item label="内容">
      <Input.Group compact>
        <Input 
          maxLength={50}
          style={{ width: 120 }}
          value={text}
          onKeyDown={
            ev => {
              ev.key === 'Enter' && onChang()
              ev.stopPropagation()
            }
          }
          onBlur={onChang}
          onChange={ev => setText(ev.target.value)}
        />
        <Button type="primary" onClick={onChang}>确定</Button>
      </Input.Group>
      
    </Form.Item>
  )
}

const ContentInput = ({ shape }: { shape: ExtractShape<'content'> }) => {
  const [edit, setEdit] = useState(false)
  const [content, setContent] = useState(shape.data.content)
  const refer = content.filter(item => item.rowIndex === 0)
  const tableAttrs = useMemo(() => {
    const dataSource: string[][] = []
    content.forEach(item => {
      let columns = dataSource[item.rowIndex]
      if (!columns) {
        columns = dataSource[item.rowIndex] = []
      }
      columns[item.colIndex] = item.value
    })

    return {
      columns: refer.map((item, i) => ({
        title: `列${i + 1}`,
        dataIndex: i,
        key: i,
        editor: {
          type: 'input',
          component: InputEditor
        }
      })),
      dataSource
    }
  }, [content, refer])
  const sortContent = () => 
    content.sort((a, b) => {
      const rowDiff: number = a.rowIndex - b.rowIndex
      if (rowDiff) {
        return rowDiff
      } else {
        return a.colIndex - b.colIndex
      }
    })

  const onChange = (data: any) => {
    const newContent = [...content]
    const item = newContent.find(item => item.rowIndex === data.rowIndex && item.colIndex === data.key)
    item!.value = data.newValue
    setContent(newContent)
  }
  const onDelete = (data: any) => {
    if (content.length <= 2) {
      return alert("表格最少需要保留一行！")
    }
    const newContent = sortContent()
    const startIndex = newContent.findIndex(item => item.rowIndex === data.rowIndex)
    const endIndex = startIndex + refer.length
    setContent([
      ...newContent.slice(0, startIndex),
      ...newContent.slice(endIndex).map(item => ({...item, rowIndex: --item.rowIndex}))
    ])
  }
  const onInsert = () => {
    const maxRow = Math.max(...content.map(item => item.rowIndex))
    setContent([
      ...content, 
      ...refer.map(item => ({ ...item, value: '', rowIndex: maxRow + 1 }))
    ])
  }

  const onSubmit = useCallback(() => {
    const rowEls = Array.from(document.querySelectorAll('#edit-table .body-container .row-container')) as HTMLDivElement[]
    const bound = rowEls.map((row, rowIndex) => {
      const cells = Array.from(row.querySelectorAll('.cell')) as HTMLDivElement[]
      return cells.slice(0, -1).map((cell, colIndex) => ({
        width: cell.offsetWidth,
        height: row.offsetHeight - 1,
        value:  content.find(item => item.rowIndex === rowIndex && item.colIndex === colIndex)!.value,
        colIndex,
        rowIndex
      }))
    }).flat()
    setContent(bound)
    shape.setContent(bound)
    console.log(bound)
    setEdit(false)
  }, [content, shape])

  useEffect(() => {
    if (!edit) {
      setContent(shape.data.content || [['', '']])
    }
  }, [edit, shape.data.content])

  useEffect(() => {
    if (shape.autoSet) {
      setEdit(true)
      setTimeout(onSubmit, 100)
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  return (
    <Form.Item label="内容">
      <Button type="primary" onClick={() => setEdit(true)}>编辑</Button>
      <Modal open={edit} onCancel={() => setEdit(false)} onOk={onSubmit} width="430px" className="edit-table-layout">
        <div id="edit-table" onKeyDown={ev => ev.stopPropagation()}>
          { tableAttrs.dataSource.length &&
              <ReactEditeTable 
                {...tableAttrs}
                onDelete={onDelete}
                onChange={onChange} 
              />
          }
          
          <div className={style['add-table-row']}>
            <Button onClick={onInsert} type="primary">
              <PlusOutlined className="icon" /> 行
            </Button>
          </div>
        </div>
      </Modal>
    </Form.Item>
  )
}

const RotateInput = ({ shape }: { shape: ExtractShape<'rotate'> }) => (
  <Button 
    onClick={() => shape.setRotate((shape.data.rotate + 90) % 360)} 
    type="primary" 
    style={{marginRight: '10px'}}
  >
    <RotateRightOutlined /> 旋转
  </Button>
)

const shapeCompontes: { [key in ShapeType]?: ComponentType<{ shape: any }> } = {
  Tag: TextInput,
  Table: ContentInput,
  Compass: RotateInput,
  Title: TextInput
}

export type EShapeProps = {
  board: Board
}
export const EShape = ({ board }: EShapeProps) => {
  const [shape, setShape] = useState<BoardShape | null>(null)  
  const Edit = shape && shapeCompontes[shape.data.type]
  const disabledDelete: boolean = ([title, compass] as any).includes(shape?.data.type)
  const renderDelete = !disabledDelete && (
    <Form.Item label="删除">
      <Button type="primary" onClick={() => shape!.delete()}>删除</Button>
    </Form.Item>
  )

  useEffect(() => {
    board.bus.on('selectShape', setShape)
    return () => {
      board.bus.off('selectShape', setShape)
    }
  }, [board])

  useEffect(() => {
    const keydownHandler = (ev: KeyboardEvent) => {
      if (['Backspace', 'Delete'].includes(ev.key) && shape && !disabledDelete) {
        shape.delete()
      }
    }
    window.addEventListener('keydown', keydownHandler)
    return () => {
      window.removeEventListener('keydown', keydownHandler)
    }
  }, [board, shape, disabledDelete])

  const path = usePathData()
  const user = useSelector(store => store.user.value)
  useEffect(() => {
    if (board && path?.id === '-1') {
      board.calcTableShape([
        ["案发时间", ""],
        ["案发地点", ""],
        ["绘图单位", ""],
        ["绘图人", ""],
        ["绘图时间", ""]
      ]).then(data => {
        board.setDefaultTable(data.content, null)
        board.initHistory()
      })
    } else {
      board.initHistory()
    }
  }, [user, board, path?.id])

  return shape ? (
    <div className={style['def-shape-edit']} style={{ visibility: shape.autoSet ? "hidden" : 'visible' }}>
      { Edit && <Edit shape={shape} /> }
      { renderDelete }
      <div 
        className={`ant-form-item ${style['def-close-shape-edit']}`} 
        onClick={() => setShape(null)}
      >
        <CloseOutlined className={`${style['icon']}`} onClick={() => board.unSelectShape()}  />
      </div>
    </div>
  ) : <></>
}

export default EShape