import { Steps, Button, Space, Form, Drawer, message } from 'antd'
import StepOne from './StepOne'
import StepTwo from './StepTwo'
import StepThree from './StepThree'
import StepFour from './StepFour'
import React, { useState, useEffect, useRef } from 'react'
import DataTableStruct from './DataTableStruct'
import styled from 'styled-components'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import {
  getDataSourceList,
  getTableSchema,
  buildJsonData,
  createJob,
} from '../services'
import { useNavigate } from 'react-router'
import moment from 'moment'

const { Step } = Steps

const SyncTask = styled.div`
  padding: 20px;
  .check__btn {
    position: absolute;
    right: 0;
    top: 20%;
    border-radius: 0;
  }
`

export default function SyncTaskAdd() {
  // 路由导航
  const navigate = useNavigate()
  // 步骤三ref
  const stepThreeRef = React.createRef()

  // jsonValue
  const jsonValue = React.createRef()

  const cronRef = useRef()

  // 步骤数
  const [currentStep, setCurrentStep] = useState(0)

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

  // 构建loading状态
  const [building, setBuilding] = useState(false)

  // 提交loading状态
  const [submiting, setSubmiting] = useState(false)

  // 完成状态
  const [isfinishBuild, setIsFinishBuild] = useState(false)

  const [dataxJson, setDataxJson] = useState(null)

  const [partitionNum, setPartitionNum] = useState(0)

  const [cron_data, setCronData] = useState(null)

  // 提取源表单表结构
  const [drawDataStruct, setDrawDataStruct] = useState([])
  const updateDrawDataStruct = async (ds_id, table_name) => {
    await updateTableStruct(ds_id, table_name, setDrawDataStruct)
  }

  // 加载源表单表结构
  const [loadDataStruct, setLoadDataStruct] = useState([])
  const updateLoadDataStruct = async (id, table_name) => {
    await updateTableStruct(id, table_name, setLoadDataStruct)
  }

  // 更新表结构
  const updateTableStruct = async (id, table_name, setFunc) => {
    const { data } = await getTableSchema({ id, table_name })
    if (data.code === 200) {
      const tableList = data.data.map(item => {
        const splitData = item.split(':')
        return {
          key: splitData[0],
          id: splitData[0],
          field: splitData[1],
          type: splitData[2],
        }
      })
      setFunc(tableList)
    } else {
      message.error('表结构数据加载失败')
    }
  }

  // 配置提取源表单
  const [drawDataForm] = Form.useForm()

  // 配置加载源表单
  const [loadDataForm] = Form.useForm()

  // 同步参数表单
  const [syncDataForm] = Form.useForm()

  // 当前表单
  const [currentForm, setCurrentForm] = useState(drawDataForm)

  // 上一步/下一步
  const changeStep = num => {
    if (num === -1) {
      setIsFinishBuild(false)
    }
    setCurrentStep(currentStep + num)
  }

  // 暂存cron表达式
  const saveCron = () => {
    if (Object.keys(cronRef.current.getCronData).length !== 0) {
      setCronData(cronRef.current.getCronData)
    }
  }

  // 监听步骤设置当前表单
  useEffect(() => {
    switch (currentStep) {
      case 0:
        setCurrentForm(drawDataForm)
        break
      case 1:
        setCurrentForm(loadDataForm)
        break
      case 3:
        setCurrentForm(syncDataForm)
        break
      default:
        break
    }
  }, [currentStep])

  // 右侧表结构可视
  const [visible, setVisible] = useState(false)

  // 展示
  const showDrawer = () => {
    setVisible(true)
  }

  // 关闭
  const onClose = () => {
    if (currentStep === 3) {
      saveCron()
      if (jsonValue.current) {
        setDataxJson(JSON.parse(jsonValue.current.jsonValue.editor.getValue()))
      }
    }
    setVisible(false)
  }

  // 获取列表数据
  const fetchDataSourceList = async () => {
    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,
        }
      })
      setDataSourceList(list)
    }
  }

  // 挂载的时候获取SourceList
  useEffect(() => {
    fetchDataSourceList()
  }, [])

  const [syncMapSaving, setSyncMapSaving] = useState([])

  // reader_columns
  const [reader_columns, setReaderColumns] = useState([])

  // writer_columns
  const [writer_columns, setWriterColumns] = useState([])

  // 下一步
  const nextStep = () => {
    if (currentStep === 2) {
      setSyncMapSaving(stepThreeRef.current.syncMappings)
      setReaderColumns(
        stepThreeRef.current.syncMappings.map(item => {
          return item.key.drawData
        })
      )
      setWriterColumns(
        stepThreeRef.current.syncMappings.map(item => {
          return item.key.loadData
        })
      )
    }
    if (currentStep === 2) {
      if (stepThreeRef.current?.syncMappings.length) {
        changeStep(1)
      } else {
        message.error('缺少同步字段')
      }
    } else {
      currentForm
        .validateFields()
        .then(() => {
          changeStep(1)
        })
        .catch(err => {
          console.log(err)
          message.error('请检查表单数据是否完整')
        })
    }
  }

  // 格式化构建请求参数数据
  const formatBuildData = () => {
    // 获取表单数据
    const reader_form = drawDataForm.getFieldValue()
    const writer_form = loadDataForm.getFieldValue()
    // 获取id tables
    const reader_datasource_id = reader_form['datasource_name']
    const reader_tables = [reader_form['datasource_table']]
    const writer_datasource_id = writer_form['datasource_name']
    const writer_tables = [writer_form['datasource_table']]
    const writer_filename = writer_form['writer_filename']
    // 基础固定参数
    const base_params = {
      reader_datasource_id,
      reader_tables,
      reader_columns,
      writer_datasource_id,
      writer_tables,
      writer_columns,
    }
    // 获取表类型
    const reader_type = dataSourceList.find(
      item => item.key === reader_datasource_id
    ).datasource
    const writer_type = dataSourceList.find(
      item => item.key === writer_datasource_id
    ).datasource
    // 结构表单参数
    const {
      reader_split_pk,
      where_param,
      query_sql,
      reader_default_fs,
      reader_file_type,
      reader_path,
      reader_field_delimiter,
    } = reader_form
    const {
      pre_sql,
      post_sql,
      writer_default_fs,
      writer_file_type,
      writer_path,
      writer_mode,
      writer_field_delimiter,
    } = writer_form
    // 根据类型区分参数
    switch (`${reader_type}2${writer_type}`) {
      case 'mysql2mysql':
        return {
          ...base_params,
          rdbms_reader: { reader_split_pk, where_param, query_sql },
          rdbms_writer: { pre_sql, post_sql },
        }
      case 'mysql2hive':
        return {
          ...base_params,
          rdbms_reader: { reader_split_pk, where_param, query_sql },
          hive_writer: {
            writer_default_fs,
            writer_file_type,
            writer_path,
            writer_mode,
            writer_field_delimiter,
            writer_filename,
          },
        }
      case 'hive2mysql':
        return {
          ...base_params,
          hive_reader: {
            reader_default_fs,
            reader_file_type,
            reader_path,
            reader_field_delimiter,
          },
          rdbms_writer: { pre_sql, post_sql },
        }
      case 'hive2hive':
        return {
          ...base_params,
          hive_reader: {
            reader_default_fs,
            reader_file_type,
            reader_path,
            reader_field_delimiter,
          },
          hive_writer: {
            writer_default_fs,
            writer_file_type,
            writer_path,
            writer_mode,
            writer_field_delimiter,
            writer_filename,
          },
        }
      default:
        break
    }
    return null
  }

  // 构建表单
  const build = async () => {
    saveCron()
    const buildParams = formatBuildData()
    if (!buildParams) {
      message.error('获取表单参数失败')
      return
    }
    setBuilding(true)
    const { data } = await buildJsonData(buildParams)
    if (data.code === 200) {
      message.success('构建成功')
      const json = data.data.json
      setDataxJson(json)
      showDrawer()
      setIsFinishBuild(true)
    } else {
      message.error('构建失败,请检查表单数据')
    }
    setBuilding(false)
  }

  // 完成提交
  const finishSubmit = async job_json => {
    // setSubmiting(true)
    const fields = currentForm.getFieldValue()
    const params = {
      ...fields,
      job_json,
      inc_start_time: moment(fields.inc_start_time).unix(),
      user_id: 'test',
    }
    params['partition_num'] = partitionNum
    const { data } = await createJob(params)
    if (data.code === 200) {
      message.success('提交成功')
      navigate(-1)
    } else {
      message.error(data.msg)
    }
    setSubmiting(false)
  }

  // 提交表单
  const submit = () => {
    if (jsonValue.current) {
      setDataxJson(JSON.parse(jsonValue.current.jsonValue.editor.getValue()))
    }
    try {
      let job_json = JSON.stringify(dataxJson)
      if (jsonValue.current) {
        job_json = JSON.stringify(
          JSON.parse(jsonValue.current.jsonValue.editor.getValue())
        )
      }
      if (Object.keys(cronRef.current.getCronData).length !== 0) {
        currentForm.setFieldValue(
          'cron_expression',
          cronRef.current.getCronData
        )
      }
      currentForm
        .validateFields()
        .then(() => {
          finishSubmit(job_json)
        })
        .catch(err => {
          message.error('请检查表单数据是否完整')
        })
    } catch (error) {
      message.error('转换JSON字符串失败，请检查json数据', error)
    }
  }

  return (
    <SyncTask>
      {/* 步骤条 */}
      <Steps current={currentStep} labelPlacement="vertical" size="small">
        <Step title="步骤1: 配置提取源" />
        <Step title="步骤2: 配置加载源" />
        <Step title="步骤3: 配置转换规则" />
        <Step title="步骤4: 设置同步参数" />
      </Steps>

      {/* 表单项 */}
      {/* 配置提取源 */}
      {currentStep === 0 && (
        <StepOne
          drawDataForm={drawDataForm}
          dataSourceList={dataSourceList}
          updateTableStruct={updateDrawDataStruct}
        />
      )}
      {/* 配置加载源 */}
      {currentStep === 1 && (
        <StepTwo
          loadDataForm={loadDataForm}
          dataSourceList={dataSourceList}
          updateTableStruct={updateLoadDataStruct}
        />
      )}

      {/* 配置转换规则 */}
      {currentStep === 2 && (
        <StepThree
          onRef={stepThreeRef}
          drawDataForm={drawDataForm}
          loadDataForm={loadDataForm}
          syncMapSaving={syncMapSaving}
        />
      )}

      {/* 设置同步参数 */}
      {currentStep === 3 && (
        <StepFour
          onRef={cronRef}
          syncDataForm={syncDataForm}
          cron_data={cron_data}
          partitionNumHandle={{
            num: partitionNum,
            func: val => setPartitionNum(val),
          }}
        />
      )}

      {/* 按扭操作 */}
      {/* 表结构预览 */}
      {(currentStep === 0 || currentStep === 1 || currentStep === 3) && (
        <>
          {dataxJson !== null ||
            (currentStep !== 3 && (
              <Button
                type="primary"
                onClick={showDrawer}
                className="check__btn"
                size="large"
                icon={<MenuFoldOutlined />}>
                {currentStep !== 3 ? '表结构预览' : '构建'}
              </Button>
            ))}

          <Drawer
            title={currentStep === 3 ? '构建' : '表结构预览'}
            placement="right"
            onClose={onClose}
            visible={visible}
            width={600}
            mask={false}
            destroyOnClose={true}
            closeIcon={<MenuUnfoldOutlined style={{ color: '#1890ff' }} />}>
            <DataTableStruct
              currentStep={currentStep}
              tableData={currentStep === 0 ? drawDataStruct : loadDataStruct}
              datax={dataxJson}
              onRef={jsonValue}
            />
          </Drawer>
        </>
      )}

      {/* 按扭操作 */}
      <Space style={{ margin: '20px' }}>
        {currentStep === 0 && (
          <Button
            onClick={() => {
              navigate(-1)
            }}>
            返回上一级
          </Button>
        )}
        {currentStep !== 0 && (
          <Button
            onClick={() => {
              changeStep(-1)
            }}
            disabled={building}>
            上一步
          </Button>
        )}
        {currentStep === 3 ? (
          <Button
            type="primary"
            onClick={isfinishBuild ? submit : build}
            loading={isfinishBuild ? submiting : building}>
            {isfinishBuild ? '提交' : '构建'}
          </Button>
        ) : (
          <Button type="primary" onClick={nextStep}>
            下一步
          </Button>
        )}
      </Space>
    </SyncTask>
  )
}
