import {useAppDispatch, useAppSelector} from "../../../redux/configureStore";
import {selectDataSet, selectModals} from "../MainPage/slice/selectors";
import {useCallback, useMemo, useRef, useState} from "react";
import {
  createDataSet, deleteDataSet,
  getAllDataset,
  getDomains,
  getModalInfo,
  getModals, queryDataSet
} from "../MainPage/slice/thunks";
import {ProCard} from "@ant-design/pro-components";
import {CheckCardList} from "../../components/CheckCardList";
import {Select, Space, Table, Tabs, Input, Button} from "antd";
import {WorkFlowPanel} from "../../components/WorkFlow";
import {useWorkFlow} from "../../hooks/useWorkFlow";
import {FilterPanel} from "../../components/FilterPanel";
import {DatasetForm} from "./components/DatasetForm";
import {WORKFLOW_DEFAULT_STYLE} from "../../components/WorkFlow/constants";
import useMount from "../../hooks/useMount";
import {FORM_TYPE} from "../IndexDefine/constants";
import {TYPE_ENUM} from "../../constants";
import {MarkerType} from "@xyflow/react";

const {Search} = Input;

export const IndexDataSet = () => {
  const dispatch = useAppDispatch();
  const {
    getNodesState,
    getEdgesState,
    updateNodesState,
    updateEdgesState,
    modalToNodes,
    clear
  } = useWorkFlow();
  const dataset = useAppSelector(selectDataSet);
  const modals = useAppSelector(selectModals);
  /** 创建数据集窗口状态 */
  const [open, setOpen] = useState(false);
  /** 创建数据集临时数据 */
  const [temps, setTemps] = useState([]);
  /** 选择的模型 */
  const selected = useRef([]);
  /** 选择的数据集*/
  const [record,setRecord] = useState({});
  /** 表头及数据 */
  const [queryData,setQueryData] = useState({});

  useMount(
    () => {
      dispatch(getDomains())
      dispatch(getAllDataset({}))
    },
    () => {
      clear()
    }
  )

  const cardList = useMemo(
    () => [...dataset, ...temps].map(value => ({value, title: value.name,}))//.concat({value: {id: 10, domainId: 10}, title: '测试数据集'})
    , [dataset, temps]
  );

  /** 选中数据集卡片时取数据并渲染WorkFlow */
  const onCardSelect = useCallback((value) => {
    if (value) {
      // 选中的模型
      selected.current=value.allModels

      // 缓存点击的数据
      setRecord(value)

      // 获取模型信息
      dispatch(getModals(value.domainId))

      if (value.id){
        // 获取数据集详情-回显
        const {allModels,modelRelas,dataSetDetail}=value;
        const fieldsCheck = dataSetDetail?.dataSetModelConfigs;

        // 循环到最后一次时插入节点
        let initNodes = [];
        allModels.forEach((id,index)=>{
          dispatch(getModalInfo({
            id,
            resolve:(data)=> {
              initNodes = [...initNodes,...modalToNodes(data,index+1,fieldsCheck)]
              if (allModels.length===index+1){
                setTimeout(()=>{
                  updateNodesState(initNodes)
                },100)
              }
            }
          }))
        })

        // 插入关系节点
        let initEdges=[];
        modelRelas.map(rel=>{
          const {fromModelId,toModelId,joinConditions}=rel;
          const {leftField,rightField} = joinConditions[0];
          initEdges = [...initEdges,{
            id:`xy-edge__${fromModelId}.${leftField}-${toModelId}.${rightField}`,
            style: {strokeWidth: 2, stroke: 'black'},
            type: 'smoothstep',
            markerEnd: {
              type: MarkerType.ArrowClosed,
              color: 'black',
            },
            source: leftField,
            target: rightField
          }]
          updateEdgesState(initEdges);
        })
      }else {
        clear()
      }
    }
  }, [getNodesState,getEdgesState])

  /** 数据预览筛选条件回调 */
  const onChange = useCallback((key) => {
    console.log(key);
  }, [])

  /** 选择模型回调*/
  const onSelectModal = useCallback((id) => {
    // 获取模型明细
    dispatch(getModalInfo({
      id,
      resolve(data) {
        updateNodesState([
          ...getNodesState,
          ...modalToNodes(data, selected.current.length)
        ])
      }
    }))
  }, [getNodesState])

  /** 取消选择模型回调-删除节点*/
  const onDeselectModal = useCallback((modalId) => {
    // 删除节点
    const filterNodes = getNodesState.filter(
      node => !(
        node.id === `${modalId}` ||
        node.parentId === `${modalId}`
      )
    );
    updateNodesState(filterNodes)

    // 删除连接线
    const remove = getNodesState.filter(node =>
      !(node.id === `modal_${modalId}` || node.parentId === `modal_${modalId}`)
    );
    const difference = getEdgesState.filter(item =>
      !remove.some(del =>
        !(item.target === del.id || item.source === del.id)
      )
    );
    updateEdgesState(difference)
  }, [getNodesState, getEdgesState])

  /** 模型列表 */
  const memoModals = useMemo(() =>
    modals.map(item => ({
      label: item.name,
      value: item.id,
    }))
    , [modals]
  )

  /** 保存数据集*/
  const onDatasetSave = useCallback(() => {
    // 模型显示字段
    const displayNodes = getNodesState.filter(node => node.data.checked)
    const dataSetModelConfigs = getNodesState
      .filter(node => node.type==='table')
      .map(node => ({
        id: parseInt(node.id),
        includesAll: true,
        metrics:displayNodes
          .filter(
            metrics =>
              node.id===metrics.parentId &&
              FORM_TYPE[metrics.data.type]
          ).map(item => item.data.id),
        dimensions:displayNodes
          .filter(
            metrics =>
              node.id===metrics.parentId &&
              !FORM_TYPE[metrics.data.type]
          ).map(item => item.data.id),
      }))
    // 模型连接关系
    const modelRela = getEdgesState.map(edge => {
      const formModal = getNodesState.find(node => node.id === edge.source);
      const toModal = getNodesState.find(node => node.id === edge.target);
      return {
        domainId: record.domainId,
        fromModelId: parseInt(formModal.parentId),
        toModelId: parseInt(toModal.parentId),
        joinType: "LEFT",
        joinConditions: [
          {
            leftField: edge.source,
            rightField: edge.target,
            operator: "IN"
          }
        ],
        createdBy: "admin",
        updatedBy: "admin",
        createdAt: "2024-08-13T02:40:17.000+00:00",
        updatedAt: "2024-08-13T02:40:17.000+00:00"
      }
    })

    const params = {
      id: record.id,
      name: record.name,
      bizName: record.bizName,
      description: record.description,
      status: 1,
      typeEnum: "DATASET",
      sensitiveLevel: 0,
      createdBy: "admin",
      updatedBy: "admin",
      createdAt: "2024-08-13T02:40:17.000+00:00",
      updatedAt: "2024-08-13T02:40:17.000+00:00",
      domainId: record.domainId,
      dataSetDetail: {
        dataSetModelConfigs
      },
      modelRela: modelRela,
      alias: record.name,
      queryConfig: {
        metricTypeDefaultConfig: {
          timeDefaultConfig: {
            unit: 365,
            period: "day",
            timeMode: "LAST"
          }
        }
      },
    }
    console.log(params)
    dispatch(createDataSet({
      params,
      resolve() {
        setTemps([])
        dispatch(getAllDataset({}))
      }
    }))
  },[getNodesState,getEdgesState])

  /** 查询数据集结果 */
  const onFilterChange =useCallback((value)=>{
    console.log(value)
    const dimensionFilters = value.tags.map(tag => {
      const dimensionObj = JSON.parse(tag.dimension)
      return {
        id: tag.value,
        relation: "FILTER",
        bizName: dimensionObj.bizName,
        name: tag.bizName,
        operator: tag.condition,
        value: tag.keyword,
        children: []
      }
    })
    const params = {
      limit: 50,
      sql: "",
      queryType: "DETAIL",
      dataSetId: record.id,
      dataSetName: record.name,
      dateInfo: {
        dateMode: "BETWEEN",
        startDate: "2024-01-01",
        endDate: "2024-09-01",
        dateList: [],
        unit: 0,
        period: 'day',
        detectWord: "",
        isInherited: false,
        groupByDate: false
      },
      dimensionFilters,
      needAuth: false,
      groups: value.dimension.map(item=>item.bizName),
      aggregators:value.metric.map(item=>({
        column: item.bizName,
        func: "SUM",
        nameCh: "",
        args: [],
        alias: item.label
      })),
      orders: [],
      params: [],
      cacheInfo: {
        cache: false
      },
      metricFilters: [],
    }
    dispatch(queryDataSet({
      params,
      resolve(data) {
        setQueryData(data)
      }
    }))
  },[record])

  const options = useMemo(()=>{
    const {dimensionList,metricList}=record;
    const dimension = (dimensionList||[]).map(v=>({
      label:v.description||v.name,
      value:v.id,
      bizName:v.bizName,
      type:TYPE_ENUM.DIMENSION
    }))
    const metric = (metricList||[]).map(v=>({
      label:v.description||v.name,
      value:v.id,
      bizName:v.bizName,
      type:TYPE_ENUM.METRIC
    }))
    return {dimension,metric}
  },[record])

  /** 标签页选项 */
  // const items = useMemo(() => [], [queryData,record,modals, getNodesState,getEdgesState]);

  /** 创建临时数据集 */
  const handleDatasetFinish = useCallback((value) => {
    dispatch(getModals(value.domainId))
    setTemps(pre => pre.concat(value))
    setOpen(false)
  }, [])

  const openForm = useCallback(() => setOpen(true), [])
  const closeForm = useCallback(() => setOpen(false), [])

  /** 删除数据集 */
  const onDeleteDataset = useCallback((event,item) => {
    const {id} = item.value;
    if (id){
      // 删除数据
      dispatch(deleteDataSet({
        id,
        resolve(){
          dispatch(getAllDataset({}))
        }
      }))
    }else {
      // 清除临时创建记录
      setTemps([])
    }

  },[])

  return (
    <ProCard gutter={8} ghost>
      <ProCard
        bordered
        headerBordered
        colSpan="20%"
        title="数据集"
        style={{height: '85vh'}}
        extra={
          <Button type="link" size="large" onClick={openForm}>+新增数据集</Button>
        }
      >
        <DatasetForm open={open} onFinish={handleDatasetFinish} onCancel={closeForm}/>
        <CheckCardList
          options={cardList}
          onSelect={onCardSelect}
          actions={{
            items: [{label: '删除', key: '1'}],
            onClick: onDeleteDataset
          }}
        />
      </ProCard>
      <ProCard bordered bodyStyle={{padding: '0 20px 0 20px', height: '84vh'}}>
        <Tabs
          size='large'
          defaultActiveKey="1"
          onChange={onChange}
          items={
            [
              {
                key: '1',
                label: '数据集设计',
                children: <>
                  <Space style={{marginBottom: 10}}>
                    <Search placeholder="搜索关键字" style={{width: 300}}/>
                    <Select
                      mode="multiple"
                      style={{width: 400}}
                      maxTagCount='responsive'
                      placeholder="请选择模型"
                      onSelect={onSelectModal}
                      onDeselect={onDeselectModal}
                      value={selected.current}
                      onChange={(e) => selected.current=e}
                      options={memoModals}
                    />
                  </Space>
                  <Space style={{float: 'right'}}>
                    <Button>授权</Button>
                    <Button onClick={onDatasetSave}>保存</Button>
                    <Button type="primary" style={{backgroundColor: '#fa541c', width: 100}}>发布</Button>
                  </Space>
                  <WorkFlowPanel
                    {...WORKFLOW_DEFAULT_STYLE}
                    style={{height: '74vh'}}
                    initialNodes={getNodesState}
                    initialEdges={getEdgesState}
                  />
                </>,
              },
              {
                key: '2',
                label: '预览',
                children: (
                  <FilterPanel
                    delay={1000}
                    options={options}
                    onChange={onFilterChange}
                    viewer={
                      <Table
                        columns={
                          (queryData?.columns||[]).map(item=>({
                            title: item.name,
                            dataIndex: item.nameEn,
                            key: item.nameEn,
                          }))
                        }
                        dataSource={queryData?.resultList}
                      />
                    }
                  />
                ),
              },
            ]
          }
        />
      </ProCard>
    </ProCard>
  )
}