import {memo, useCallback, useMemo, useRef, useState} from 'react';

import {QuickStartStep} from "./QuickStartStep.jsx";
import {MODAL_TYPE, RadioType} from "../constants.js";
import {StepsForm} from "@ant-design/pro-components";
import {Button, message, Modal, Space, Tooltip} from "antd";
import {ModalConfigPanel} from "./ModalConfigPanel.jsx";
import {ConfigPreviewPanel} from "./ConfigPreviewPanel.jsx";
import {InfoCircleFilled} from "@ant-design/icons";
import {SqlStartStep} from "./SqlStartStep";
import {useWorkFlow} from "../../../hooks/useWorkFlow";
import {DIM_TYPE_ENUM} from "../../../constants";
import {useAppDispatch} from "../../../../redux/configureStore";
import {executeSql} from "../../MainPage/slice/thunks";

const descriptions = [
  {
    key: '1',
    label: '模型名称',
    children: '视光产品销售数据',
  },
  {
    key: '2',
    label: '创建方式',
    children: '快速创建',
  },
  {
    key: '3',
    label: '关联原子指标',
    children: '5',
  },
  {
    key: '4',
    label: '关联派生指标',
    children: '6',
  },
  {
    key: '5',
    label: '关联复合指标',
    children: '6',
  },
];

const viewerColumns = [
  {
    title: '表名',
    dataIndex: 'tableName',
    key: 'tableName',
    width: 180,
  },
  {
    title: '字段',
    dataIndex: 'bizName',
    key: 'bizName',
    width: 130,
  },
  {
    title: '类型',
    dataIndex: 'dataType',
    key: 'dataType',
  },
  {
    title: '字段含义',
    dataIndex: 'comment',
    key: 'fieldDesc',
    width: 130,
    render: (text,record) => (
      <span>
        <span>{text}</span>
        {
          record?.descriptions &&
          <span>
            <Tooltip title={record?.descriptions}>
              <InfoCircleFilled style={{marginLeft: 5, color: '#bfbfbf'}}/>
            </Tooltip>
          </span>
        }
      </span>
    ),
  },
  {
    title: '关联',
    dataIndex: 'relation',
    key: 'relation',
    width: 50,
    render: (text) => <a>{text}</a>,
  },
];

/** 表头信息*/
const configColumns = [
  {
    title: '数据表',
    dataIndex: 'tableName',
    readonly: true,
    width: '16%',
  },
  {
    title: '字段',
    dataIndex: 'fieldName',
    readonly: true,
    width: '12%',
  },
  {
    title: '业务字段',
    dataIndex: 'bizName',
    width: '12%',
    fieldProps: {
      allowClear:false,
    },
  },
  {
    title: '类型',
    dataIndex: 'dataType',
    readonly: true,
    width: '8%',
  },
  {
    title: '主键',
    dataIndex: 'isKey',
    valueType: 'switch',
  },
  {
    title: '度量',
    dataIndex: 'measure',
    valueType: 'switch',
  },
  {
    title: '通用维度',
    dataIndex: 'common',
    valueType: 'switch',
    width: 80,
  },
  {
    title: '时间维度',
    dataIndex: 'datetime',
    valueType: 'switch',
    tooltip: '非日期类型，不允许勾选为时间维度',
    fieldProps: (form, {entity}) =>({disabled: entity.dataType!=='DATETIME'}),
    //render: (text, record, _, action) => console.log(text, record, _, action)
    width: 90,
  },
  {
    title: '字段含义',
    dataIndex: 'comment',
    fieldProps: {
      allowClear:false,
    },
    width: '12%',
  },
  {
    title: '字段描述',
    dataIndex: 'description',
    fieldProps: {
      allowClear:false,
      placeholder:"请输入详细描述内容"
    },
    width: '15%',
  },
];

export const ModalDesign = memo(({
  open=false,
  onCancel,
  onFinish,
  initialValues,
  type
}) => {
  const {
    getFields ,
    markFields ,
    getNodesState,
    getEdgesState
  } = useWorkFlow();
  const dispatch = useAppDispatch();
  /** StepForm步骤*/
  const [current,setCurrent] = useState(0);
  /** 步骤一的Ref */
  const stepOneRef = useRef(null);
  /** sql缓存 */
  const sqlRef = useRef("");
  /** sql结果状态 */
  const [sqlStatus,setSqlStatus] = useState(false);
  /** sql结果 */
  const [sqlResult,setSqlResult] = useState(null);
  /** ConfigTable的Ref钩子*/
  const configTableRef = useRef();
  /** 步骤二的Table数据 */
  const configData = useMemo(()=> {
    const nodeFields = getFields(getNodesState);
    let bizList = [];
    let initFields = [];
    if (initialValues){
      const {modelDetail} = initialValues;
      initFields = modelDetail?.fields || [];
      bizList = [
        ...(modelDetail?.dimensions || []),
        ...(modelDetail?.identifiers || []),
        ...(modelDetail?.measures || [])
      ];
    }

    // 快速创建回显
    if (MODAL_TYPE.QUICK===type?.value){
      if (initialValues){
        return nodeFields.map((field) => {
          const initObj = bizList.find(item=>item.name===field.fieldName)
          return initObj
            ? {
              ...field,
              id:Math.random(),
              bizName:initObj.bizName.replace(initialValues?.bizName+"_", ""),
              isKey:DIM_TYPE_ENUM.IDENTIFY===initObj.type,
              common:DIM_TYPE_ENUM.CATEGORICAL===initObj.type,
              datetime:DIM_TYPE_ENUM.DATETIME===initObj.type,
              measure:!initObj.type,
            }
            : field
        })
      }
    }

    // SQL创建
    if (MODAL_TYPE.SQL===type?.value){
      let tempArr = [];

      if (initialValues && !sqlResult){
        const {modelDetail} = initialValues;
        const SQL = modelDetail?.sqlQuery || "";
        const fromIndex = SQL.indexOf('FROM');
        const sqlRelation = SQL.slice(fromIndex)
        let SQLFields = "SELECT "
        initFields.forEach(({bizName,tableName,fieldName,dataType,comment},index) => {
          if (index===initFields.length-1){
            SQLFields += `${tableName}.${fieldName} \r\n`
          }else {
            SQLFields += `${tableName}.${fieldName},\r\n`
          }
          const initObj = bizList.find(item=>item.name===fieldName)
          tempArr.push({
            id:Math.random(),
            comment:comment,
            bizName: bizName.replace(initialValues?.bizName+"_",""),
            dataType: dataType,
            fieldName: fieldName,
            tableName: tableName,
            isKey:DIM_TYPE_ENUM.IDENTIFY===initObj?.type,
            common:DIM_TYPE_ENUM.CATEGORICAL===initObj?.type,
            datetime:DIM_TYPE_ENUM.DATETIME===initObj?.type,
            measure:!initObj?.type,
          })
        })

        sqlRef.current=SQLFields + sqlRelation;

        setSqlStatus(true);
      }

      if(sqlResult){
        // 取SELECT-FROM之间的字符串，并分割出所有字段
        const fromIndex = sqlRef.current?.indexOf('FROM');
        const fieldStr = sqlRef.current.slice(0, fromIndex).replace('SELECT','');
        // 按逗号分割字段
        const fieldArr = fieldStr.split(',');
        // 判断是否有JOIN
        const sqlRelation = sqlRef.current?.slice(fromIndex)
        const regex = /\b(LEFT\s+JOIN|RIGHT\s+JOIN|INNER\s+JOIN)\b/i;
        const isJoin = regex.test(sqlRelation.toUpperCase());

        // 单表查询直接取表名
        const regex2 = /FROM\s+([\w_]+)/;
        const singleTable = sqlRelation.match(regex2)[1] || "";

        // 按顺序处理SQL字符串
        const fieldFormat = fieldArr.map(item=> {
          let table,field,aliasStr,str=item;
          // 判断字符串是否包含AS,有则去除AS
          const asRegex = /\s+AS\s+/i;
          const hasAs = asRegex.test(item);
          if (hasAs){
            const asStr = item.match(asRegex)[0];
            str = item.split(asStr)[0];
            aliasStr = item.split(asStr)[1].trim();
          }
          // 去除AS之后去除所有符号,但不包含'.'
          str = str.replace(/^\s+|\s+$/g, '').replace(/\s+/g, '');

          // 若是以.的形式取则分割出表和字段
          if (str.includes('.')){
            const split = str.split('.');
            table = split[0]
            field = split[1]
          }

          // 有join则按表分类字段，否则直接取FROM后面的表
          return isJoin
            ? {table,field,alias:aliasStr}
            : {
              table:table?table:singleTable,
              field:field?field:str,
              alias:aliasStr
            }
        });

        sqlResult.forEach(col=>{
          // SQL中摘出的字段、别名、表
          let {table,alias,field}  = fieldFormat.find(item=>item.field===col.nameEn || item.alias===col.nameEn);
          // 校验两个字段是否重叠
          const exist = tempArr.find(item=>item.tableName===table && item.fieldName===col.nameEn)
          if (exist){
            // 若重叠
            const sss = fieldFormat
              .filter(item=>!(item.table===table && item.field===col.nameEn))
              .find(item=>item.field===col.nameEn)

            table = sss?.table || '';
            alias = sss?.alias || '';
          }


          // 描述能取初始值就取初始值
          const finalField = alias?field:col.nameEn;
          let mergeObj ;
          if (initialValues){
            mergeObj = initFields.find(item=> item.tableName === table && item.fieldName === finalField)
          }

          // 初始化配置
          const initObj = bizList.find(item=>item.name===finalField);

          // 字段：有别名取字段否则取返回的值
          tempArr.push(
            {
              id:Math.random(),
              bizName: alias? alias: (mergeObj? mergeObj?.bizName.replace(initialValues?.bizName+"_",""):finalField),
              comment: mergeObj? mergeObj?.comment : col.comment,
              dataType: col.type,
              fieldName: finalField,
              tableName: table,
              isKey:DIM_TYPE_ENUM.IDENTIFY===initObj?.type,
              common:DIM_TYPE_ENUM.CATEGORICAL===initObj?.type,
              datetime:DIM_TYPE_ENUM.DATETIME===initObj?.type,
              measure:initObj?!initObj?.type:false,
            }
          )
        })
      }
      console.log(tempArr)
      return tempArr
    }
    // 默认取WorkFlow数据回显
    return nodeFields
  },[initialValues,getNodesState,sqlResult]);

  /** 步骤三的预览数据 */
  const [viewerData,setViewerData] = useState([]);

  /** 提交最终数据 */
  const handelFinish = useCallback((values)=>{
    onFinish({
      ...values,
      nodes:configTableRef.current.getRowsData(),
      edges:getEdgesState,
      classify:viewerData,
      modelType:type.value,
      sqlStr:sqlRef.current
    })
    setCurrent(0)
  },[viewerData])


  /** 分类数据 */
  const secondStepFinish = useCallback(()=>{
    setViewerData(
      markFields(
        configTableRef.current.getRowsData(),
        RadioType
      )
    )
    setCurrent(pre=>pre+1)
  },[current])

  /** SQL编辑器回调 */
  const onEditorChange = useCallback((sql)=>{
    sqlRef.current = sql
  },[])

  /** 关闭设计*/
  const onCloseModal = useCallback((e)=>{
    onCancel(e)
    setCurrent(0)
    setViewerData([])
    setSqlResult(null)
    sqlRef.current = ""
  },[]);

  /** SQL执行回调 */
  const onExecuteSql = useCallback(async ()=>{
    const formValue = await stepOneRef?.current?.validateFieldsReturnFormatValue?.();
    let status = false;
    await dispatch(executeSql({
      params:{
        id: formValue.dbSource,
        sql:sqlRef.current,
        sqlVariables:[],
        limit:1
      },
      resolve(data){
        setSqlResult(data?.columns||[])
        message.success("执行成功")
        status=true
      }
    }))

    // 开启下一步
    setSqlStatus(status);
    // SELECT dwd_payment_detail.id ,
    //   dwd_payment_detail.adm_id  ,
    //   dwd_payment_detail.bill_date  ,
    //   dwd_payment_detail.pat_amt  ,
    //   ods_prhis_adm.id  ,
    //   ods_prhis_adm.AdmDate  ,
    //   ods_prhis_adm.HospitalName
    //   ads_optometry_sales.adm_id
    // FROM dwd_payment_detail
    //   LEFT JOIN ods_prhis_adm
    // ON dwd_payment_detail.adm_id=ods_prhis_adm.ID
  },[])

  return (
    <StepsForm
      current={current}
      onFinish={handelFinish}
      containerStyle={{width:'90%'}}
      stepsFormRender={(dom, submitter) =>
        <Modal
          title="分步表单"
          width={1412}
          onCancel={onCloseModal}
          open={open}
          footer={
            submitter.map(item=>{
              if (item.key==='pre'){
                return <Button key="pre" onClick={()=>setCurrent(pre=>pre-1)}>上一步</Button>
              }
              if (current===0 && MODAL_TYPE.SQL===type?.value){
                return <Space key="excute">
                  <Button onClick={onExecuteSql}>执行SQL</Button>
                  {sqlStatus && item}
                </Space>
              }
              return item
            })
          }
          destroyOnClose={true}
          maskClosable={false}
        >
          {dom}
        </Modal>
      }
    >
      {/** 步骤一 */}
      <StepsForm.StepForm
        name="base"
        title="基本信息"
        labelCol={{span:6}}
        wrapperCol={{span:18}}
        layout='horizontal'
        formRef={stepOneRef}
        onFinish={()=> setCurrent(pre => pre + 1)}
      >
        {MODAL_TYPE.QUICK===type?.value && <QuickStartStep initialValues={initialValues}/>}
        {MODAL_TYPE.SQL===type?.value && <SqlStartStep sql={sqlRef.current} initialValues={initialValues} onEditorChange={onEditorChange}/>}
      </StepsForm.StepForm>

      {/** 步骤二 */}
      <StepsForm.StepForm
        name="configuration"
        title="模型设置"
        onFinish={secondStepFinish}
      >
        <ModalConfigPanel values={configData} columns={configColumns} ref={configTableRef}/>
      </StepsForm.StepForm>

      {/** 步骤三 */}
      <StepsForm.StepForm
        name="viewer"
        title="完成设置"
      >
        <ConfigPreviewPanel values={viewerData} descriptions={descriptions} columns={viewerColumns}/>
      </StepsForm.StepForm>
    </StepsForm>
  )
})
