import CustomListModel from '@/components/CustomList'
import Tables from '@/components/Tables'
import { FullscreenExitOutlined, FullscreenOutlined, QuestionCircleOutlined, RedoOutlined, SearchOutlined, SettingOutlined } from '@ant-design/icons'
import { useDebounceFn, useFullscreen, useThrottleFn } from 'ahooks'
import { Button, Card, Col, Row, Space, Tooltip, } from 'antd'
import React, { useEffect, useRef, useState, useCallback } from 'react'
import style from './index.less'
import moment from 'moment'
import lodash from 'lodash';

interface Prosp {
    isZj?: boolean,//是否查总计
    tableTotal?: { [key: string]: string },//是个开启总计
    scroll?: { x?: number, y?: number },//开启行滑动并设置容器最大宽度
    title?: string,//tabel的标题
    tips?: JSX.Element, // 提示
    tooltip?: JSX.Element,//是否在标题后加问号展示说明
    dataSource: any[],//table的数据
    expandedRowRender?: (data: any) => JSX.Element,
    className?: string,//自定义class
    isdownload?: boolean,
    leftChild?: JSX.Element,
    czChild?: JSX.Element,
    config?: any,
    configName?: any,
    page?: number,
    pageSize?: number,
    size?: 'small' | 'middle' | 'large',
    total?: number,
    onChange?: (props: {
        pagination?: { current?: number, pageSize?: number, gzh?: string },
        filters?: any,
        sortData?: {
            column: { dataIndex: string },
            order?: "ascend" | "descend"
        }
    }) => void,
    ajax?: any,//接口刷新
    fixed?: {
        left: number,
        right: number
    },
    totalData?: any[]
    summary?: ((data: readonly any[]) => React.ReactNode)
    rowClassName?: string | ((record: any, index: any) => string)
    sortData?: {
        field?: string,
        order?: "descend" | "ascend"
    }
    estimatedRowHeight?: number | (() => number)
    headerHeight?: number
    rowSelection?: any

}

export const version = '1.0.0'

function TableData(props: Prosp) {
    /*************************/
    const { isZj, totalData, czChild, scroll, title, tips, dataSource, expandedRowRender, rowSelection, sortData, className, rowClassName, leftChild, page = undefined, pageSize = undefined, size = 'small', total = 0, onChange, config, configName, ajax, fixed = { left: 0, right: 1 }, summary, estimatedRowHeight } = props
    const [visible, setVisible] = useState<boolean>(false)
    const [isFullscreen, setIsFullscreen] = useState<boolean>(true)
    const [oldSelectData, setoldSelectData] = useState<any[]>([])
    const [oldFixed, setoldFixed] = useState<any>({ left: '0', right: '0' })
    const [newColumns, setNewColumns] = useState<any[]>([])
    const [originalColumns, setOriginalColumns] = useState<any[]>([])
    const [timer, setTimer] = useState<string>(moment().format('HH:mm:ss'))
    const [selectData, setSelectData] = useState<{ selectData: any[], fixed: { left: number, right: number } }>({ selectData: [], fixed: { left: fixed.left, right: fixed.right } })
    const ref = useRef(null)
    const [isFull, { toggleFull }] = useFullscreen(ref);
    const oldName = useRef(null)
    /*************************/

    useEffect(() => {
        if (originalColumns.length > 0) {
            if (sortData?.field && sortData.order) {
                setNewColumns(originalColumns.map((item: any) => {
                    if (item.dataIndex === sortData?.field) {
                        item.sortOrder = sortData.order
                    } else if (item?.sortOrder) {
                        delete item.sortOrder
                    }
                    return item
                }))
            } else {
                setNewColumns(originalColumns.map((item: any) => {
                    const { sortOrder, ...ite } = item
                    return ite
                }))
            }
        }
    }, [originalColumns, sortData?.field, sortData?.order])


    const { run: runSet } = useThrottleFn((newArr, newConfig, fixedData) => {
        setoldSelectData(selectData.selectData)
        setoldFixed(selectData.fixed)
        if (newArr.length > 0) {
            let c: any[] = []
            newArr.forEach((newItem: any, index: number) => {
                let oldItem = newConfig.find((c: { dataIndex: any }) => c.dataIndex === newItem.dataIndex)
                if (oldItem) {
                    // if (newItem?.width !== oldItem?.width) {
                    oldItem.width = newItem?.width
                    // }
                    if (index < Number(fixedData.left)) {//设置左悬浮
                        oldItem['fixed'] = 'left'
                    } else if (index > (newArr?.length - Number(fixedData.right) - 1)) {//设置右悬浮
                        oldItem['fixed'] = 'right'
                        if (oldItem?.children?.length > 0) {
                            oldItem['children'] = oldItem?.children.map((item: { [x: string]: string }) => {
                                item['fixed'] = 'right'
                                return item
                            })
                        }
                    } else {
                        oldItem['fixed'] = false
                        if (oldItem?.children?.length > 0) {
                            oldItem['children'] = oldItem?.children.map((item: { [x: string]: any }) => {
                                item['fixed'] = false
                                return item
                            })
                        }
                    }
                    let { label, default: a, tips, title, ...ite } = oldItem
                    if (tips) {
                        ite.title = <Space size={2}>
                            {title}
                            <Tooltip title={tips} placement='bottom'>
                                <QuestionCircleOutlined />
                            </Tooltip>
                        </Space>
                    } else {
                        ite.title = title
                    }
                    c.push(ite)
                }
            })
            setOriginalColumns(c)
        }
    }, { wait: 200 });
    /**重组选中的字段 */
    useEffect(() => {
        let oldConfigName = oldName.current || ''
        let oldSelectDataString = JSON.stringify(oldSelectData)
        if (configName !== oldConfigName && oldSelectData.length > 0) {
            oldSelectDataString = ''
        }
        if (configName) {
            const defSelectData = localStorage.getItem(`myAdMonitorConfig${version}_` + configName)
            const defFixed = localStorage.getItem(`myAdMonitorConfigFixed${version}_` + configName)
            let newArr: any = [], fixedData: { left: number, right: number } = selectData.fixed
            const newConfig = config?.map((item: { data: any }) => item.data)?.flat()
            if (defSelectData) {
                newArr = JSON.parse(defSelectData)
            }
            if (defSelectData && (selectData?.selectData?.length === 0 || configName !== oldConfigName)) {//首次查找个人配置是否存在，并且selectData为空，存在用个人配置设置selectData
                console.log('首次使用个人配置赋值')
                let newDefSelectData = JSON.parse(defSelectData)
                newDefSelectData = newDefSelectData.filter((item: any) => !!item && newConfig.some((c: { dataIndex: any }) => c.dataIndex === item.dataIndex))//去除空项
                setSelectData(() => ({ selectData: newDefSelectData, fixed: defFixed ? JSON.parse(defFixed) : { left: 0, right: 0 } }))
                fixedData = defFixed ? JSON.parse(defFixed) : { left: 0, right: 0 }
                newArr = newDefSelectData
            }
            if (!defSelectData && (selectData?.selectData?.length === 0 || configName !== oldConfigName)) {//首次查找个人配置是否存在，并且selectData为空，不存在默认配置设置selectData
                let newSelectData: any[] = []
                config?.forEach((item: { data: { default: any }[] }) => {
                    item?.data?.forEach((d: { default: any }) => {
                        if (d.default) {
                            newSelectData[d.default - 1] = d
                        }
                    })
                })
                console.log('首次使用默认配置赋值')
                setSelectData(() => ({ ...selectData, selectData: newSelectData }))
                newArr = newSelectData
            }
            if ((JSON.stringify(oldSelectDataString) !== JSON.stringify(selectData?.selectData)) || (JSON.stringify(selectData.fixed) !== JSON.stringify(oldFixed))) {
                runSet(newArr, newConfig, fixedData)
            }
        }
        if (configName !== oldConfigName) {
            oldName.current = configName
        }
    }, [selectData, oldSelectData, dataSource, oldFixed, configName, config, timer])

    const { run: runResize } = useDebounceFn((columns, type: string) => {
        if (configName) {
            let newSelectData = selectData?.selectData?.map((item, index) => {
                if (type === 'vir') {
                    if (item.dataIndex === columns.key) {
                        item['width'] = Math.ceil(columns['width'])
                    }
                } else {
                    item['width'] = columns[index]['width']
                }
                return item
            })
            localStorage.setItem(`myAdMonitorConfig${version}_` + configName, JSON.stringify(newSelectData))
        }
    }, { wait: 100 });

    //拖动宽度设置设置保存
    const handelResize = useCallback((columns: any, type: string) => {
        runResize(columns, type)
    }, [configName, selectData])

    let colData = czChild ? { span: 24 } : { flex: '1 1 150px' }

    const header = <Col span={24}>
        <Row gutter={[0, 10]} align='bottom'>
            <Col {...colData}>
                {isFullscreen && leftChild}
            </Col>
            {czChild && <Col flex='1 1 150px'>{czChild}</Col>}
            <Col flex='0 1 150px'>
                {/*紧凑*/}
                <Space style={{ float: 'right', marginBottom: 4 }}>
                    <Button size='small' type='text' style={{ color: '#F56C6C' }} onClick={() => { setIsFullscreen(!isFullscreen) }}>
                        <Tooltip title={isFullscreen ? '隐藏搜索' : '显示搜索'}><SearchOutlined /></Tooltip>
                    </Button>
                    {ajax && <Button
                        size='small'
                        type='text'
                        style={{ color: '#67C23A' }}
                        onClick={() => {
                            ajax.refresh()
                        }}>
                        {/* <span style={{ fontSize: 10, color: '#999' }}>刷新时间:{ajax?.data?.reqTime}</span> */}
                        <Tooltip title='刷新'><RedoOutlined /></Tooltip>
                    </Button>}
                    <Button
                        size='small'
                        type='text'
                        style={{ color: '#E6A23C' }}
                        onClick={() => {
                            setVisible(true)
                        }}>
                        <Tooltip title='设置'><SettingOutlined /></Tooltip>
                    </Button>
                    <Button
                        type='text'
                        size='small'
                        style={{ color: '#409EFF' }}
                        onClick={toggleFull}>
                        {<Tooltip title={!isFull ? '全屏' : '退出全屏'}>{!isFull ? <FullscreenOutlined /> : <FullscreenExitOutlined />}</Tooltip>}
                    </Button>
                    {visible && <CustomListModel
                        sysFixed={fixed}
                        version={version}
                        config={config}
                        configName={configName}
                        visible={visible}
                        onClose={() => { setVisible(false) }}
                        onChange={(arr: any) => {
                            setTimer(moment().format('HH:mm:ss'));
                            if (arr) {
                                setSelectData({ selectData: [], fixed: { left: fixed.left, right: fixed.right } })
                            } else {
                                setSelectData({ selectData: [], fixed: { left: fixed.left, right: fixed.right } })
                            }
                        }}
                        columns={newColumns}
                    />}
                </Space>
            </Col>
        </Row>
    </Col>
    const content = <Row gutter={[0, 20]} ref={ref} style={isFull ? { background: '#fff' } : {}}>
        {/**table */}
        <Col span={24}>
            <Card
                style={{ borderRadius: 8 }}
                // title={<div style={{ textAlign: 'center', fontWeight: 'bold' }}>{title}</div>}
                headStyle={{ textAlign: 'left' }}
                bodyStyle={{ padding: '5px 10px' }}
            >
                <div style={{ textAlign: 'center', fontWeight: 'bold', padding: '4px 6px 6px', fontSize: 16, marginBottom: 4, position: 'relative' }}>
                    <Space>
                        <span>{title}</span>
                        {tips && <Tooltip title={tips}>
                            <span><QuestionCircleOutlined /></span>
                        </Tooltip>}
                    </Space>
                </div>
                <Row gutter={[0, 16]}>
                    {header}
                    <Tab {...{ size, newColumns, handelResize, className, isZj, totalData, rowSelection, rowClassName, scroll, isFull, page, pageSize, dataSource, onChange, expandedRowRender, total, ajax, summary }} />
                </Row>
            </Card>
        </Col>
    </Row>

    return <>
        {content}
    </>
}

/**表格 */
const Tab = React.memo((props: any) => {
    const { size, newColumns, className, handelResize, scroll, isFull, page, isZj, rowSelection, rowClassName, pageSize, totalData, dataSource, onChange, expandedRowRender, total, ajax, summary } = props
    let ran = Math.ceil(Math.random() * 100)

    useEffect(() => {
        const contentBodyScroll = (e: any) => {
            let el = document.querySelector(`.header_table_body_${ran} .ant-table-body`);
            if (el) {
                el.scrollLeft = e.target.scrollLeft
            }
        }
        const headerBodyScroll = (e: any) => {
            let el = document.querySelector(`.content_table_body_${ran} .ant-table-body`);
            if (el) {
                el.scrollLeft = e.target.scrollLeft
            }
        }
        if (isZj) {
            document.querySelector(`.content_table_body_${ran} .ant-table-body`)?.addEventListener('scroll', contentBodyScroll);
            document.querySelector(`.header_table_body_${ran} .ant-table-body`)?.addEventListener('scroll', headerBodyScroll);
        }
        () => {
            if (isZj) {
                document.querySelector(`.content_table_body_${ran} .ant-table-body`)?.removeEventListener('scroll', contentBodyScroll);
                document.querySelector(`.header_table_body_${ran} .ant-table-body`)?.removeEventListener('scroll', headerBodyScroll);
            }
        }
    }, [isZj, ran])
    return <Col span={24}>
        <div className={`${style[size]} ${className ? style[className] : ''} `}>
            {
                isZj && <Tables
                    bordered
                    columns={newColumns}
                    dataSource={totalData?.length > 0 ? [...totalData] : [{ id: 1 }]}
                    scroll={scroll ? isFull ? { ...scroll, y: document.body.clientHeight - 300 } : scroll : {}}
                    size={size}
                    pagination={false}
                    hideOnSinglePage
                    current={page}
                    pageSize={pageSize}
                    loading={ajax?.loading}
                    rowSelection={rowSelection}
                    className={`all_table header_table_body header_table_body_${ran} ${className ? className : ''}`}
                    sortDirections={['ascend', 'descend', null]}
                    handelResize={((columns: any) => handelResize(columns, 'antd'))}
                    onChange={(pagination: any, filters: any, sorter: any) => onChange && onChange({ pagination, filters, sortData: sorter })}
                />
            }
            <Tables
                showHeader={!isZj}
                className={`all_table content_table_body content_table_body_${ran} ${className ? className : ''}`}
                bordered
                sortDirections={['ascend', 'descend', null]}
                current={page}
                rowSelection={rowSelection}
                pageSize={pageSize}
                columns={newColumns}
                dataSource={dataSource}
                scroll={scroll ? isFull ? { ...scroll, y: document.body.clientHeight - 300 } : scroll : {}}
                onChange={(pagination: any, filters: any, sorter: any) => onChange && onChange({ pagination, filters, sortData: sorter })}
                rowClassName={rowClassName}
                expandedRowRender={expandedRowRender ? expandedRowRender : undefined}
                size={size}
                total={total}
                loading={ajax?.loading}
                defaultPageSize={20}
                handelResize={((columns: any) => handelResize(columns, 'antd'))}
                summary={summary}
            />

        </div>
    </Col >
})

export default React.memo(TableData, (prevProps, nextProps) => {
    return lodash.isEqual(nextProps, prevProps); // 假设 deepEqual 是一个深层比较函数
})