import {memo, forwardRef, useRef, useCallback, useEffect} from 'react';
import {Button, Card, Drawer, message} from "antd";
import {
  ProForm,
  ProFormDatePicker,
  ProFormTimePicker,
  ProFormGroup,
  ProFormText,
  ProFormRadio,
  ProFormDependency,
  ProFormTreeSelect,
  ProFormSelect, ProFormTextArea
} from "@ant-design/pro-components";
import {AtomicIndexForm} from "./AtomicIndexForm";
import {FORM_TYPE, INDEX_TYPE, INVOKE_TYPE, PERSISTENCE_WAY, SENSITIVE, TIME_MODE, CONFIRM_STATUS} from "../constants";
import {DerivedIndexForm} from "./DerivedIndexForm";
import {CompositeIndexForm} from "./CompositeIndexForm";
import {useAppDispatch, useAppSelector} from "../../../../redux/configureStore";
import {selectDomains, selectPeriods} from "../../MainPage/slice/selectors";
import {createCondition, getConditions, getModals, getPersistenceConfig, periodList} from "../../MainPage/slice/thunks";
import {styled} from "styled-components";
import useI18NPrefix from "../../../hooks/useI18NPrefix";
import {bizConditionToSQL} from "../../../../utils/listTools";
import {pinyin} from "pinyin-pro";

const formLayoutType = "horizontal";
const pickerWidth = 390;

const component = forwardRef(({
  onFinish,
  initialValues,
  open,
  handleCancel,
}, ref) => {
  const t = useI18NPrefix('global');
  const dispatch = useAppDispatch()
  const domains = useAppSelector(selectDomains);
  const periods = useAppSelector(selectPeriods);
  const formRef = useRef(null);
  const compositeRef = useRef(null);

  useEffect(() => {
    dispatch(periodList({}));

    const {domainId,id} = initialValues;
    if (domainId){
      dispatch(getModals({domainId}));
    }
    if (id){
      dispatch(getPersistenceConfig({
        id,
        resolve(data){
          if (data){
            const defaultConfig = JSON.parse(data.defaultConfig)
            formRef.current?.setFieldsValue({
              invokeMethod:defaultConfig?.type || 'AUTO',
              runCycleCode:data?.runCycleCode,
              unit:defaultConfig?.unit,
              way:defaultConfig?.way,
              startTime:defaultConfig?.startTime,
              incrementPeriod:defaultConfig?.period,
              syncToBI:defaultConfig?.syncToBI,
            })
          }
        }
      }))
      if (initialValues?.expr && initialValues?.metricDefineType === "CUSTOM"){
        const expr = initialValues?.metricDefineByFieldParams?.expr
        const fields = initialValues?.metricDefineByFieldParams?.fields
        compositeRef.current = {
          expr,
          metrics:(fields||[]).map(item=>({bizName:item.fieldName})),
        }
      }
      if (initialValues?.expr && initialValues?.metricDefineType === "METRIC"){
        compositeRef.current = initialValues?.metricDefineByMetricParams
      }
    }
  }, [open,initialValues]);

  /** 主题域选择回调 */
  const handelDomainSelect =useCallback((value)=>{
    dispatch(getModals({domainId:value}));
    formRef.current?.resetFields(['modelId']);
  },[]);

  /** 切换模型时清空子数据 */
  const onFieldChange = useCallback(()=>{
    formRef.current?.resetFields([
      'measure',
      'dateDimId',
      'relateDimension',
      'formIndex',
      "attributes",
      "filters"
    ])
  },[]);

  /** 业务限定保存 */
  const onConditionSave=useCallback(async (tab,txt)=>{
    const formatValue = await formRef.current?.validateFieldsReturnFormatValue?.();
    // 组织数据
    const {filters,name,domainId,modelId} = formatValue;
    if (!domainId) {
      message.error("请先选择主题")
      return false
    }
    if (!modelId) {
      message.error("请先选择模型")
      return false
    }
    const defaultConfig = (tab==='customScript') ? txt : bizConditionToSQL(filters);

    if (defaultConfig){
      const params = {
        status:1,
        defaultConfig,
        name,
        modelId,
        domainId
      }
      dispatch(createCondition({
        params,
        resolve(){
          message.success(t("validation.success"))
          dispatch(getConditions({}))
        }
      }))
    }else {
      const errorMessage = (tab==='customScript') ? '请先编辑脚本' :'请先配置字段'
      message.error(errorMessage)
    }
  },[])

  const handleCreatorFinish=(val)=>{
    const { modelId, dateDimId, dimensionIds } = val;
    let composite = compositeRef.current || '';
    if(val.type == "COMPOSITE") {
      val.dimensionId = '';
      val.dateDimId = '';
      val.modelId = Array.isArray(modelId) ? modelId[0] : modelId;
      const metrics = [];
      composite.metrics.forEach((v, i) =>{
        delete v.dateArr;
        delete v.analyzeArr,
        metrics.push({
          ...v,
          dateDimId: dateDimId[i] || '',
          dimensionIds: dimensionIds[i],
        });
      });
      composite = {
        ...composite,
        metrics,
      }
    }
    onFinish({
      id:initialValues?.id || null,
      domainId:initialValues?.domainId,
      ...val,
      conditionId:val?.conditionId || null,
      metricDefineByMetricParams: composite,
      measureExpr:composite,
    })
  }

  // 当名称改变时自动填充业务限定编码为中文首字母
  const onNameChange =(event)=>{
    const py = pinyin(event?.target?.value, { toneType: "none", type: "array" });
    let bizCode = "";
    py.forEach(p=>bizCode+=p[0].toUpperCase());
    formRef?.current?.setFieldValue('bizName',"BIZ_"+bizCode);
  }

  const onSetFields=useCallback((f,v)=> {
    formRef?.current?.setFieldValue(f,v)
  },[])

  return (
    <Drawer
      title={t(initialValues?.id?"title.metricUpdate":"title.metricCreate")}
      width={1230}
      styles={{body:{padding:'0'}}}
      open={open}
      maskClosable={false}
      destroyOnClose
      onClose={handleCancel}
      footer={[
        <Button key="previewer" style={{marginLeft:'40%'}} onClick={handleCancel} disabled={!initialValues?.id}>
          {t("button.preview")}
        </Button>,
        <Button key="upload" style={{marginLeft:15}} onClick={handleCancel} disabled={!initialValues?.id}>
          {t("button.publish")}
        </Button>,
        <Button key="submit" style={{marginLeft:15}} type="primary" onClick={()=>{formRef?.current?.submit()}}>
          {t("button.save")}
        </Button>
      ]}
    >
      <ProForm
        formRef={formRef}
        layout={formLayoutType}
        initialValues={initialValues}
        onFinish={handleCreatorFinish}
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 18 }}
        submitter={false}
      >
        {/** 指标通用字段 */}
        <Card type="inner" title={t("title.baseInfo")} bordered={false}>
          <ProFormRadio.Group
            name="type"
            label={t("formItem.metricType")}
            rules={[{ required: true }]}
            valueEnum={INDEX_TYPE}
            fieldProps={{
              onChange(){
                formRef.current?.resetFields(['modelId'])
              }
            }}
          />
          <ProFormRadio.Group
            name="sensitiveLevel"
            label={t("formItem.sensitiveLevel")}
            rules={[{ required: true }]}
            valueEnum={SENSITIVE}
          />
          <ProFormText
            name="name"
            label={t("formItem.metricName")}
            rules={[{ required: true }]}
            fieldProps={{
              onChange:onNameChange
            }}
          />
          <ProFormText
            name="description"
            label={t("formItem.metricDesc")}
          />
          <ProFormText
            name="bizName"
            label={t("formItem.bizName")}
            rules={[{ required: true }]}
          />
          <ProFormTreeSelect
            name="domainId"
            label={t("formItem.domain")}
            rules={[{ required: true }]}
            request={async ()=>domains}
            fieldProps={{
              onSelect:handelDomainSelect
            }}
          />
          <ProFormTextArea
            name="alias"
            label={t("formItem.caliber")}
            rules={[{ required: true }]}
          />
          <ProFormText
            name="director"
            label={t("formItem.director")}
            rules={[{ required: true }]}
          />
          <ProFormGroup style={{marginLeft:115}}>
            <ProFormDatePicker name="createdAt" label={t("formItem.startDate")} rules={[{ required: true }]} width={pickerWidth} initialValue={initialValues?.createdAt || new Date}/>
            <ProFormDatePicker name="stopDate" label={t("formItem.stopDate")} width={pickerWidth}/>
          </ProFormGroup>
        </Card>
        <Card bordered={false} type="inner" title={t("title.metricDefine")} style={{boxShadow:'none'}}>
          <ProFormDependency name={["type"]}>
            {({ type }) => {
              switch (type) {
                case FORM_TYPE.ATOMIC.value:
                  return <AtomicIndexForm initialValues={initialValues} onChange={onFieldChange} onExprChange={expr=>compositeRef.current=expr}/>
                case FORM_TYPE.DERIVED.value:
                  return <DerivedIndexForm initialValues={initialValues} onSetField={onSetFields} onExprChange={expr=>compositeRef.current=expr} onChange={onFieldChange} onConditionSave={onConditionSave}/>
                case FORM_TYPE.COMPOSITE.value:
                  return <CompositeIndexForm initialValues={initialValues} onChange={expr=>compositeRef.current=expr}/>
                default : return null
              }
            }}
          </ProFormDependency>
          <ProFormSelect
            name="periodId"
            label={t("formItem.period")}
            options={periods.map(item=>({label:item.name,value:item.id}))}
            rules={[{ required: true }]}
          />
          <ProFormRadio.Group
            name="invokeMethod"
            label={t("formItem.invokeMethod")}
            valueEnum={INVOKE_TYPE}
          />
          <ProFormDependency name={["invokeMethod"]}>
            {
              ({ invokeMethod }) =>
                invokeMethod==='MANUAL' && <>
                  <Wrapper>
                    <Title className="divider"> {t("title.invokeRule")} </Title>
                  </Wrapper>
                  <ProFormSelect
                    name="incrementPeriod"
                    label={t("formItem.incrementPeriod")}
                    valueEnum={TIME_MODE}
                    rules={[{ required: true }]}
                  />
                  <ProFormSelect
                    name="runCycleCode"
                    label={t("formItem.runCycle")}
                    valueEnum={TIME_MODE}
                    rules={[{ required: true }]}
                  />
                  <ProFormTimePicker name="startTime" width="100%" label={t("formItem.startTime")} initialValue={initialValues?.startTime}/>
                  <ProFormRadio.Group
                    name="way"
                    label={t("formItem.invokeWay")}
                    initialValue={initialValues?.syncToBI || 'INC'}
                    options={PERSISTENCE_WAY}
                    rules={[{ required: true }]}
                  />
                  <ProFormRadio.Group 
                    name="syncToBI"
                    label={t("formItem.syncToBI")}
                    options={CONFIRM_STATUS}
                    initialValue={initialValues?.syncToBI || 0}
                    rules={[{ required: true }]}
                  />
                </>
            }
          </ProFormDependency>

        </Card>
      </ProForm>
    </Drawer>
  )
})
export const IndexCreator = memo(component);

const Wrapper = styled.div`
  width: 100%;
  display: flex;
  align-items: center;
  box-sizing: border-box;
`

const Title = styled.div`
  display: inline-block;
  flex: 1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  box-sizing: border-box;
  text-align: center;
  font-weight: 600;
  padding-block-end: 10px;
  &.divider {
    // 添加必填红色*的样式
    &::before {
      display: inline-block;
      margin-inline-end: 4px;
      color: #bfbfbf;
      font-size: 16px;
      line-height: 1;
      content: "------------------";
    }
    &::after {
      display: inline-block;
      margin-inline-start: 4px;
      color: #bfbfbf;
      font-size: 16px;
      line-height: 1;
      content: "------------------";
    }
  }
`