import {ProCard, ProTable} from '@ant-design/pro-components';
import {Button, Checkbox, message} from 'antd';
import {useCallback, useEffect, useRef, useState} from 'react';
import {TreeMenu} from '../../components/TreeMenu.jsx';
import {DIM_TYPE_ENUM, ProTableDefault, STATUS_TYPE, TYPE_ENUM} from '../../constants.js';
import {columnsFactory} from '../../../utils/columnsFactory.jsx';
import {DomainForm} from './components/DomainForm.jsx';
import {SelectModal} from '../../components/SelectModal';
import {ModalDesign} from "./components/ModalDesign.jsx";
import {MODAL_TYPE} from "./constants.js";
import {useAppDispatch, useAppSelector} from "../../../redux/configureStore";
import {
  createDomain,
  createModal,
  updateModal,
  deleteModal,
  getDBSource,
  getDomains,
  getModalDetail,
  getModals
} from "../MainPage/slice/thunks";
import {selectDomains, selectModals} from "../MainPage/slice/selectors";
import {useWorkFlow} from "../../hooks/useWorkFlow";
import {CALC_TYPE, FORM_TYPE} from "../IndexDefine/constants";

const modalTypeOption = [
  {label: "快速创建", value: MODAL_TYPE.QUICK, icon: true},
  {label: "SQL自定义", value: MODAL_TYPE.SQL, icon: true},
]

const baseColumns = [
  {
    title: '模型编码',
    dataIndex: 'bizName',
  },
  {
    title: '模型名称',
    dataIndex: 'name',
  },
  {
    title: '别名',
    dataIndex: 'alias',
  },
  {
    title: '描述',
    dataIndex: 'description',
  },
  {
    title: '数据源',
    dataIndex: 'datasourceName',
  },
  {
    title: '创建方式',
    dataIndex: 'createMethod',
    valueType: 'select',
    fieldProps: {
      options: modalTypeOption
    },
  },
  {
    title: '状态',
    dataIndex: 'status',
    valueType: 'select',
    valueEnum: STATUS_TYPE,
  },
  {
    title: '关联原子指标',
    dataIndex: 'ATOMIC',
  },
  {
    title: '关联派生指标',
    dataIndex: 'DERIVED',
  },
  {
    title: '关联复合指标',
    dataIndex: 'COMPOSITE',
  }
]

export const ModalManage = () => {
  const { clear } = useWorkFlow();
  const dispatch = useAppDispatch();
  const domains = useAppSelector(selectDomains);
  const modals = useAppSelector(selectModals);
  /** 格式化表头 */
  const [columns, setColumns] = useState([]);

  /** 打开主题域表单 */
  const [domainModalOpen, setDomainModalOpen] = useState(false);
  /** 模型设计面板 */
  const [openModalDesign, setDesignModalOpen] = useState(false);

  /** 打开模型弹窗*/
  const onDomainModalOpen = useCallback(
    ()=> setDomainModalOpen(false)
    ,[]
  );

  /** Table action 的引用，便于自定义触发 */
  const actionRef = useRef();

  /** 数据缓存*/
  const commonRef = useRef({
    domainSelect: {
      id:0,
      name:'模型信息'
    },
    modalSelect: {
      value:null,
      label:null,
    },
  });

  /** 关闭模型弹窗*/
  const onModalDesignClose = useCallback(
    ()=>{
      clear()
      commonRef.current.modelDetail=null;
      setDesignModalOpen(false);
    },[]
  )

  useEffect(() => {
    /** 获取主题域 */
    dispatch(getDomains());

    setColumns(
      columnsFactory({
        dataSource: baseColumns,
        onDelete:({id},reload)=> {
          dispatch(deleteModal({
            id,
            resolve(){
              console.log(reload)
              reload()
            }
          }))
        },
        onDetail:onModalDetail,
      })
    )
  }, [])

  /** 模型编辑 */
  const onModalDetail=useCallback(({id})=>{

    // 获取数据源
    dispatch(getDBSource());
    // 获取模型明细
    dispatch(getModalDetail({
      id,
      resolve(data){
        commonRef.current.modelDetail=data
        commonRef.current.modalSelect=modalTypeOption.find(item=>item.value === data.modelDetail.queryType);
        setDesignModalOpen(true);
      }
    }))
  },[])

  /** 选择创建模式 */
  const onModelSelect = useCallback((info) => {
    // 主题不能为空
    if (commonRef.current.domainSelect.id){
      // 获取数据源
      dispatch(getDBSource());
      setDesignModalOpen(true);
      commonRef.current.modalSelect=info
    }else {
      message.error("请先选择主题")
    }
  }, [modalTypeOption]);

  /** 侧边栏主题域钩子 */
  const onSelect = async (keys, info) => {
    const {node} = info;
    if (node?.children?.length === 0) {
      commonRef.current.domainSelect=node
      dispatch(getModals(node.id))
    }else {
      commonRef.current.domainSelect.id=0
    }
  };

  /** 主题域过滤 */
  const onSearch = (keys) => {
    console.log('onSearch', keys);
  };

  /** 主题域表单提交 */
  const domainFormSubmit = useCallback((values) => {
    const {parentId} = values;
    dispatch(createDomain({
      ...values,
      parentId: parentId ? parentId : 0
    }));
  },[]);

  /** 模型设计提交 */
  const onDesignFormFinish=useCallback((values)=>{
    const {modalSelect,domainSelect,modelDetail} = commonRef.current;
    if (domainSelect.id<=0){
      message.warning('未选择主题域')
      return false
    }
    const {modelType,classify,nodes,edges,tableName,bizName,name,description,dbSource,db,sqlStr} = values;
    console.log("values",values)
    // 多表之间的关联关系(仅快速创建模式使用)
    let joinRelations = [];
    let sqlRelation = ` FROM ${tableName} `;
    if (MODAL_TYPE.QUICK===modelType){
      // 快速创建-多表
      if (edges.length>0){
        for (const e in edges) {
          const edge = edges[e];
          const left = nodes.find(n=>`${n.tableName}.${n.fieldName}`===edge.source);
          const right = nodes.find(n=>`${n.tableName}.${n.fieldName}`===edge.target);
          const leftTable = left.tableName;
          const leftFields = left.fieldName;
          const rightTable = right.tableName;
          const rightFields = right.fieldName;
          // SQL连接关系拼接
          sqlRelation = sqlRelation + ` LEFT JOIN ${rightTable} ON ${edge.source}=${edge.target}`;
          joinRelations.push({
            left:leftTable,
            leftFields:[leftFields],
            right:rightTable,
            rightFields:[rightFields],
            type:'LeftJoin',
            conditions:[
              {
                left:leftFields,
                right:rightFields,
                operator: "IN",
              }
            ]
          });
        }
      }
    }

    if (MODAL_TYPE.SQL===modelType){
      const fromIndex = sqlStr.indexOf('FROM');
      sqlRelation = sqlStr.slice(fromIndex);
    }


    // 主键
    let identifiers = [];
    let dimensions = [];
    let measures = [];
    for (const c in classify) {
      const {data,value} = classify[c];
      if (value==="isKey"){
        console.log(data)
        identifiers = data.map(item=>({
          name: item.fieldName,
          type: DIM_TYPE_ENUM.IDENTIFY,
          bizName: `${bizName}_${item.bizName}`,
          isCreateDimension: 1
        }))
      }
      if (value==="datetime"){
        for (const i in data) {
          const item = data[i];
          dimensions.push({
            name: item.fieldName,
            type: DIM_TYPE_ENUM.DATETIME,
            bizName: `${bizName}_${item.bizName}`,
            isCreateDimension: 1,
            description: item.comment,
            typeParams: {
              isPrimary: true,
              timeGranularity: 'day'
            }
          })
        }
      }
      if (value==="common"){
        for (const i in data) {
          const item = data[i];
          dimensions.push({
            name: item.fieldName,
            type: DIM_TYPE_ENUM.CATEGORICAL,
            bizName: `${bizName}_${item.bizName}`,
            isCreateDimension: 1,
            description: item.comment
          })
        }
      }
      if (value==="measure"){
        measures = data.map(item=>({
          name: item.fieldName,
          agg: CALC_TYPE.SUM,
          expr: `${bizName}_${item.bizName}`,
          bizName: `${bizName}_${item.bizName}`,
          isCreateDimension: 1,
          alias: item.comment,
          constraint: ""
        }))
      }
    }
    // SQL字段拼接
    let sqlString = "SELECT "
    nodes.forEach((value,index)=>{
      if (index!==nodes.length-1){
        if (joinRelations.length>0){
          sqlString = `${sqlString} ${value.tableName}.${value.fieldName},`
        }else {
          sqlString = `${sqlString} ${value.tableName}.${value.fieldName} AS ${bizName}_${value.bizName},`
        }

      }else {
        if (joinRelations.length>0){
          sqlString = `${sqlString} ${value.tableName}.${value.fieldName} `
        }else {
          sqlString = `${sqlString} ${value.tableName}.${value.fieldName} AS ${bizName}_${value.bizName} `
        }

      }
    })
    const modalParams = {
      id:modelDetail?.id,
      databaseId: dbSource,
      dbName:db,
      domainId: domainSelect.id,
      alias: name,
      sourceType: modalSelect.label,
      name:name,
      bizName: bizName,
      description: description,
      typeEnum: TYPE_ENUM.MODEL,
      sensitiveLevel: 0,
      modelDetail: {
        sqlQuery:joinRelations.length>0 ? sqlString+sqlRelation : "",
        queryType: modalSelect.value,
        tableQuery: edges?.length===0 ? tableName :null,
        joinRelations: joinRelations,
        identifiers: identifiers,
        dimensions: dimensions,
        measures: measures,
        fields:nodes.map(value=>(
          {
            tableName:value.tableName,
            fieldName:value.fieldName,
            dataType:value.dataType,
            comment:value.comment,
            bizName:`${bizName}_${value.bizName}`
          }
        ))
      }
    }
    console.log(modalParams)
    if (modelDetail?.id){
      dispatch(updateModal({
        params:modalParams,
        resolve() {
          message.success('模型修改成功')
          clear()
          actionRef.current?.reload()
          commonRef.current.modelDetail=null;
        }
      }))
    }else {
      dispatch(createModal({
        params:modalParams,
        resolve() {
          message.success('模型创建成功')
          clear()
          actionRef.current?.reload();
          commonRef.current.modelDetail=null;
        }
      }))
    }
    setDesignModalOpen(false)
  },[])

  return (
    <>
      {/** 主题域编辑面板 */}
      <DomainForm
        open={domainModalOpen}
        onCancel={onDomainModalOpen}
        onFinish={domainFormSubmit}
      />
      {/** 模型设计面板 */}
      <ModalDesign
        open={openModalDesign}
        onCancel={onModalDesignClose}
        type={commonRef.current.modalSelect}
        initialValues={commonRef.current?.modelDetail}
        onFinish={onDesignFormFinish}
      />
      {/** 模型列表 */}
      <ProCard gutter={8} ghost>
        <ProCard
          bordered
          title="主题"
          colSpan="20%"
          headerBordered
          style={{height: '84vh'}}
          extra={
            <Button type="link" size="large" onClick={()=>setDomainModalOpen(true)}>+新增主题</Button>
          }
        >
          <TreeMenu treeData={domains} onSelect={onSelect} onSearch={onSearch} extra={<Checkbox>仅显示生效</Checkbox>}/>
        </ProCard>
        <ProCard bordered={false} bodyStyle={{padding: 0}}>
          <ProTable
            {...ProTableDefault}
            actionRef={actionRef}
            headerTitle={commonRef.current.domainSelect.name}
            columns={columns}
            dataSource={modals}
            pagination={{
              pageSize: 20,
              onChange: (page) => console.log(page),
            }}
            request={async ()=>{
              if (commonRef.current.domainSelect.id){
                await dispatch(getModals(commonRef.current.domainSelect.id))
              }
            }}
            toolBarRender={() => [
              <SelectModal description="请选择模型创建方式" title="创建模式" options={modalTypeOption} onSelect={onModelSelect}/>
            ]}
          />
        </ProCard>
      </ProCard>
    </>
  );
};
