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, updateDataSet
} from "../MainPage/slice/thunks";
import {ProCard} from "@ant-design/pro-components";
import {CheckCardList} from "../../components/CheckCardList";
import {Select, Space, Tabs, Input, Button, message} 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";
import moment from "moment/moment";
import useI18NPrefix from "../../hooks/useI18NPrefix";

const {Search} = Input;

export const IndexDataSet = () => {
  const t = useI18NPrefix('global');
  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 [queryData,setQueryData] = useState({});
  /** 数据加载中 */
  const [loading, setLoading] = useState(false);
  /** 缓存的数据集 */
  const recordRef = useRef(null)
  /** options*/
  const [options,setOption] = useState([])
  useMount(
    () => {
      dispatch(getDomains())
      dispatch(getAllDataset({}))
    },
    () => {
      clear()
    }
  )

  const cardList = useMemo(
    () => [...dataset, ...temps].map(value => ({value, title: value.name,}))
    , [dataset, temps]
  );

  /** 结果预览面板初始化 */
  const initFilterPanel=(value)=>{
    const {dimensionList,metricList} = value;
    const dimension = (dimensionList||[])
      // .filter(v=>v?.type!==DIM_TYPE_ENUM.DATETIME)
      .map(v=>({
        label:v.description||v.name,
        value:v.id,
        bizName:v.bizName,
        semanticType:v.semanticType,
        type:TYPE_ENUM.DIMENSION
      }))
    const metric = (metricList||[]).map(v=>({
      label:v.description||v.name,
      value:v.id,
      bizName:v.bizName,
      type:TYPE_ENUM.METRIC
    }))

    setOption({dimension,metric})
  }

  /** 选中数据集卡片时取数据并渲染WorkFlow */
  const onCardSelect = useCallback((value) => {
    if (value) {
      // 缓存点击的数据
      recordRef.current=value

      initFilterPanel(value)

      // 获取模型信息
      dispatch(getModals({
        domainId:value.domainId,
        resolve(){
          // 选中的模型回显
          selected.current=value.allModels
        }
      }))

      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(() => {}, [])


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

  /** 选择模型回调*/
  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 = (update) => {
    const record = recordRef.current;
    // 模型显示字段
    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),
      }))

    // 必须选择维度
    let dimLen = 0
    dataSetModelConfigs.forEach(item => {
      dimLen = dimLen + item?.dimensions?.length
    })
    if (dimLen<1){
      message.error("共同维度不能为空")
      return false
    }
    // 模型连接关系
    // const modelRela = getEdgesState.map(edge => {
    //   console.log(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 = {
      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: [],
      alias: record.name,
      queryConfig: {
        metricTypeDefaultConfig: {
          timeDefaultConfig: {
            unit: 365,
            period: "day",
            timeMode: "LAST"
          }
        }
      },
    }

    if (update && update?.id){
      dispatch(updateDataSet({
        params:{
          ...params,
          id: update.id,
          name: update.name,
          bizName: update.bizName,
          description: update.description,
          domainId: update.domainId,
          alias: update.name,
        },
        resolve(data) {
          recordRef.current=data
          setTemps([])
          message.success("修改成功")
          dispatch(getAllDataset({}))
          initFilterPanel(data)
        }
      }))
    }else {
      dispatch(createDataSet({
        params,
        resolve(data) {
          recordRef.current=data
          setTemps([])
          message.success("保存成功")
          dispatch(getAllDataset({}))
          initFilterPanel(data)
        }
      }))
    }

  }

  /** 查询数据集结果 */
  const onFilterChange =async ({days, dimension,metric, tags})=>{
    setLoading(true)
    const record = recordRef.current
    const groups = (dimension||[]).filter(item=>item.semanticType!=='DATE').map(item=>item.bizName);
    let dateInfo = {
      dateMode: "BETWEEN",
      startDate: moment().subtract(days ? days : 0, 'days').format('YYYY-MM-DD'),
      endDate: moment().format('YYYY-MM-DD'),
      dateList: [],
      unit: 0,
      period: 'day',
      detectWord: "",
      isInherited: false,
      groupByDate: groups.length<dimension?.length
    }
    let dimensionFilters = [];
    (tags||[]).forEach(tag=>{
      const dimensionObj = JSON.parse(tag.dimension);
      if (dimensionObj.semanticType!=="DATE"){
        dimensionFilters.push({
          id: tag.value,
          relation: "FILTER",
          bizName: dimensionObj.bizName,
          name: tag.bizName,
          operator: tag.condition,
          value: tag.keyword,
          semanticType: dimensionObj.semanticType,
          children: []
        })
      }else {
        dateInfo = {
          dateMode: "BETWEEN",
          startDate: tag.startDate,
          endDate: tag.endDate,
          dateList: [],
          unit: 0,
          period: 'day',
          detectWord: "",
          isInherited: false,
          groupByDate: true
        }
      }
    })
    const params = {
      limit: 10000,
      sql: "",
      queryType: "DETAIL",
      dataSetId: record.id,
      dataSetName: record.name,
      dateInfo,
      dimensionFilters,
      needAuth: false,
      groups,
      aggregators:(metric||[]).map(item=>({
        column: item.bizName,
        func: "SUM",
        nameCh: "",
        args: [],
        alias: item.label
      })),
      orders: [],
      params: [],
      cacheInfo: {
        cache: false
      },
      metricFilters: [],
    }
    await dispatch(queryDataSet({
      params,
      resolve(data) {
        setQueryData(data)
      }
    }))
    setLoading(false)
  }

  // const options = useMemo(()=>{
  //   const {dimensionList,metricList}=record;
  //   const dimension = (dimensionList||[])
  //     // .filter(v=>v?.type!==DIM_TYPE_ENUM.DATETIME)
  //     .map(v=>({
  //       label:v.description||v.name,
  //       value:v.id,
  //       bizName:v.bizName,
  //       semanticType:v.semanticType,
  //       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 = (value) => {
    if (value?.id){
      onDatasetSave(value)
    }else {
      dispatch(getModals({domainId:value.domainId}))
      setTemps(pre => pre.concat(value))
      onCardSelect(value)
      setOpen(false)
    }
  }

  const openForm = useCallback(() => {
    recordRef.current=null
    setOpen(true)
  }, [])
  const closeForm = useCallback(() => {
    recordRef.current=null
    setOpen(false)
  }, [])

  /** 删除数据集 */
  const onDeleteDataset = useCallback((event,item) => {
    const {id} = item.value;
    if (id){
      if (event.key==='delete'){
        // 删除数据
        dispatch(deleteDataSet({
          id,
          resolve(){
            dispatch(getAllDataset({}))
            recordRef.current=null
            clear()
          }
        }))
      }

      if (event.key==='edit'){
        onCardSelect(item.value)
        setOpen(true)
      }
    }

    if (!id && event.key==='delete'){
      // 清除临时创建记录
      setTemps([])
      recordRef.current=null
    }

  },[])

  return (
    <ProCard gutter={8} ghost>
      <ProCard
        bordered
        headerBordered
        colSpan="20%"
        title={t("title.dataset")}
        style={{height: '85vh'}}
        extra={
          <Button type="link" size="large" onClick={openForm}>+{t("title.datasetCreate")}</Button>
        }
      >
        <DatasetForm initialValues={recordRef.current} open={open} onFinish={handleDatasetFinish} onCancel={closeForm}/>
        <CheckCardList
          value={recordRef.current}
          options={cardList}
          onSelect={onCardSelect}
          actions={{
            items: [{label: t("button.delete"), key: 'delete'},{label: t("button.edit"), key: 'edit'}],
            onClick: onDeleteDataset
          }}
        />
      </ProCard>
      <ProCard bordered bodyStyle={{padding: '0 20px 0 20px', height: '84vh'}} style={{height: '85vh'}}>
        <Tabs
          size='large'
          defaultActiveKey="1"
          onChange={onChange}
          items={
            [
              {
                key: '1',
                label: t("title.datasetDesign"),
                children: <>
                  <Space style={{marginBottom: 10}}>
                    <Search placeholder={t("placeholder.keyword")} style={{width: 300}}/>
                    <Select
                      style={{width: 400}}
                      placeholder={t("placeholder.model")}
                      value={selected.current}
                      onChange={onChangeModal}
                      options={memoModals}
                    />
                    {/*<Select*/}
                    {/*  mode="multiple"*/}
                    {/*  style={{width: 400}}*/}
                    {/*  maxTagCount='responsive'*/}
                    {/*  placeholder={t("placeholder.model")}*/}
                    {/*  onSelect={onSelectModal}*/}
                    {/*  onDeselect={onDeselectModal}*/}
                    {/*  value={selected.current}*/}
                    {/*  onChange={(e) => selected.current=e}*/}
                    {/*  options={memoModals}*/}
                    {/*/>*/}
                  </Space>
                  <Space style={{float: 'right'}}>
                    <Button>{t("button.auth")}</Button>
                    <Button onClick={()=>onDatasetSave(recordRef.current)}>{t("button.save")}</Button>
                    <Button type="primary" style={{backgroundColor: '#fa541c', width: 100}}>{t("button.publish")}</Button>
                  </Space>
                  <WorkFlowPanel
                    {...WORKFLOW_DEFAULT_STYLE}
                    style={{height: '74vh'}}
                    initialNodes={getNodesState}
                    initialEdges={getEdgesState}
                  />
                </>,
              },
              {
                key: '2',
                label: t("title.preview"),
                children: (
                  <FilterPanel
                    delay={1000}
                    options={options}
                    onChange={onFilterChange}
                    loading={loading}
                    dataSource={queryData}
                    requires={['metric']}
                  />
                ),
              },
            ]
          }
        />
      </ProCard>
    </ProCard>
  )
}