import { CheckCircleFilled, MinusCircleOutlined } from '@ant-design/icons';
import { Button, Drawer, Input, message, Modal, Tree, TreeDataNode } from 'antd';
import { DataNode } from 'antd/lib/tree';
import { debounce, isArray } from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Icon } from '../components/icons';
import { Renderer, RendererProps } from '../factory';
import { BaseSchema, SchemaApi } from '../Schema';
import { isMobile } from '../utils/helper';
import { getHashCode } from '../utils/utils';
import iconMap from '../icons/font';
export interface QuickLaunchSchema extends BaseSchema {
  // 定义类型
  type: 'quick-launch';
  launchAddApi: SchemaApi;
  launchDataApi: SchemaApi;
  launchDeleteApi: SchemaApi;
  launchListApi: SchemaApi;
  launchTreeApi: SchemaApi;
  title?: string;
}
export interface QuickLaunchProps extends RendererProps, Omit<QuickLaunchSchema, 'type' | 'className'> {

}
type LaunchListItem = {
  appId: string,
  launchIcon?: any,
  firstPage: 0 | 1,
  launchId: string,
  launchMenuType: number,
  launchName: string,
  launchPath: string
}
type FitstMenuItem = {
  firstPage: boolean,
  menuId: string,
  menuName: string,
  menuPage?: string,
  menuType?: number,
  seq: number,
  terminalType: number,
  workbench: number
}
//左侧树结构
type AppTreeItem = {
  firstMenuList: Array<FitstMenuItem>,
  appId: string,
  appName: string,
}
type LaunchSecItem = {
  appId: string,
  groupId: string,
  menuPage: string,
  menuPath: string,
  menuType: string,
  secMenuName: string,
  secMenuId: string,
  seq: number,
  icon?: string
}
//一级页面
type CombinePage = {
  appId: string,
  menuId: string,
  menuName: string,
  menuPage: string,
  menuPath: string,
  menuType: number,
  workbench: number,
  icon?:string
}
//一级菜单
type LaunchGroupItem = {
  secondList: Array<LaunchSecItem>,
  groupName: string,
}
//一级菜单完整结构，有且仅有一项，后端因为复用了初始化app时的接口导致
type MenuTree = {
  menuId: string,
  menuName: string,
  seconds: LaunchGroupItem[],
  workbench: number
}
const QuickLaunch = (props: QuickLaunchProps) => {
  const { env, launchDataApi, launchAddApi, launchListApi, launchTreeApi, launchDeleteApi,
    classnames: cx, title = '快速发起' } = props;
  const [launchList, setLaunchList] = useState<LaunchListItem[]>([]);
  const [visible, setVisible] = useState(false);
  const [appList, setAppList] = useState<DataNode[]>([]);
  const [launchGroup, setLaunchGroup] = useState<Array<MenuTree | CombinePage>>([]);
  const [searchRes, setSearchRes] = useState<Array<LaunchSecItem | CombinePage>>();
  const [tempNum, setTempNum] = useState(0);
  const [selectList, setSelectList] = useState<Array<LaunchSecItem & CombinePage>>([]);
  const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
  const [editing, setEditing] = useState(false);
  const bodyRef = useRef<HTMLDivElement>(null);
  const pageBodyRef = useRef<HTMLDivElement>(null);
  const appId = useRef('');
  const defaultValue = useRef('')
  useEffect(() => {
    //计算缺少的占位元素数量
    if(bodyRef.current) {
      const colNum = Math.floor((bodyRef.current.clientWidth - 32 ) / (70 + 8));//列数
      const restNum = launchList.length % colNum;//最后一行数量
      const num = colNum - restNum - 1;
      num > 0 && setTempNum(num);
    }
  }, [launchList])
  const initLaunchData = async () => {
    const { data, ok, msg } = await env.fetcher(launchDataApi)
    if(ok) {
      setLaunchList(isArray(data) ? (data as LaunchListItem[]).map(item => {
        const hashNum = getHashCode(item.launchName + item.launchPath) % 54 || 0;
        const targetIcon = iconMap[hashNum];
        return { ...item, launchIcon: item.launchIcon || targetIcon.icon }
      }) : [])
    } else {
      message.error(msg)
    }
  }
  const initLaunchTreeData = async () => {
    const { data, ok, msg } = await env.fetcher(launchTreeApi)
    if(ok) {
      if(isArray(data)) {
        const rootNode = data as AppTreeItem[];
        appId.current = rootNode[0].appId;
        const treeList = rootNode.map((item, index) => {
          const children = item.firstMenuList.map((info, childIndex) => ({
            title: info.menuName,
            key: `${index}-${childIndex}`,
            icon: '',
            appId: item.appId,
            menuId: info.menuId
          }))
          return { title: item.appName, appId: item.appId, key: String(index), icon: '', children }
        })
        setAppList(treeList)
        initLaunchGroup()
      } else { setAppList([data[0]]) }
    } else {
      message.error(msg)
    }
  }
  const initLaunchGroup = async () => {
    const currentSecondMenu = sessionStorage.getItem('currentSecondMenu');
    let menuId = '', secMenuId = '';
    if(currentSecondMenu) {
      const obj = JSON.parse(currentSecondMenu)
      menuId = obj.menuId || '';
      secMenuId = obj.secMenuId || '';
    }
    const { data, ok, msg } = await env.fetcher(launchListApi, {menuId, secMenuId})
    if(ok) {
      if(isArray(data) && data.length > 0) {
        //有seconds是一级菜单，否则是一级页面，添加时后端需要前端把appId补上
        const list = data.map(item => {
          if(item?.seconds) {
            return {
              ...item,
              seconds: (item.seconds as LaunchGroupItem[]).map(info => ({
                ...info,
                secondList: info.secondList.map(node => ({
                  ...node, appId: appId.current
                }))
              }))
            }
          } else {
            return {...item, appId: appId.current}
          }
        })
        setLaunchGroup(list)
      } else {
        setLaunchGroup([])
      }
    } else {
      message.error(msg)
    }
  }
  const onSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    debounce(handleSearch, 500)(e.target.value)
  }
  //搜索
  const handleSearch = (value: string) => {
    defaultValue.current = value;
    if(!value) {
      setSearchRes(undefined)
      return;
    }
    const list: Array<LaunchSecItem | CombinePage> = [];
    launchGroup.forEach((item: MenuTree & CombinePage) => {
      if(item.seconds) {
        item.seconds.forEach(node => {
          node.secondList?.forEach(info => {
            info.secMenuName.includes(value) && list.push(info)
          })
        })
      } else {
        item.menuName.includes(value) && list.push(item)
      }
    })
    setSearchRes(list)
  }
  const onSelect = (selectedKeys: string[], info: any) => {
    setSelectedKeys(selectedKeys)
    const dom = (pageBodyRef.current as HTMLDivElement)?.querySelector('#' + info.node.menuId)
    if(dom) {
      dom.scrollIntoView({behavior: 'smooth', block: 'start'})
    }
  }
  const handleClick = async (node: LaunchListItem) => {
    if(editing) {
      const { ok, msg } = await env.fetcher(launchDeleteApi, { launchId: node.launchId, firstPage: node.firstPage })
      if(ok) {
        setLaunchList(launchList.filter(item => item.launchId !== node.launchId && item.launchPath !== node.launchPath))
        setLaunchGroup([])
      } else {
        message.error(msg)
      }
    } else {
      if(node.launchPath) {
        const id = 'Matrix' + getHashCode(node.launchPath).toString();
        env.onPageLink?.(id, id, node.launchName, node.launchPath, undefined);
      }
    }
  }
  const handleSelect = (node: LaunchSecItem & CombinePage) => {
    //判断是选中还是取消选中
    const isSelected = selectList.find(item => {
      if(node.secMenuId) return item.secMenuId === node.secMenuId && item.menuPath === node.menuPath;
      if(node.menuId) return item.menuId === node.menuId && item.menuPath === node.menuPath;
      return false;
    })
    if(isSelected) {
      setSelectList(selectList.filter(item => {
        if(node.secMenuId) return item.secMenuId !== node.secMenuId && item.menuPath !== node.menuPath;
        if(node.menuId) return item.menuId !== node.menuId && item.menuPath !== node.menuPath;
        return true;
      }))
    } else {
      setSelectList([...selectList, node])
    }
  }
  const handleOk = async () => {
    if(selectList.length) {
      const { msg, ok } = await env.fetcher(launchAddApi, { launchParam: selectList.map(item => ({
        ...item, launchId: item.secMenuId || item.menuId
      }))})
      if(ok) {
        setSelectList([])
        setVisible(false)
        setLaunchGroup([])
        initLaunchData()
        message.info('添加成功')
      } else {
        message.error(msg)
      }
    } else {
      message.info('请勾选要添加的菜单')
    }
  }
  useEffect(() => {
    initLaunchData()
    initLaunchTreeData()
  }, [])
  useEffect(() => {
    if(visible && !launchGroup.length) {
      initLaunchGroup()
    }
  }, [visible])
  const selectedFields = useMemo(() => {
    return `已选（${selectList.length}）：${selectList.map(item => item.secMenuName || item.menuName).join('、')}`;
  }, [selectList])
  const renderFooter = () => {
    return <div className='quick-launch-modal-footer'>
      <div className='quick-launch-modal-footer-left'>{selectedFields}</div>
      <div className='quick-launch-modal-footer-right'>
        <Button onClick={() => setVisible(false)}>取消</Button>
        <Button type='primary' onClick={handleOk}>确定</Button>
      </div>
    </div>
  }
  const renderFlattenItem = (item: LaunchSecItem & CombinePage, index: number) => {
    const k = `${index}-${item.secMenuId || item.menuId}`
    const hashNum = getHashCode(k) % 54 || 0;
    const targetIcon = iconMap[hashNum]; 
    return <div key={k} id={searchRes?.length ? '' : item.menuId}
      className="quick-launch-modal-body-group-item"
      onClick={() => handleSelect(item as any)}
    >
      <div className='quick-launch-modal-body-group-item-icon-box'>
        <div className='quick-launch-modal-body-group-item-icon'><i className={item.icon || targetIcon.icon}></i></div>
      </div>
      <div className='quick-launch-modal-body-group-item-name'>{item.secMenuName || item.menuName}</div>
      {selectList.find(node => node.secMenuId ? node.secMenuId === item.secMenuId && node.menuPath === item.menuPath
        : node.menuId === item.menuId && node.menuPath === item.menuPath
      ) ?
        <CheckCircleFilled className='quick-launch-modal-body-group-item-sel' style={{fontSize: '18px'}} />
        : <div className='quick-launch-modal-body-group-item-unsel' />}
    </div>
  }
  const renderItem = () => {
    if(searchRes) {
      return <div className='quick-launch-modal-body-search-list'>
        {searchRes.map((item: LaunchSecItem & CombinePage, index) => renderFlattenItem(item, index))}
      </div>
    }
    return launchGroup.map((item: MenuTree & CombinePage, index) => {
      if(item.seconds) {
        if(item.seconds.length) {
          return <div id={item.menuId} key={item.menuId + index}>
            {item.seconds.map((node, nodeIndex) => <div key={node.groupName ?? '' + index + '-' + nodeIndex} className="quick-launch-modal-body-group">
              <div className="quick-launch-modal-body-group-title">{node.groupName}</div>
              <div className="quick-launch-modal-body-group-body">
                <div className="quick-launch-modal-body-group-body-container">
                  {
                    node.secondList?.map((info, secIndex) => {
                      const hashNum = getHashCode(info.secMenuName + info.menuPath) % 54 || 0;
                      const targetIcon = iconMap[hashNum];
                      return <div
                        onClick={() => handleSelect(info as any)}
                        key={index + '-' + nodeIndex + '-' + secIndex + info.secMenuName + info.secMenuId}
                        className="quick-launch-modal-body-group-item"
                      >
                        <div className='quick-launch-modal-body-group-item-icon-box'>
                          <div className='quick-launch-modal-body-group-item-icon'>
                            <i className={info.icon || targetIcon.icon}></i>
                          </div>
                        </div>
                        <div className='quick-launch-modal-body-group-item-name'>{info.secMenuName}</div>
                        {selectList.find(node => node.secMenuId === info.secMenuId && node.menuPath === info.menuPath) ? 
                          <CheckCircleFilled className='quick-launch-modal-body-group-item-sel' style={{fontSize: '18px'}} />
                          : <div className='quick-launch-modal-body-group-item-unsel' />}
                      </div>}
                    )
                  }
                </div>
              </div>
            </div>
            )}
          </div>
        }
        return null;
      }
      return renderFlattenItem(item as any, index)
    })
  }
  return (
    <div className={cx('Quick-launch')}>
      <div className={cx('Quick-launch-header')}>
        <div className={cx('Quick-launch-header-title')}>{title}</div>
        <div><Button size='small' type='link' onClick={() => setEditing(!editing)}>{editing ? '保存' : '编辑'}</Button></div>
      </div>
      <div className={cx('Quick-launch-body')} ref={bodyRef}>
        <div className={cx('Quick-launch-body-wrapper')}>
          {
            launchList.map(item => (
              <div className={cx('Quick-launch-body-wrapper-item')} key={item.launchId} onClick={() => handleClick(item)}>
                <div className={cx('Quick-launch-body-wrapper-item-icon')}>
                  <div className={cx('Quick-launch-body-wrapper-item-icon-box')}>
                    <i className={item.launchIcon} ></i>
                  </div>
                </div>
                <div className={cx('Quick-launch-body-wrapper-item-name')}>{item.launchName}</div>
                {editing && <MinusCircleOutlined className={cx('Quick-launch-body-wrapper-item-close')} />}
              </div>
            ))
          }
          <div className={cx('Quick-launch-body-wrapper-item', 'add-item')} key='plus' onClick={() => setVisible(true)}>
            <div className={cx('Quick-launch-body-wrapper-item-icon')}><Icon icon="plus" className="icon" style={{ fontSize: 32 }} /></div>
            <div></div>
          </div>
          {/* 占位元素 */}
          {
            tempNum > 0 ? Array.from({ length: tempNum }, (_, i) => (
              <div className={cx('Quick-launch-body-wrapper-item placeholder-item')} style={{ height: 0 }} key={i} />
            )) : null
          }
        </div>
      </div>
      {visible && !isMobile() && <Modal open={visible} title='快速发起管理' width={'70vw'} centered className='quick-launch-modal'
        getContainer={() => document.getElementById('amis-modal-container') || document.body}
        footer={renderFooter()} onCancel={() => setVisible(false)}>
        <div className='quick-launch-modal-body'>
          <div className='quick-launch-modal-body-left'>
            <div className='quick-launch-modal-body-left-title'>系统菜单</div>
            <div className='quick-launch-modal-body-left-search'>
              <Input placeholder='搜索名称' onChange={onSearch} defaultValue={defaultValue.current} />
            </div>
            <div className='quick-launch-modal-body-left-tree'>
              <Tree
                showIcon
                defaultExpandedKeys={['0']}
                selectedKeys={selectedKeys}
                onSelect={onSelect}
                treeData={appList}
              />
            </div>
          </div>
          <div className='quick-launch-modal-body-right' ref={pageBodyRef}>
            {renderItem()}
          </div>
        </div>
      </Modal>}
      {
        visible && isMobile() && <Drawer open={visible} width={'100%'} onClose={() => setVisible(false)}
          getContainer={() => document.getElementById('amis-modal-container') || document.body}
          className="quick-launch-modal">
          <div className='quick-launch-drawer'>
            <div className='quick-launch-drawer-header'>
              <div className='quick-launch-drawer-header-close' onClick={() => setVisible(false)}><Icon icon="title-left" style={{ width: '16px', height: '16px' }} /></div>
              <div className='quick-launch-drawer-header-search'><Input placeholder='搜索名称' onChange={onSearch} defaultValue={defaultValue.current} /></div>
              <div><Button type='link' onClick={handleOk}>应用</Button></div>
            </div>
            <div className='quick-launch-drawer-body'>
              <div className='quick-launch-drawer-body-left'>
                <div className='quick-launch-drawer-body-left-list'>
                  {appList[0]?.children?.map(item => <div key={item.key}
                    className={`quick-launch-drawer-body-left-list-item ${selectedKeys.includes(item.key as string) ? 'active-item' : ''}`}
                    onClick={() => {
                      setSelectedKeys([item.key as string])
                      const dom = (pageBodyRef.current as HTMLDivElement)?.querySelector('#' + (item as any).menuId)
                      if(dom) {
                        dom.scrollIntoView({behavior: 'smooth', block: 'start'})
                      }
                    }}
                  >
                    {item.title}
                  </div>)}
                </div>
              </div>
              <div className='quick-launch-drawer-body-right'>
                <div className='quick-launch-drawer-body-right-fields'>
                  <div className='quick-launch-drawer-body-right-fields-content'>
                    {selectedFields}
                  </div>
                </div>
                <div className='quick-launch-drawer-body-right-content' ref={pageBodyRef}>
                  {renderItem()}
                </div>
              </div>
            </div>
          </div>
        </Drawer>
      }
    </div>
  )
}
// 将组件注册到 amis 渲染器中
export default Renderer({
  type: 'quick-launch'
})(QuickLaunch);