import React, { useEffect } from 'react'
import { Tooltip, Tag, Typography, Space, Button, Modal, Spin, Select, } from 'antd'
import {
  EllipsisOutlined,
  PlusOutlined,
} from '@ant-design/icons'
import produce from 'immer'

import DataQuality, { DataQualityFeighTagSelect } from '../../../QianKun/DataQualitySzse'
import { showMessage } from '../../../../util'
import { dispatch } from '../../../../model'
import { AppContext } from '../../../../App'

const FC = ({ type, id, did, tags, onChange }) => {
  const [data, setData] = React.useState([])
  const [tagSelectPopupParams, setTagSelectPopupParams] = React.useState({
    visible: false,
    type: undefined,
    items: undefined,
  })

  useEffect(() => {
    setData(tags)
  }, [tags])

  const storageChange = (e) => {
    if (e.key === 'tagChangeEvent' && e.id === id) {
      getTags()
    }
  }

  React.useEffect(() => {
    window?.addEventListener("storage", storageChange)
    return () => {
      window?.removeEventListener("storage", storageChange)
    }
  }, [type, id])

  const getTags = () => {
    dispatch({
      type: 'tag.getResourceTagIn',
      payload: {
        params: {
          resourceIds: id,
          includeAll: true,
          includePrivate: true
        }
      },
      callback: data => {
        setData(data?.data?.[`${id}`]);
        onChange?.(data?.data?.[`${id}`]);
      }
    });
  }

  //资产或者资源详情里的标签同步
  const syncTag = () => {
    if (type === 'dataAsset') {
      let event = new Event('storage')
      event.key = 'assetListTagChangeEvent'
      event.id = id
      window?.dispatchEvent(event)
    }
  }

  return (
    <React.Fragment>
      <TagCell 
        value={data}
        onChange={(val) => {
          getTags()
          syncTag()
        }} 
        onAdd={(val) => {
          setTagSelectPopupParams({
            visible: true,
            type,
            items: [{ resourceId: id, catalogId: did, type, }]
          })
        }}
      />
       <TagSelectPopup 
        onCancel={() => {
          setTagSelectPopupParams({
            visible: false,
            type: undefined,
            items: undefined
          })
        }}
        onChange={(val) => {
          getTags()
          syncTag()
        }}
        {...tagSelectPopupParams}
      />
    </React.Fragment>
  )
}

export default FC

export const TagRender = (props) => {
  const { data, closable, onClose, style, ...restProps } = props;

  const color = React.useMemo(() => {
    if (data) {
      return (data.type==='public') ? '#196AD2' : '#4C7813'
    }
    return ''
  }, [data])

  const onPreventMouseDown = (event) => {
    event.preventDefault();
    event.stopPropagation();
  };
  
  return (
    <Tooltip title={data?.name}>
      <Tag
        onMouseDown={onPreventMouseDown}
        closable={closable}
        onClose={onClose}
        style={{
          marginRight: 3,
          padding: '2px 7px',
          textAlign: 'center',
          borderColor: color,
          color,
          backgroundColor: '#fff',
          ...style
        }}
        {...restProps}
      > 
        <Typography.Text ellipsis={true} style={{ width: 56 }}>
          <span style={{ color }}>{data?.name}</span>
        </Typography.Text>
      </Tag>
    </Tooltip>
  );
};

export function TagCell({ value, readonly = false, onChange, onAdd }) {
  const maxShowCount = 3

  const [haveMore, _value] = React.useMemo(() => {
    return [(value??[]).length>maxShowCount, (value??[]).slice(0, maxShowCount)]
  }, [value])

  const onClose = (e, tag) => {
    e.preventDefault()
    if (tag?.id) {
      dispatch({
        type: 'tag.deleteTags',
        payload: {
          tagInResourceIds: tag?.id
        },
        callback: () => {
          showMessage('success', '删除成功');
          onChange?.()
        }
      })
    }
  }

  return (
    <div style={{ 
      display: 'flex',
      marginRight: '12px',
      justifyContent: 'space-between',
      alignItems: 'center',
      height: '100%',
    }}>
    {
      _value?.map((item, index) => <TagRender 
        key={item.id} 
        data={item} 
        closable={!readonly&&item?.deleteAble}
        onClose={(e) => {
          onClose(e, item)
        }}
        style={{ marginRight: 0 }}
      />)
    }
    {
      haveMore && <Tooltip title={
        <Space wrap={true}>
          {
            value?.map((item, index) => <TagRender 
              key={item.id} 
              data={item} 
              closable={!readonly&&item?.deleteAble}
              onClose={(e) => {
                onClose(e, item)
              }}
            />)
          }
        </Space>
      }>
        <Button size='small' icon={<EllipsisOutlined />}></Button>
      </Tooltip>
    }
    {
      !readonly && <Button size='small' icon={<PlusOutlined />} onClick={(e) => {
        e.stopPropagation()
        onAdd?.()
      }}></Button>
    }
    <React.Fragment>
    {
      (_value??[]).length < maxShowCount && Array.from({ length: maxShowCount-_value.length }, (_, key) => <div key={key} style={{ width: 80 }} />)
    }
    </React.Fragment>
    {
      !haveMore && <div style={{ width: 24 }} />
    }
    </div>
  )
}

export function TagSelect({ options, onChange }) {
  const [popupParams, setPopupParams] = React.useState({
    visible: false,
    value: undefined
  })

  return (
    <React.Fragment>
      <Select
        mode='multiple'
        placeholder='请选择标签'
        tagRender={(props) => {
          const { value } = props
          const index = (options??[]).findIndex(item => item.value === value)
          if (index !== -1) {
            return <TagRender key={value} data={options[index]} {...props} />
          }

          return <React.Fragment></React.Fragment>
        }}
        onDropdownVisibleChange={(open) => {
          if (open) {
            setPopupParams({
              visible: true,
              value: options
            })
          }
        }}
        open={false}
        style={{ width: 200 }}
        value={(options??[]).map(item => item.value)}
        options={options}
        allowClear
        onChange={(newValue) => {
          const newOptions = (options??[]).filter(item => newValue.indexOf(item.value) !== -1)

          onChange?.(newOptions)
        }}
        maxTagCount='responsive'
      />

      <TagSelectPopup
        value={options}
        onCancel={(value) => {
          setPopupParams({
            visible: false,
            value: undefined
          })
        }}
        onChange={(value) => {
          const newOptions = produce(value??[], (draft) => {
            draft?.forEach(item => {
              item.value = item.id
              item.label = item.name
            })
          })

          onChange?.(newOptions)
        }}
        {...popupParams}
      />
    </React.Fragment>
  )
}

export function TagSelectPopup({ visible, type, value, items, onCancel, onChange, }) {
  const [waiting, setWaiting] = React.useState(false)
  const [selectedRows, setSelectedRows] = React.useState([])
  const [showDataQuality, setShowDataQuality] = React.useState(false)
  const app = React.useContext(AppContext)

  React.useEffect(() => {
    if (visible) {
      setTimeout(() => {
        setShowDataQuality(true)
      }, 300)
    }
  }, [visible])

  const close = () => {
    setWaiting(false)
    setShowDataQuality(false)
    setSelectedRows([])
    onCancel?.()
  }

  const save = async () => {
    if (items) {
      if ((selectedRows??[]).length === 0) {
        showMessage('warn', '请先选择标签')
        return
      }

      setWaiting(true)
      dispatch({
        type: 'tag.addTags',
        payload: {
          params: {
            tagIds: (selectedRows??[]).map(item => item.id).toString(),            
            creator: app?.user?.userName,
            overrideAll: (items??[]).length === 1 ? true : false,
          },
          data: items
        },
        callback: () => {
          setWaiting(false)
          onChange?.(selectedRows)
          close()
        },
        error: () => {
          setWaiting(false)
        }
      })
    } else {
      onChange?.(selectedRows)
      close()
    }
  }

  const footer = React.useMemo(() => {
    return [
      <Button key={'cancel'}
        onClick={() => close()}
      >取消</Button>,
      <Button key={'save'} type='primary'
        onClick={() => save()}
      >确定</Button>
    ]
  }, [close, save])

  return (
    <Modal
      visible={visible}
      footer={footer}
      width='90%'
      bodyStyle={{ padding: '15px 15px 0px 15px', overflowX: 'auto', minHeight: '60vh' }}
      title='选择标签'
      centered destroyOnClose
      onCancel={() => { close() }}
    >
      <Spin spinning={waiting} >
        {
          showDataQuality ? <DataQuality 
            type={DataQualityFeighTagSelect} 
            data={{
              type,
              items,
              value,
            }}
            onChange={(val) => {
              setSelectedRows(val)
            }} 
          /> : null
        }        
      </Spin>
    </Modal>
  )
}