import React, {
  useState,
  useEffect,
  useImperativeHandle,
  forwardRef,
} from 'react'
import {
  Space,
  Table,
  Modal,
  message,
  Popconfirm,
  Button,
  Select,
  Tabs,
  Input,
} from 'antd'
import { SearchOutlined } from '@ant-design/icons'
import DatasourceData from '../component/DatasourceData'
import DatasourceEdit from '../component/DatasourceEdit'
import {
  getDataSourceList,
  delDataSource,
  getTableNamesList,
  getDataSourceInfo,
  getAilabList,
  getAllShareProject,
  shareAilab,
  getLakeTable,
  ailabTablePreview,
  ailabSchema,
  lakeTablePreview,
  lakeSchema,
} from '../services'

const { Option } = Select
const { TabPane } = Tabs

const DatasourceManage = ({ dataType }, ref) => {
  // 查看数据源弹窗是否可可视
  const [dataModalVisible, setDataModalVisible] = useState(false)
  const [dataPreviewVisible, setDataPreviewVisible] = useState(false)
  const [dsModalVisible, setDsModalVisible] = useState(false)

  // 初始化数据源列表数据 constructor
  const [dataSourceList, setDataSourceList] = useState([])
  // 初始化ailab列表数据
  const [ailabDataList, setAilabDataList] = useState([])

  const [filterAilabDataList, setFilterAilabDataList] = useState([])

  const [lakeDataList, setLakeDataList] = useState([])

  // 表格Loading状态
  const [dataLoading, setDataLoading] = useState(false)

  // 表名
  const [tableNames, setTableNames] = useState([])

  // 选中数据源
  const [datasourceId, setDatasourceId] = useState(null)

  // 查看是否可点击
  const [tableWatcher, setTableWatcher] = useState(false)

  const [currentDsId, setCurrentDsId] = useState(null)
  const [currentDsInfo, setCurrentDsInfo] = useState(null)
  const [isShareData, setIsShareData] = useState(false)
  //选择表格项
  const [selectedRowKeys, setSelectedRowKeys] = useState([])
  // 分享的ailab表
  const [selectedAilabTable, setSelectedAilabTable] = useState([])
  const [projectsList, setProjectsList] = useState([])
  const [selectedProjects, setSelectedProjects] = useState([])
  // 表内容表头
  const [contentCols, setContentCols] = useState([])
  // 表内容表数据
  const [contentData, setContentData] = useState([])
  // 表内容表格Loading状态
  const [contentLoading, setContentLoading] = useState(false)
  // 表结构表头
  const [schemaCols, setScheamCols] = useState([])
  // 表结构表数据
  const [schemaData, setScheamData] = useState([])
  // 表结构表格Loading状态
  const [schemaLoading, setSchemaLoading] = useState(false)

  const onSelectChange = newSelectedRowKeys => {
    setSelectedRowKeys(newSelectedRowKeys)
  }

  // 获取列表数据
  const fetchDataSourceList = async () => {
    setDataLoading(true)
    const { data } = await getDataSourceList()
    if (data.code === 200) {
      const list = data.data.items.map(item => {
        return {
          key: item.id,
          datasource_name: item.datasource_name,
          datasource: item.datasource,
          tag: item.tag,
          comments: item.comments,
          create_time: item.create_time,
          update_time: item.update_time,
        }
      })
      setDataSourceList(list)
    } else {
      message.error(data.msg)
    }
    setDataLoading(false)
  }

  const fetchAilabList = async () => {
    setDataLoading(true)
    const { data } = await getAilabList()
    if (data.code === 200) {
      const list = data.data.map(item => {
        return {
          key: item,
          datatable_name: item,
        }
      })
      setAilabDataList(list)
      setFilterAilabDataList(list)
    } else {
      message.error(data.msg)
    }
    setDataLoading(false)
  }

  const fetchLakeList = async () => {
    setDataLoading(true)
    const { data } = await getLakeTable()
    if (data.code === 200) {
      const list = data.data.map(item => {
        return {
          key: item.id,
          database_name: item.database_name,
          datatable_name: item.table_name,
        }
      })
      setLakeDataList(list)
    } else {
      message.error(data.msg)
    }
    setDataLoading(false)
  }
  // 暴露更新列表方法
  useImperativeHandle(ref, () => {
    return {
      updateSourceList: fetchDataSourceList,
      updateAilabList: fetchAilabList,
      updateLakeList: fetchLakeList,
    }
  })

  // 删除确认
  const DeleteConfirm = async key => {
    const { data } = await delDataSource(key)
    if (data.code === 200) {
      message.success('删除成功')
      fetchDataSourceList()
    } else {
      message.success('删除失败')
    }
  }

  //获取数据源表名
  const fetchTableNames = async key => {
    setTableWatcher(true)
    const { data } = await getTableNamesList(key)
    if (data.code === 200) {
      setDatasourceId(key)
      setTableNames(data.data)
      setDataModalVisible(true)
    } else {
      message.error(data.msg)
    }
    setTableWatcher(false)
  }
  const handleContent = contentData => {
    const colsList = contentData?.header?.map(item => {
      return {
        title: item,
        dataIndex: item,
        key: item,
      }
    })
    const dataList = contentData?.content?.map((item, index) => {
      const row = {}
      row['key'] = index + 1
      item.forEach((val, index) => {
        const title = contentData.header[index]
        row[title] = val
      })
      return row
    })
    setContentCols(colsList)
    setContentData(dataList)
  }

  const handleSchema = schemaData => {
    const colsList = [
      {
        title: '序号',
        dataIndex: 'order',
        key: 'order',
      },
      {
        title: '字段',
        dataIndex: 'field',
        key: 'field',
      },
      {
        title: '属性',
        dataIndex: 'attribute',
        key: 'attribute',
      },
    ]
    const dataList = schemaData?.map((item, index) => {
      const row = {}
      row['key'] = index + 1
      const [order, field, attribute] = item.split(':')
      row['order'] = order
      row['field'] = field
      row['attribute'] = attribute
      return row
    })
    setScheamCols(colsList)
    setScheamData(dataList)
  }

  const fetchAilabDataPreview = async (key, type) => {
    setContentLoading(true)
    const { data } =
      type === 'ailab'
        ? await ailabTablePreview(key)
        : await lakeTablePreview(key)
    if (data.code === 200) {
      handleContent(data.data)
    } else {
      message.error(data.msg)
    }
    setContentLoading(false)
  }

  const fetchAilabSchema = async (key, type) => {
    setSchemaLoading(true)
    const { data } =
      type === 'ailab' ? await ailabSchema(key) : await lakeSchema(key)
    if (data.code === 200) {
      handleSchema(data.data)
    } else {
      message.error(data.msg)
    }
    setSchemaLoading(false)
  }

  const watchAilabData = async table_name => {
    fetchAilabDataPreview(table_name, 'ailab')
    fetchAilabSchema(table_name, 'ailab')
    setDataPreviewVisible(true)
  }

  const watchLakeData = async table_name => {
    fetchAilabDataPreview(table_name, 'lake')
    fetchAilabSchema(table_name, 'lake')
    setDataPreviewVisible(true)
  }

  useEffect(() => {
    if (sessionStorage.getItem('project_id')) {
      switch (dataType) {
        case 'datasource':
          fetchDataSourceList()
          break
        case 'ailab':
          fetchAilabList()
          break
        case 'datalake':
          fetchLakeList()
          break
        default:
          break
      }
    }
  }, [dataType, sessionStorage.getItem('project_id')])

  useEffect(() => {
    if (isShareData) {
      fetchProjects()
    }
  }, [isShareData])

  const fetchProjects = async () => {
    const { data } = await getAllShareProject()
    if (data.code === 200) {
      const list = data.data.map(item => {
        return {
          label: item.name,
          value: item.id,
        }
      })
      setProjectsList(list)
    } else {
      message.error(data.msg)
    }
  }

  // 格式化事件
  const formatTime = time => {
    const date = new Date(Number(time) * 1000)
    const YY = date.getFullYear()
    const MM =
      date.getMonth() + 1 < 10
        ? '0' + (date.getMonth() + 1)
        : date.getMonth() + 1
    const DD = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
    const hh = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
    const mm =
      date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
    const ss =
      date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
    return YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss
  }

  // 编辑数据
  const editData = async id => {
    const { data } = await getDataSourceInfo(id)
    if (data.code === 200) {
      setCurrentDsId(id)
      setCurrentDsInfo(data.data)
      setDsModalVisible(true)
    } else {
      message.error(data.msg)
    }
  }

  // 数据源表格项
  const ds_columns = [
    {
      title: '数据源名称',
      dataIndex: 'datasource_name',
      key: 'datasource_name',
    },
    {
      title: '数据源类型',
      dataIndex: 'datasource',
      key: 'datasource',
    },
    {
      title: '标签',
      dataIndex: 'tag',
      key: 'tag',
      render: text => <span style={{ color: '#1890ff' }}>{text}</span>,
    },
    {
      title: '详情',
      key: 'comments',
      dataIndex: 'comments',
    },
    {
      title: '创建时间',
      key: 'create_time',
      dataIndex: 'create_time',
      render: time => formatTime(time),
    },
    {
      title: '更新时间',
      key: 'update_time',
      dataIndex: 'update_time',
      render: time => formatTime(time),
    },
    {
      title: '操作',
      key: 'operation',
      render: (_, record) => (
        <Space size="middle">
          <Button
            onClick={() => {
              fetchTableNames(record.key)
            }}
            type="link"
            disabled={tableWatcher}>
            查看
          </Button>
          {sessionStorage.getItem('role') === '1' && (
            <Button
              type="link"
              onClick={() => {
                editData(record.key)
              }}>
              编辑
            </Button>
          )}
          {sessionStorage.getItem('role') === '1' && (
            <Popconfirm
              title="确认删除？"
              okText="确认"
              cancelText="取消"
              onConfirm={() => DeleteConfirm(record.key)}>
              <Button type="link">删除</Button>
            </Popconfirm>
          )}
        </Space>
      ),
    },
  ]

  //AIlab表格项
  const ailab_columns = [
    {
      title: '数据表名称',
      dataIndex: 'datatable_name',
      key: 'datatable_name',
      align: 'center',
    },
    {
      title: '操作',
      key: 'operation',
      align: 'center',
      width: '25%',
      render: (_, record) => (
        <Space size="middle">
          {['1', '2', '3'].includes(sessionStorage.getItem('role')) && (
            <Button
              type="link"
              onClick={() => {
                setIsShareData(true)
                setSelectedAilabTable([record.key])
              }}>
              分享
            </Button>
          )}
          <Button
            onClick={() => {
              watchAilabData(record.key)
            }}
            type="link">
            查看
          </Button>
        </Space>
      ),
    },
  ]

  const dl_columns = [
    {
      title: '数据库名称',
      dataIndex: 'database_name',
      key: 'database_name',
      align: 'center',
    },
    {
      title: '数据表名称',
      dataIndex: 'datatable_name',
      key: 'datatable_name',
      align: 'center',
    },
    {
      title: '操作',
      key: 'operation',
      align: 'center',
      width: '25%',
      render: (_, record) => (
        <Space size="middle">
          <Button
            onClick={() => {
              watchLakeData(record.datatable_name)
            }}
            type="link">
            查看
          </Button>
        </Space>
      ),
    },
  ]

  // 查看数据源弹窗取消
  const handledataModalCancel = () => {
    setDataModalVisible(false)
  }

  const handledsModalCancel = () => {
    setDsModalVisible(false)
  }

  const handledataPreviewCancel = () => {
    setDataPreviewVisible(false)
  }

  // 查看数据源弹窗数据
  const dataModal = (
    <Modal
      title="数据表预览"
      visible={dataModalVisible}
      onCancel={handledataModalCancel}
      footer={null}
      destroyOnClose={true}
      width={'80%'}
      bodyStyle={{ paddingTop: 0 }}>
      <DatasourceData data={tableNames} datasourceId={datasourceId} />
    </Modal>
  )

  const dataPreviewModal = (
    <Modal
      title="数据表预览"
      visible={dataPreviewVisible}
      onCancel={handledataPreviewCancel}
      footer={null}
      destroyOnClose={true}
      width={'80%'}
      bodyStyle={{ paddingTop: 0 }}>
      {
        <Tabs size={'small'}>
          <TabPane
            tab="预览表内容"
            key="content"
            style={{ height: '700px', overflow: 'auto' }}>
            <Table
              columns={contentCols}
              dataSource={contentData}
              bordered
              loading={contentLoading}
            />
          </TabPane>
          <TabPane
            tab="预览表结构"
            key="schema"
            style={{ height: '700px', overflow: 'auto' }}>
            <Table
              columns={schemaCols}
              dataSource={schemaData}
              bordered
              loading={schemaLoading}
            />
          </TabPane>
        </Tabs>
      }
    </Modal>
  )

  const dsEditModal = (
    <Modal
      title="编辑数据源"
      visible={dsModalVisible}
      onCancel={handledsModalCancel}
      footer={null}
      destroyOnClose={true}
      width={'60%'}>
      <DatasourceEdit
        ds_id={currentDsId}
        ds_info={currentDsInfo}
        updateDataSource={fetchDataSourceList}
        setDsModalVisible={val => setDsModalVisible(val)}
      />
    </Modal>
  )

  const rowSelection = {
    selectedRowKeys,
    onChange: onSelectChange,
    columnWidth: '100px',
    selections: [
      Table.SELECTION_ALL,
      Table.SELECTION_INVERT,
      Table.SELECTION_NONE,
    ],
  }

  const shareBtn = () => (
    <Button
      type="link"
      disabled={!selectedRowKeys.length}
      onClick={() => {
        setSelectedAilabTable(selectedRowKeys)
        setIsShareData(true)
      }}>
      批量分享
    </Button>
  )

  const searchTable = e => {
    const list = ailabDataList.filter(item =>
      item.datatable_name.includes(e.target.value)
    )
    setFilterAilabDataList(list)
  }

  const searchTool = () => (
    <Input
      type="link"
      style={{ width: '210px' }}
      onChange={searchTable}
      suffix={<SearchOutlined />}
    />
  )

  const shareTable = async () => {
    if (selectedProjects.length) {
      const parmas = {
        table_names: selectedAilabTable,
        project_ids: selectedProjects,
      }
      const { data } = await shareAilab(parmas)
      if (data.code === 200) {
        message.success('分享成功')
        setIsShareData(false)
        setSelectedProjects([])
      } else {
        message.error(data.msg)
      }
    } else {
      message.error('请选择项目')
    }
  }

  const shareMadal = (
    <Modal
      title="分享数据表"
      visible={isShareData}
      onOk={shareTable}
      okText="确认分享"
      onCancel={() => {
        setIsShareData(false)
        setSelectedProjects([])
      }}>
      <Space style={{ padding: '10px 20px 30px' }}>
        <span>选择分享至：</span>
        <Select
          mode="multiple"
          value={selectedProjects}
          onChange={val => setSelectedProjects(val)}
          style={{ width: '300px' }}
          showArrow
          showSearch
          optionFilterProp="label"
          placeholder="请选择项目">
          {projectsList.map(item => {
            return (
              <Option key={item.value} value={item.value} label={item.label}>
                {item.label}
              </Option>
            )
          })}
        </Select>
      </Space>
    </Modal>
  )

  // 最终渲染
  return (
    <div>
      {dataType === 'datasource' && (
        <Table
          columns={ds_columns}
          dataSource={dataSourceList}
          bordered
          loading={dataLoading}
        />
      )}
      {dataType === 'ailab' && (
        <Table
          rowSelection={rowSelection}
          columns={ailab_columns}
          dataSource={filterAilabDataList}
          bordered
          loading={dataLoading}
          footer={
            ['1', '2', '3'].includes(sessionStorage.getItem('role'))
              ? shareBtn
              : null
          }
          title={searchTool}
        />
      )}
      {dataType === 'datalake' && (
        <Table
          columns={dl_columns}
          dataSource={lakeDataList}
          bordered
          loading={dataLoading}
        />
      )}
      {dataModal}
      {dataPreviewModal}
      {dsEditModal}
      {shareMadal}
    </div>
  )
}

export default forwardRef(DatasourceManage)
