import { CloseOutlined, ColumnWidthOutlined, SearchOutlined } from "@ant-design/icons"
import { Button, Checkbox, Input, InputNumber, message, Modal, Popover, Space, Spin, Tooltip } from "antd"
import React, { useCallback, useEffect, useState } from "react"
import './index.less'
import { ReactComponent as DrawStem } from '@/assets/drawStem.svg'
import { SortableContainer, SortableElement, SortableHandle } from "react-sortable-hoc";
import arrayMove from "array-move";

const DragHandle: any = SortableHandle(() => <DrawStem className='draw' />);
const SortableItem: any = SortableElement(({ item, del, setConfig }: any) => {
    const [visible, setVisible] = useState<boolean>(false)
    const [width, setWidth] = useState<number>(item?.width || 0)
    return <li className='liDraw'>
        <div className='lileft'>
            <DragHandle />
            <div>{item?.title}</div>
        </div>
        <Space style={{ float: 'right', marginRight: 10 }}>
            <Popover
                content={
                    <div>
                        <InputNumber min={0} max={500} onChange={(value) => {
                            if (value) {
                                setWidth(value)
                            }
                        }} value={width} size='small' />
                        <Button type='primary' size='small' onClick={() => {
                            setConfig({ ...item, width })
                            setVisible(false)
                        }}>OK</Button>
                    </div>
                }
                trigger="click"
                open={visible}
                placement='left'

                onOpenChange={(visible) => { setVisible(visible) }}
            >
                <Tooltip title='宽度设置'><a><ColumnWidthOutlined /></a></Tooltip>
            </Popover>
        </Space>
        {item?.label !== 'pos_type' && <Tooltip title='删除'><div className="clear" onClick={() => { del() }}><a><CloseOutlined /></a></div></Tooltip>}
    </li>
});
/** 外层 */
const SortableList: any = SortableContainer(({ children }: { children: any }) => (<ul className='selectedList'>{children}</ul>));

interface dataProps {
    title: string,
    label: string,
    dataIndex: string,
    disabled: boolean
}

interface DataProps {
    label: string,
    data: dataProps[],
    fieldSHow?: {
        label: string,
        saveField: string,
        defaultValue: any[],
        data: any[]
    },
    bcColor?: string
}

/**
 * 自定义列
 */
type customProps = {
    visible?: boolean,
    onChange?: (data: any) => void,
    onClose?: () => void,
    config: any[],//配置表
    configName: string,//配置表名称
    columns: any[],//配置菜单
    version: string, // 版本号
    sysFixed?: {
        left: number,
        right: number
    }
}
function CustomListModel(props: customProps) {
    const { visible, onChange, onClose, config, configName, columns, version, sysFixed = { left: 0, right: 1 } } = props
    // dataA 总数据
    // 数据开始
    const [dataA, setDataA] = useState<DataProps[]>(config)//备份原始数据
    const [data, setData] = useState<DataProps[]>(config)//变动的数据
    const [search, setSearch] = useState<string>('')  // 搜索字段
    const [selectData, setSelectData] = useState<dataProps[]>([])//选择的数据
    const [serverData, setServerData] = useState<dataProps[]>([])//备份的数据
    const [fieldData, setFieldData] = useState<any>({})
    const [fixed, setFixed] = useState<{ left: number, right: number }>(localStorage.getItem(`myAdMonitorConfigFixed${version}_` + configName) ? JSON.parse(localStorage.getItem(`myAdMonitorConfigFixed${version}_` + configName) as any) : { left: sysFixed.left, right: sysFixed.right })
    // 数据结束

    // 处理表格里列字段展示
    useEffect(() => {
        let mySelectFieldData = localStorage.getItem(`myAdFieldConfig${version}_` + configName)
        let newSelectFieldData: any = {}
        if (mySelectFieldData) {
            newSelectFieldData = JSON.parse(mySelectFieldData)
        }
        data?.forEach((item) => {
            if (item?.fieldSHow) {
                const { saveField, defaultValue } = item?.fieldSHow
                if (!newSelectFieldData[saveField]) {
                    newSelectFieldData[saveField] = defaultValue
                }
            }
        })
        if (Object.keys(newSelectFieldData).length > 0) {
            setFieldData({ ...newSelectFieldData })
        }
    }, [data])
    // 获取数据
    useEffect(() => {
        getUserList()
    }, [configName])
    // 获取个人配置
    const getUserList = () => {
        let mySelectData = localStorage.getItem(`myAdMonitorConfig${version}_` + configName)
        if (mySelectData) {//获取自定义配置
            let newMySelectData = JSON.parse(mySelectData)
            newMySelectData = newMySelectData.filter((item: any) => item && columns.some(c => c.dataIndex === item.dataIndex))//去除空项,并去除多余不存在的
            setSelectData(newMySelectData)
            setServerData(newMySelectData)
            setListWidth(newMySelectData)
            localStorage.setItem(`myAdMonitorConfig${version}_` + configName, JSON.stringify(newMySelectData))//重新存下本地，避免更新后数据不对
        } else {//使用默认配置
            let newSelectData: any[] = []
            config?.forEach((item) => {
                item?.data?.forEach((d: { default: any }) => {
                    if (d.default) {
                        newSelectData[d.default - 1] = d
                    }
                })
            })
            setSelectData(newSelectData)
            setServerData(newSelectData)
            setListWidth(newSelectData)
        }
    }
    // 首次赋值默认宽
    const setListWidth = useCallback((selectData) => {
        if (selectData?.length === columns?.length && !selectData?.every((item: any) => item.width)) {
            let newSelectData: any[] = []
            newSelectData = selectData?.map((item: { [x: string]: any }, index: string | number) => {
                item['width'] = columns[index as any]['width']
                return item
            })
            setSelectData(newSelectData)
            setServerData(newSelectData)
        }
    }, [columns])

    //首次赋值默认宽
    // useEffect(() => {
    //     console.log('首次赋值默认宽====>',selectData,columns)
    //     if (selectData?.length === columns?.length && !selectData?.every((item: any) => item.width)) {
    //         let newSelectData: any[] = []
    //         newSelectData = selectData?.map((item, index) => {
    //             item['width'] = columns[index]['width']
    //             return item
    //         })
    //         setSelectData(newSelectData)
    //         setServerData(newSelectData)
    //     }
    // }, [selectData,columns])
    // 搜索 过滤
    const searchHandle = useCallback((value: string) => {
        setSearch(value)
        if (search) {
            let newData1: any[] = []
            dataA.forEach((item: DataProps) => {
                let newData = item.data.filter((listItem: dataProps) => {
                    if (listItem?.title?.includes(value)) {
                        return listItem
                    } else {
                        return null
                    }
                })
                if (newData?.length > 0) {
                    newData1.push({ ...item, data: newData })
                }
            })
            setData([...newData1])
        } else {
            setData(dataA)
        }
    }, [data, dataA, search])

    // 选中数据
    const selectHandle = useCallback((checked: boolean, data: dataProps) => {
        if (checked) {
            setSelectData([...selectData, { ...data }])
        } else {
            let newSelectData = selectData.filter((item: dataProps) => {
                if (item.dataIndex === data.dataIndex) {
                    return null
                } else {
                    return item
                }
            })
            setSelectData(newSelectData)
        }
    }, [selectData])

    // 每个大项 全选
    const checkAllHandle = useCallback((checked: boolean, value: string) => {
        let oldData = data.find((item: DataProps) => item.label === value)
        console.log(oldData)
        if (oldData) {
            if (checked) {
                let newSelectData: any[] = selectData?.filter(item => item)
                oldData.data.forEach((item: dataProps) => {
                    if (!item.disabled && selectData.findIndex((selsectItem: dataProps) => selsectItem?.dataIndex === item?.dataIndex) === -1) {
                        newSelectData.push(item)
                    }
                })
                setSelectData([...newSelectData])
            } else {
                let newSelectData = selectData.filter((item: dataProps) => {
                    if (oldData?.data?.some((dataItem: dataProps) => dataItem.dataIndex === 'pos_type' ? false : dataItem?.dataIndex === item.dataIndex)) {
                        return null
                    } else {
                        return item
                    }
                })
                setSelectData(newSelectData)
            }
        }

    }, [selectData, data])

    const onSortEnd = ({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
        setSelectData(arrayMove(selectData, oldIndex, newIndex))
    }
    // 提交
    const onSubmit = useCallback(() => {
        if (selectData.length > 0) {
            localStorage.setItem(`myAdMonitorConfig${version}_` + configName, JSON.stringify(selectData))
            localStorage.setItem(`myAdMonitorConfigFixed${version}_` + configName, JSON.stringify(fixed))
            localStorage.setItem(`myAdFieldConfig${version}_` + configName, JSON.stringify(fieldData))
            message.success('保存成功')
            onChange && onChange({ selectData, fixed })
            onClose && onClose()
        } else {
            message.error('请选择最少一项！！！')
        }
    }, [serverData, selectData, fixed, fieldData])
    // 恢复默认
    const defaultConfig = useCallback(() => {
        localStorage.setItem('REFRESH', new Date().getTime().toString())
        localStorage.removeItem(`myAdMonitorConfig${version}_` + configName)
        localStorage.removeItem(`myAdMonitorConfigFixed${version}_` + configName)
        localStorage.removeItem(`myAdFieldConfig${version}_` + configName)
        setFixed({ ...sysFixed })
        getUserList()
        message.success('恢复默认成功')
        onChange && onChange('')
        onClose && onClose()
    }, [])
    // 设置悬浮
    const changeFixed = useCallback((name: string, value: number) => {
        let v = Number(value)
        if (!isNaN(v)) {
            setFixed({ ...fixed, [name]: value })
        }
    }, [fixed])
    //取消操作
    const cancel = () => {
        setSelectData(serverData)
        onClose && onClose()
    }
    // 设置配置参数
    const setConfig = useCallback((data) => {
        let newServerData = selectData?.map((item) => {
            if (item.dataIndex === data.dataIndex) {
                item = data
            }
            return item
        })
        setSelectData(newServerData)
    }, [selectData])

    // 处理显示字段
    const fieldHandle = (saveField: string, data: any, checked: boolean) => {
        let newFieldData = JSON.parse(JSON.stringify(fieldData))
        if (checked) {
            if (Object.keys(newFieldData).includes(saveField)) {
                newFieldData[saveField] = [...newFieldData[saveField], data]
            } else {
                newFieldData[saveField] = [data]
            }
        } else {
            newFieldData[saveField] = newFieldData[saveField].filter((item: any) => item.key !== data.key && item.type === data.type)
        }
        setFieldData(newFieldData)
    }

    return <Modal
        title={null}
        footer={null}
        open={visible}
        width={1100}
        className='customListModel'
        onCancel={cancel}
        maskClosable={false}
    >
        <div className='content'>
            <div className='left'>
                <div className='leftSearch'>
                    <Input size="small" placeholder="输入关键词，搜索数据指标" onChange={(e) => { searchHandle(e.target.value) }} value={search} prefix={<SearchOutlined style={{ color: '#a3a3a3', fontSize: 18 }} />} allowClear bordered={false} />
                </div>

                <div className="dataList">
                    <Spin spinning={false}>
                        {data?.map((item: DataProps, index: number) => {
                            return <dl key={index}>
                                {item?.fieldSHow && <div style={{ backgroundColor: '#f7f7f7' }}>
                                    <dt style={{ color: '#ff7875' }}>{item.fieldSHow.label}</dt>
                                    <div style={{ padding: '0 20px', boxSizing: 'border-box' }}>
                                        {item?.fieldSHow?.data?.map((item1: any, index) => {
                                            return <dl key={'field' + index}>
                                                <dt>{item1.label}</dt>
                                                {item1.data.map((item2: any, index: number) => <dd key={'item2' + index}><Checkbox className='checkbox' onChange={(e) => fieldHandle((item.fieldSHow as any).saveField, item2, e.target.checked)} checked={fieldData[(item.fieldSHow as any).saveField]?.some((field: any) => field.key === item2.key && field.type === item2.type)} disabled={fieldData[(item.fieldSHow as any).saveField]?.length > 0 ? fieldData[(item.fieldSHow as any).saveField][0].type === item1.label ? false : true : false}>{item2?.label}</Checkbox></dd>)}
                                            </dl>
                                        })}
                                    </div>
                                </div>}
                                <dt>
                                    <Checkbox onChange={(e) => { checkAllHandle(e.target.checked, item.label) }} className='checkbox'>
                                        <span style={item?.bcColor ? { backgroundColor: item?.bcColor } : {}}>{item.label}</span>
                                    </Checkbox>
                                </dt>
                                {item.data?.map((listItem: dataProps, listIndex: number) => {
                                    return <dd key={item.label + listIndex}>
                                        <Checkbox onChange={(e) => { selectHandle(e.target.checked, listItem) }} disabled={listItem.label === 'pos_type' || listItem?.disabled} checked={selectData.some((selectItem: { dataIndex: string }) => selectItem?.dataIndex === listItem?.dataIndex)} className='checkbox'>{listItem?.title}</Checkbox>
                                    </dd>
                                })}
                            </dl>
                        })}
                    </Spin>
                </div>
            </div>
            <div className='right'>
                <div className='rightTitle'>
                    <div className="rightTitleLeft">已选<span>{selectData?.filter(item => item)?.length}</span>项</div>
                    <a onClick={defaultConfig} style={{ marginRight: 30 }}>恢复默认</a>
                </div>
                <div style={{ display: 'flex', flexFlow: 'row nowarp', padding: '0 28px', justifyContent: 'space-between' }}>
                    <div>左侧固定列数：<InputNumber size='small' style={{ width: 50 }} onChange={(value) => { changeFixed('left', value as number) }} value={fixed.left} max={100} min={0} /></div>
                    <div>右侧固定列数：<InputNumber size='small' style={{ width: 50 }} onChange={(value) => { changeFixed('right', value as number) }} value={fixed.right} max={100} min={0} /></div>
                </div>
                <SortableList axis='y' onSortEnd={onSortEnd} useDragHandle>
                    {selectData.map((item: dataProps, index: number) => <SortableItem key={'li' + index} index={index} item={item} del={() => { selectHandle(false, item) }} setConfig={setConfig} />)}
                </SortableList>
                <div className='rightOperate'>
                    <div style={{ margin: '0 auto' }}>
                        <Button onClick={cancel}>取消</Button>
                        <Button type='primary' className='confirm' loading={false} onClick={() => { onSubmit() }} disabled={selectData?.length === 0}>确认</Button>
                    </div>
                </div>
            </div>
        </div>
    </Modal>
}

export default CustomListModel