import React from 'react';
import MSG from '../../../../utils/msgsub'
import { WrapperModal } from './style';
import Select from 'antd/lib/Select';
import Card from 'antd/lib/card';
import Button from 'antd/lib/button';
import Input from 'antd/lib/input';
import { Shell } from '../../../../../../utils/shell';
import SparkMD5 from 'spark-md5';
import { RendererEnv } from '../../../../../../env';
import './MainExport.css';
import Tag from 'antd/lib/tag';
import ArrowUpOutlined from '@ant-design/icons/lib/icons/ArrowUpOutlined';

type OptionField = { label: string, name: string }

interface ExportTemplate {
  tempKey: string
  tempName: string
  exportFields: string
}

interface ExportExcelProps {
  normalSelectAll?: boolean
  env: RendererEnv
  action: any
  ctx: any
  handleCancel: () => void
}
interface ExportExcelState {
  visible: boolean
  loading: boolean
  fileType: string
  exportRange: string
  exportType: string
  tempId: string
  tempName: string
  exportFields: string[]
  exportTemplates: ExportTemplate[]
}

export default class LionExportExcel extends React.Component<ExportExcelProps, ExportExcelState> {

  static readonly DEFAULT_TEMP_ID = 'defaultTempId'
  static readonly DEFAULT_TEMP_NAME = '默认模板'

  _fileTypeList: OptionField[] = [{ label: '数据文件', name: 'dataFile' }]
  _exportRangeList: OptionField[] = [{ label: '选中数据', name: '0' }, { label: '所有数据', name: '1' }]
  _exportTypeList: OptionField[] = [{ label: '按设置列导出', name: 'column' }, { label: '按模板导出', name: 'template' }]
  allExportColumns: OptionField[]
  defaultTemplate: ExportTemplate

  constructor(props: ExportExcelProps) {
    super(props)
    const exportColumns = props.ctx.exportFields as OptionField[]
    const isSelected = props.ctx.selectedItems.length > 0
    this.allExportColumns = exportColumns
    this.defaultTemplate = { tempKey: LionExportExcel.DEFAULT_TEMP_ID, tempName: LionExportExcel.DEFAULT_TEMP_NAME, exportFields: exportColumns.map(field => field.name).join(',') }
    this.state = {
      visible: true,
      loading: false,
      fileType: 'dataFile',
      exportRange: isSelected ? '0' : '1',
      exportType: 'column',
      tempId: LionExportExcel.DEFAULT_TEMP_ID,
      tempName: LionExportExcel.DEFAULT_TEMP_NAME,
      exportFields: exportColumns.map(field => field.name),
      exportTemplates: [this.defaultTemplate]
    }
  }

  componentDidMount() {
    this.handleGetTemplate()
  }

  async handleGetTemplate() {
    const { env, ctx } = this.props
    const selectApi = ctx.selectApi
    if (selectApi) {
      const res = await env.fetcher(selectApi)
      if (res.status === 0) {
        const template = res.data as ExportTemplate[]
        template.push(this.defaultTemplate)
        this.setState({
          exportTemplates: template,
          tempId: template[0].tempKey,
          tempName: template[0].tempName,
          exportFields: template[0].exportFields.split(',')
        })
      }
    }
  }

  async handleSaveTemplate() {
    const { env, ctx } = this.props
    const setApi = ctx.setApi
    if (setApi) {
      const { tempName, exportFields } = this.state
      const tempKey = SparkMD5.hash(tempName)
      const res = await env.fetcher(setApi, { tempKey, tempName, exportFields: exportFields.join(',') })
      if (res.status === 0) {
        this.handleGetTemplate()
      } else {
        MSG._error(res.msg, env?.getModalContainer)
      }
    }
  }

  async handleDeleteTemplate() {
    const { env, ctx } = this.props
    const deleteApi = ctx.deleteApi
    if (deleteApi) {
      const { tempId } = this.state
      const res = await env.fetcher(deleteApi, { tempKey: tempId })
      if (res.status === 0) {
        this.handleGetTemplate()
      } else {
        MSG._error(res.msg, env?.getModalContainer)
      }
    }
  }

  handleChangeTemplate(tempId: string) {
    const fields = this.state.exportTemplates.find(item => item.tempKey === tempId)
    this.setState({ tempId, tempName: fields?.tempName ?? '', exportFields: fields?.exportFields.split(',') ?? [] })
  }

  handeCancel = () => {
    this.props.handleCancel()
    this.setState({ visible: !this.state.visible })
  }

  openDownloadDialog = (url: any, saveName: string) => {
    return new Promise((resolve, reject) => {
      resolve('')
    }).then(res => {
      if (typeof url == 'object' && url instanceof Blob) {
        url = URL.createObjectURL(url); // 创建blob地址
      }
      var aLink = document.createElement('a');
      aLink.href = url;
      aLink.download = saveName || ''; // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，file:///模式下不会生效
      var event;
      if (window.MouseEvent) event = new MouseEvent('click');
      else {
        event = document.createEvent('MouseEvents');
        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
      }
      aLink.dispatchEvent(event);
    })
  }

  handleSubmit = async () => {
    const { exportRange, exportFields, exportType } = this.state;
    const { ctx, env } = this.props;
    const { selectedItems, exportSetColumnFields } = ctx;
    if (exportRange === '0' && selectedItems?.length <= 0) {
      MSG._error('选中项为空', env?.getModalContainer)
      return
    }
    const baseUrl = env?.axiosInstance?.defaults?.baseURL;
    const fields = exportType === 'template' ? exportFields.join(',') : exportSetColumnFields.join(',')
    this.setState({ loading: true })

    if (!Shell.hasShell()) {
      env.fetcher(ctx.api, { ...ctx, exportType: Number(exportRange), exportFields: fields }).then((res: any) => {
        if (res?.status === 0) {
          res?.data && this.openDownloadDialog((baseUrl ?? res?.reqUrl) + res?.data?.fileUrl, res?.data?.fileName)
          MSG._success(res?.msg, env?.getModalContainer);
        } else if (res?.status === 301) {
          MSG._info(res?.msg, env?.getModalContainer);
        } else {
          MSG._error(res?.msg, env?.getModalContainer);
        }
      }).catch((err: any) => {
        MSG._error('导出出错', env?.getModalContainer)
      }).finally(() => this.setState({ loading: false }))
    } else {
      env.fetcher(ctx.api, { ...ctx, exportType: exportRange, exportFields: fields }).
        then(async (res: any) => {
          this.setState({
            visible: false
          })
          if (res?.status === 301) {
            MSG._info(res?.msg, env?.getModalContainer);
            return
          }
          const confirmd = await env.confirm('是否要保存并打开文件?');
          if (confirmd) {
            const shellRes = await Shell.download((baseUrl ?? res?.reqUrl) + res?.data?.fileUrl, res?.data?.fileName, 0);
            if (shellRes?.success) {
              MSG._success(shellRes?.msg!, env?.getModalContainer);
            } else {
              MSG._error(shellRes?.msg!, env?.getModalContainer);
            }
          } else {
            MSG._info('用户取消', env?.getModalContainer)
          }
        }).catch((err: any) => {
          MSG._error('导出出错', env?.getModalContainer)
        }).finally(() => this.setState({ loading: false }))
    }
  }

  handleReset = () => {
    const { exportTemplates } = this.state
    const isSelected = this.props.ctx.selectedItems.length > 0
    this.setState({
      fileType: 'dataFile',
      exportRange: isSelected ? '0' : '1',
      exportType: 'column',
      tempId: exportTemplates.length > 0 ? exportTemplates[0].tempKey : '',
      tempName: exportTemplates.length > 0 ? exportTemplates[0].tempName : '',
      exportFields: exportTemplates.length > 0 ? exportTemplates[0].exportFields.split(',') : []
    })
  }

  renderSelectTag = (props: any) => {
    const { label, value, closable, onClose } = props;
    const onPreventMouseDown = (event: React.MouseEvent<HTMLSpanElement>) => {
      event.preventDefault();
      event.stopPropagation();
    };
    return (
      <Tag
        icon={<ArrowUpOutlined onClick={() => this.handleSort(value)} />}
        onMouseDown={onPreventMouseDown}
        closable={closable}
        onClose={onClose}
        style={{ margin: 3 }}
      >
        {label}
      </Tag>
    );
  }

  handleSort(name: string) {
    const { exportFields } = this.state
    const tempArr = Array.from(exportFields)
    const index = tempArr.findIndex(item => name === item)
    if (index > 0) {
      const a = tempArr[index - 1]
      const b = tempArr[index]
      tempArr[index - 1] = b
      tempArr[index] = a
      this.setState({ exportFields: tempArr })
    }
  }

  render() {
    const { env, normalSelectAll } = this.props;
    const { visible, loading, fileType, exportRange, exportType, tempId, tempName, exportFields, exportTemplates } = this.state

    return (
      <div className="lion-export-wrapper">
        <WrapperModal
          wrapClassName='fastlion-export'
          visible={visible}
          closable
          getContainer={env?.getModalContainer as any}
          onCancel={this.handeCancel}
          title="文件导出"
          zIndex={9999}
          maskStyle={{ zIndex: 9999 }}
          footer={
            <div className="lion-export-btns"
              style={{
                display: 'flex',
                width: '100%',
                justifyContent: 'space-between',
                overflow: 'hidden'
              }}
            >
              <Button onClick={this.handleReset}>重置</Button>
              <div>
                <Button onClick={this.handeCancel}>取消</Button>
                <Button style={{ marginLeft: '10px' }} type='primary' loading={loading} onClick={this.handleSubmit.bind(this)}>确定</Button>
              </div>
            </div>
          }
        >
          <div style={{ width: '100%', marginTop: '4px', paddingLeft: '30px' }}>
            <span style={{ textAlign: 'left', paddingRight: '25px', color: '#2a3e61' }}>文件类型</span>
            <Select dropdownStyle={{ zIndex: 10019 }} bordered={false} placeholder='文件类型' value={fileType}
              onChange={type => this.setState({ fileType: type })}>
              {this._fileTypeList.map((item, index) => <Select.Option key={index} value={item.name}>{item.label}</Select.Option>)}
            </Select>
          </div>
          <div style={{ width: '100%', marginTop: '15px', paddingLeft: '30px' }}>
            <span style={{ textAlign: 'left', paddingRight: '25px', color: '#2a3e61' }}>导出范围</span>
            <Select dropdownStyle={{ zIndex: 10019 }} bordered={false} placeholder='导出范围' disabled={normalSelectAll} value={exportRange}
              onChange={type => this.setState({ exportRange: type })}>
              {this._exportRangeList.map((item, index) => <Select.Option className='lion-option-disabled' key={index} value={item.name} disabled={index !== parseInt(exportRange)} >{item.label}</Select.Option>)}
            </Select>
          </div>
          <div style={{ width: '100%', marginTop: '15px', paddingLeft: '30px' }}>
            <span style={{ textAlign: 'left', paddingRight: '25px', color: '#2a3e61' }}>导出方式</span>
            <Select dropdownStyle={{ zIndex: 10019 }} bordered={false} placeholder='导出方式' value={exportType}
              onChange={type => this.setState({ exportType: type })}>
              {this._exportTypeList.map((item, index) => <Select.Option key={index} value={item.name}>{item.label}</Select.Option>)}
            </Select>
          </div>
          <div style={{ width: '100%', marginTop: '15px', paddingLeft: '30px', display: exportType === 'template' ? 'block' : 'none' }}>
            <span style={{ textAlign: 'left', paddingRight: '25px', color: '#2a3e61' }}>导出模板</span>
            <Select className='my-select' dropdownStyle={{ zIndex: 10019 }} bordered={false} value={tempId}
              onChange={id => this.handleChangeTemplate(id)}>
              {exportTemplates.map(temp => <Select.Option value={temp.tempKey}>{temp.tempName}</Select.Option>)}
            </Select>
            {/* <Button style={{ marginLeft: '10px', fontSize: '13px' }} onClick={() => this.setState({ showSetting: true })}>设置</Button> */}
          </div>
          {exportType === 'template' &&
            <div style={{ width: '100%', marginTop: '10px', paddingLeft: '30px', paddingRight: '30px' }}>
              <Card bodyStyle={{ maxHeight: 'calc(100vh - 510px)', overflow: 'auto' }} style={{ width: '100%' }} headStyle={{ height: '30px', backgroundColor: '#f5f5f5' }} size="small" title="导出字段" >
                <div style={{ marginTop: '12px', width: '100%', padding: '0px 12px' }}>
                  <Select tagRender={this.renderSelectTag} value={exportFields} className='my-field-select' placeholder='请选择导出字段' mode="multiple" dropdownStyle={{ zIndex: 10019 }}
                    onChange={value => this.setState({ exportFields: value })}>
                    {this.allExportColumns.map((field) => <Select.Option key={field.name} value={field.name}>{field.label}</Select.Option>)}
                  </Select>
                </div>
                <div style={{ padding: '12px', display: 'flex' }}>
                  <Input addonBefore="模板名称" value={tempName} placeholder='请输入' onChange={e => this.setState({ tempName: e.target.value })} />
                  <Button style={{ fontSize: '13px', borderRadius: '0px' }} type='primary' onClick={() => this.handleSaveTemplate()}>保存</Button>
                  <Button style={{ fontSize: '13px', borderRadius: '0px 2px 2px 0px' }} disabled={tempId === LionExportExcel.DEFAULT_TEMP_ID} onClick={() => this.handleDeleteTemplate()}>删除</Button>
                </div>
              </Card>
            </div>
          }
        </WrapperModal>
      </div >
    )
  }
}
