// 核心库
import React, { Component } from 'react'
import { connect } from 'dva'
// 组件库
import { Button, Upload, Icon, message } from 'antd'
import { Search, ExportToExcel, LayoutCard } from '@woowalker/feui'
import EditableTable from './EditableTable'
// 工具库
import { initFilter, extendRule, permissionUtils, addRuleAndGroups, renderExportCell } from '../../utils/common'
import { isEqual } from 'lodash'
import config from '../../config'
// 样式
import styles from './index.css'
import storage from '../../utils/storage';
class EditableTablePage extends Component {
  constructor (props) {
    super(props)
    // 所配置的表单信息
    this.formData = {}
    // 所配置的 tables 的配置信息
    this.configList = []
    // 所配置的 tables 的表格数据
    this.state = {
      dataList: [
        // { tableCode: '', tableData: {} } // tableCode: 表单code，data: 表单数据
      ],
      searchSize: undefined
    }
    // 编辑保存的表格数据
    this.editData = {
      // [tableCode]: []
    }
  }

  componentDidMount () {
    const { onRef } = this.props
    onRef instanceof Function && onRef(this)
  }

  /**
   * Search 组件主动进行搜索
   * @param {*} searchParam 
   */
  loadData = (searchParam) => {
    if (this.configList.length) {
      this.getTablesData(this.configList, searchParam)
    } else {
      this.getTablesByFormCode(this.props.formCode).then(tableList => {
        this.getTablesConfig(tableList).then(configList => {
          this.getTablesData(configList, searchParam)
        })
      })
    }
  }

  /**
   * 获取 formCode 配置信息，以及 formCode 对应配置的多个 table
   * @param {*} formCode
   */
  getTablesByFormCode = (formCode) => {
    const { login, dispatch } = this.props
    return dispatch({
      type: 'listPage/getTablePageTables',
      payload: initFilter(login.OrgId, formCode, '', 0, 1)
    }).then(ret => {
      ret = ret || {}
      const { Nav_Tables = [], Nav_Form = {} } = ret
      this.formData = Nav_Form
      return Nav_Tables
    })
  }

  /**
   * 获取所有 table 对应的配置信息
   * 只取 pf001 -> 列表配置 -> 操作：编辑、按钮 里面的配置信息，
   * 编辑：获取 api 等配置信息
   * 按钮：获取表格右上角配置的按钮信息，比如导出、保存
   * 其他的，比如字段、过滤信息都不取
   * @param {*} tableList
   */
  getTablesConfig = (tableList) => {
    const { login, dispatch } = this.props
    const promiseFunc = tableList.map(table => {
      const { ID: tableId } = table
      // 获取 table 配置信息
      const tableConfParams = initFilter(login.OrgId, '', 'NUM', 0, 1, login.user.ID)
      extendRule(tableConfParams, 'ID', 1, tableId)

      return dispatch({
        type: 'listPage/getTablePageConfigInfo',
        payload: tableConfParams
      }).then(ret => {
        ret = ret || { PageTable: {} }
        const { ID, CODE, PAGE_FORM_ID, API_URL, FILTER_ORG_TYPE, AUTH_ORG_CODES, IGNORE_ORG_RULE, TITLE } = ret.PageTable
        const { Btns = [] } = ret
        // 表格配置信息
        const tableConfig = {
          id: ID,
          tableCode: CODE,
          formId: PAGE_FORM_ID,
          api: API_URL,
          orgType: FILTER_ORG_TYPE,
          authOrgCodes: AUTH_ORG_CODES || ret.Nav_Form.AUTH_ORG_CODES,
          ignoreOrgRule: IGNORE_ORG_RULE,
          exportTitle: TITLE,
          btns: []
        }

        // 按钮配置信息
        Btns.forEach(item => {
          if (item.ENABLE_STATUS === 1 || (item.IS_RULE && !permissionUtils(this.props.login).checkBtn(tableConfig.formId, item.ID))) return
          tableConfig.btns.push(this.getTableBtnConfig(item))
        })

        return tableConfig
      })
    })
    return Promise.all(promiseFunc).then(configList => {
      this.configList = configList
      return configList
    })
  }

  /**
   * 获取 table 配置的按钮信息
   * @param {*} btn
   */
  getTableBtnConfig = (btn) => {
    return {
      id: btn.ID,
      code: btn.CODE,
      label: btn.LABEL,
      btnType: btn.BTN_TYPE,
      isRule: btn.IS_RULE,
      clickEventFunName: btn.CLICK_EVENT,
      css: btn.CSS,
      icon: btn.ICON,
      formCode: btn.FORM_CODE,
      customParams: btn.CUSTOM_PARAMS,
      checkSelected: btn.SELECT_SHOW,
      isConfirm: btn.IS_COMFIRM,
      api: btn.API_URL,
      num: btn.NUM,
      btn,
      isAddLog: true,
      enableStatus: btn.ENABLE_STATUS
    }
  }

  /**
   * 获取所有表格数据
   * @param {*} configList 
   * @param {*} searchParam 
   */
  getTablesData = (configList, searchParam) => {
    const promiseFunc = configList.map(config => {
      const loadParamJson = this.getLoadParam(config, searchParam)
      if (loadParamJson) {
        return this.props.dispatch({
          type: 'listPage/getTableData',
          payload: loadParamJson,
          url: config.api
        }).then(ret => {
          ret = ret || { Data: {} }
          return {
            tableCode: config.tableCode,
            tableData: ret.Data
          }
        })
      }
      return false
    }).filter(item => item !== false)

    Promise.all(promiseFunc).then(dataList => {
      this.setState({ dataList })
    })
  }

  /**
   * 获取表格加载参数
   * @param {*} tableConfig 
   * @param {*} searchParam 
   */
  getLoadParam = (tableConfig, searchParam) => {
    if (!tableConfig.api) return false

    const { data, app, login } = this.props
    const loadParamJson = initFilter(login.OrgId, '')
    const { orgType, authOrgCodes, ignoreOrgRule } = tableConfig || {}

    orgType && (loadParamJson.OrgType = orgType)
    authOrgCodes && (loadParamJson.AuthOrgCodes = authOrgCodes)
    // 是否忽略组织权限
    ignoreOrgRule && (loadParamJson.IgnoreOrgRule = ignoreOrgRule)
    // 菜单参数
    const currActivatedMenu = app.currActivatedMenu || {}
    loadParamJson.MenuParameter = currActivatedMenu.MENU_FORM_PARAMS
    // 树选中参数
    data && data.TreeSelected && (loadParamJson.TreeSelected = data.TreeSelected)

    //查询参数
    searchParam && addRuleAndGroups(loadParamJson, searchParam)

    return loadParamJson
  }

  /**
   * 表格编辑
   * @param {*} tableCode 
   * @param {*} tableData 
   */
  handleTableEdit = (tableCode, tableData) => {
    this.editData[tableCode] = tableData
  }

  /**
   * 保存编辑的表格
   * @param {*} tableCode 
   * @param {*} api 
   */
  handleTableSave = (tableCode, api) => {
    if (!this.editData[tableCode] || !api) return

    const json = {
      OrgId: this.props.login.OrgId,
      Data: this.editData[tableCode] || []
    }

    this.props.dispatch({
      type: 'app/getDataByPost',
      url: api,
      payload: json
    }).then(res => {
      const { IsSuccessful, Data } = res || {}
      if (IsSuccessful) {
        if (Data.IsSucceed) {
          message.success(Data.Msg)
        } else {
          message.error(Data.Msg)
        }
      }
    })
  }

  getRequestHeaders =() =>{
    // 请求参数
    const addHeader = 'Bearer ' + storage('lacal').getItem('accessToken').val
    const userId = storage('lacal').getItem('userid').val
    const user = storage('lacal').getItem('loginUserVerify').val
    const RootOrgId = storage('lacal').getItem('RootOrgId').val
    const orgId = storage('lacal').getItem('webOrgId').val
    const Tenant = storage('lacal').getItem('Tenant').val
    const headers = {
      // 'Content-Type': type === 'post' ? 'application/json' : 'application/x-www-form-urlencoded',
      Authorization: addHeader,
      userid: userId,
      username: user ? user.username : '',
      RootOrgId,
      orgId,
      Tenant:Tenant
    }
    return headers
  }

  /**
   * 计算导出的 excel 需要在第一行插入的标题
   * @param {*} tableConfig
   */
  getExportInsertTitle = (tableConfig) => {
    const formCode = this.props.formCode
    const searchModel = this.props.search || {
      fieldConfigs: {},
      relatedFieldConfigs: {}
    }
    const relatedFieldConfigs = searchModel.relatedFieldConfigs[formCode] || {}
    const relatedFormCode = relatedFieldConfigs.relatedTo
    const relatedExtraRows = relatedFieldConfigs.extraRows
    const fieldConfigs = searchModel.fieldConfigs[relatedFormCode || formCode] || []
    const exportInserTitle = [tableConfig.exportTitle || this.formData.NAME]
    if (relatedFormCode && Array.isArray(relatedExtraRows)) {
      exportInserTitle.push(...relatedExtraRows)
    }
    fieldConfigs.forEach(fc => {
      const { isExportTitle, label, value, dataSource } = fc
      const cellText = renderExportCell(value, dataSource, fc, this.props.app.enums || {})
      if (isExportTitle && cellText) {
        exportInserTitle.push(`${label}：${cellText}`)
      }
    })
    return exportInserTitle
  }

  /**
   * 渲染表格头部按钮
   * @param {*} tableCode
   */
  renderTableBtn = (tableCode) => {
    const find = this.configList.find(item => item.tableCode === tableCode)
    if (find) {
      return find.btns.map(btn => {
        const { id, api, btnType, label, css, icon } = btn
        switch (btnType) {
          case 7: // 自定义
            return (
              <Button
                key={id}
                type={css}
                icon={icon}
                onClick={() => this.handleTableSave(find.tableCode, api)}
              >{label}</Button>
            )
          case 9: // 导出
            const exportInserTitle = this.getExportInsertTitle(find)
            return (
              <ExportToExcel
                tableId={tableCode}
                fileName={this.formData.NAME || '可编辑列表表单'}
                insertRows={[exportInserTitle.join(' ')]}
              />
            )
          case 15: // 自定义导入
            const uploadProps = {
              name: 'file',
              showUploadList: false,
              action: config.serviceHost(api),
              data: { OrgId: this.props.login.OrgId },
              headers: this.getRequestHeaders(),
              onChange: (info) => {
                const { name, status, response = {} } = info.file
                const { IsSuccessful, ErrorMessage } = response
                if (status === 'done') {
                  if (IsSuccessful) {
                    message.success(`${name} 导入并保存成功`)
                    this.forceUpdate()
                  } else {
                    message.error(`${name} 导入失败，${ErrorMessage}`)
                  }
                } else if (status === 'error') {
                  if (response.ErrorMessage) {
                    message.error(`${name} 导入错误，${ErrorMessage}`)
                  } else {
                    message.error(`${name} 导入错误`)
                  }
                }
              }
            }
            return (
              <Upload {...uploadProps}>
                <Button><Icon type={icon} title={label} /> {label}</Button>
              </Upload>
            )
          default:
            return null
        }
      })
    }
    return null
  }

  /**
   * 获取 Search 组件的宽高
   * @param {*} searchSize 
   */
  handleSize = (searchSize) => {
    !isEqual(searchSize, this.state.searchSize) && this.setState({ searchSize })
  }

  render () {
    const { formCode, preventDefaultSearch, style } = this.props
    const { dataList, searchSize = {} } = this.state
    return (
      <div className='full_height' style={style}>
        <Search
          preventDefaultSearch={preventDefaultSearch}
          formCode={formCode}
          onSearch={this.loadData}
          onSize={this.handleSize}
        />
        {
          dataList.map(({ tableCode, tableData }) => {
            const { data = [], columns = [] } = tableData
            const headerBtns = this.renderTableBtn(tableCode)
            return (
              <LayoutCard
                key={tableCode}
                id={tableCode}
                style={{ height: `calc(100% - ${searchSize.height || 0}px)` }}
              >
                <div className={styles['editable-btn__header']}>{headerBtns}</div>
                <div style={{ height: `calc(100% - ${headerBtns.length ? 40 : 0}px)` }}>
                  <EditableTable
                    data={data}
                    columns={columns}
                    onEdit={(val) => this.handleTableEdit(tableCode, val)}
                  />
                </div>
              </LayoutCard>
            )
          })
        }
      </div>
    )
  }
}

export default connect(({ app, login, search }) => ({ app, login, search }))(EditableTablePage)