<template>
   <div class="m-4 mr-0 overflow-hidden bg-white" style="width:60%">
    <a-row :gutter="10" style="margin-top:15px;padding: 1px;height: 36px;" >
          <a-col :lg="17">
              <BasicForm @register="registerForm"/> 
          </a-col>
          <a-col :lg="7">
              <a-space :size="5">
                <a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery" >查询</a-button>
                <a-button type="primary" preIcona="nt-design:reload-outlined" @click="searchReset" >重置</a-button>
              </a-space>
          </a-col>
    </a-row>
    <a-divider style="border-color: #7cb305" dashed />
    <a-tabs v-model:activeKey="activeKey" @change="tabChange" class="m-4 mr-0 overflow-hidden bg-white" style="width:100%;margin:10px 20px">
      <a-tab-pane key="tableList" tab="列表" style="width:100%">
          <BasicTable @register="registerTable">
            <template #bodyCell="{ column, record }">
              <template v-if="column.key == 'riskLevel'">
                      <a-badge color="#A9A9A9" status="default" v-if="!record.riskLevel" text="其他 "/>
                      <a-badge status="success" v-else-if="record.riskLevel==1" text="低风险"/> 
                      <a-badge status="processing" v-else-if="record.riskLevel==2" text="中风险"/> 
                      <a-badge status="error"  v-else text="高风险"/> 
                </template>
              </template>
          </BasicTable>   
        </a-tab-pane>
        <a-tab-pane key="chartLine" tab="曲线图" force-render>
          <div ref="chartRef" :style="{ height, width }"></div>
        </a-tab-pane>  
    </a-tabs>
  </div>
</template>
<script lang="ts" setup>
import { Ref,ref,unref,watch,defineProps,reactive,toRaw,onMounted} from 'vue';
import { queryAllList} from './MetricReport.api';
import { columnsreport,searchFormSchema } from './MetricReport.data';
import {BasicForm, useForm} from '/@/components/Form/index';
import {BasicTable, useTable} from '/@/components/Table';
import { useECharts } from '/@/hooks/web/useECharts';

const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);

const [registerForm, {setFieldsValue,getFieldsValue}] = useForm({
    //labelWidth: 150,
    schemas: searchFormSchema,
    showActionButtonGroup: false,
    baseColProps: {span: 24}
});

const activeKey = ref('chartLine');

const yMax = ref<Number>();
const yMin = ref<Number>();

const  interval = ref<Number>();

const  serialNames=ref<String[]>([]);

const dataList = ref([])
const props = defineProps({
  data: { require: true, type: Object },
  width: {
    type: String as PropType<string>,
    default: '100%',
  },
  height: {
    type: String as PropType<string>,
    default: 'calc(70vh - 50px)',
  },
});

function tabChange(key) {
  activeKey.value = key;
  if(key=='chartLine') {
    setChart()
  } else {
    //setData()
  }
}

let metricObj = ref()
async function setData() {
    dataList.value = [] 
    metricObj.value = props.data
    if(!props.data) {
      tabChange("tableList");
      setChart();
      return false
    }
    let srhVals = getFieldsValue();
    if(metricObj.value&&metricObj.value.mtrcCtp) {
      if(metricObj.value.mtrcCtp*1==1){
          srhVals['mtrcNos'] = metricObj.value.mtrcNo
          queryAllList(srhVals).then((res) => {
            for(let i=0;i<res.dataList.length;i++){
              let tmp = res.dataList[i]['fillTime']
              res.dataList[i]['fillTime'] = getTimeStr(tmp)
            }
            dataList.value = res.dataList
            //yMax.value = res.dataList[res.dataList.length-1].fillVals
            //yMin.value = res.dataList[0].fillVals
            setYMaxMin()
            tabChange("chartLine");
          })
      } else {
        setCombinData()
      }
    } 
}

function searchQuery(){
  setData()
}
function searchReset(){
    reload();
}

function setCombinData() {
  let params = metricObj.value["params"]
  let tmpParmsAry = params.split(",")
  const mtrcNoAry: any[] = [];
  let mtrcNoParmsObj = {}
  tmpParmsAry.forEach(function(element) {
    mtrcNoAry.push(element.substr(2))
    mtrcNoParmsObj[element.substr(0,1)] = element.substr(2)
  });

  let mtrcNos = mtrcNoAry.join(",")
  let srhVals = getFieldsValue();
  srhVals['mtrcNos'] = mtrcNos

  queryAllList(srhVals).then((res) => { 
    calc(res,mtrcNoParmsObj)
  })
}

watch(
  () => props.data,
  () => setData()
);

const [registerTable,{reload,setProps}] = useTable({
    title: '',
    dataSource:dataList,
    useSearchForm: false,
    columns: columnsreport,
    showTableSetting: false,
    pagination:true,
    canResize: true,
    scroll: { y: 500 },
    bordered:true, 
    beforeFetch(params) {
          // params['mtrcCtp'] = props.mtrcCtp
          // params = Object.assign(params)
      },   
});

async function setChart() {
  
  let {category, lineData } = getLineData()
  let {toValAry, warnValAry,intvValAry} = await getStandData()
  setOptions({
    backgroundColor: '#fff',
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        label: {
          show: true,
          backgroundColor: '#ccc',
        },
      },
    },
    legend: {
      data: [ metricObj.value.mtrcName,serialNames.value[0],serialNames.value[1],serialNames.value[2],],
      textStyle: {
        color: 'black',
      },
    },
    xAxis: {
      data: category,
      axisLine: {
        lineStyle: {
          color: 'black',
        },
      },
    },
    yAxis: {
      type:'value',
      name:'单位['+(metricObj.value.unit||'')+"]",
      position: 'left',
      alignTicks: true,
      //splitNumber:3,
      interval:interval.value,
      min: yMin.value,
      max: yMax.value,
      scale : true,
      axisLabel:{
        formatter: '{value}'
      },
      axisLine: {
        show: false,
        onZero: false,
        lineStyle: { 
          color: 'black' 
        }
      },
    },
    series: [
      {
        name: metricObj.value.mtrcName,
        type: 'line',
        smooth: true,
        showAllSymbol: 'auto',
        symbol: 'emptyCircle',
        symbolSize: 15,
        data: lineData,
      },
      {
        name: serialNames.value[0],
        type: 'line',
        smooth: true,
        showAllSymbol: 'auto',
        symbol: 'none',
        symbolSize: 15,
        color:'green',
        data: toValAry, 
        lineStyle: {
          color: 'green' 
        }
      },
      {
        name: serialNames.value[1],
        type: 'line',
        smooth: true,
        showAllSymbol: 'auto',
        symbol: 'none',
        symbolSize: 15,
        color:'yellow',
        lineStyle: {
          color: 'yellow' 
        },
        data: warnValAry,
      },
      {
        name: serialNames.value[2],
        type: 'line',
        smooth: true,
        showAllSymbol: 'auto',
        symbol: 'none',
        symbolSize: 15,
        color:'red',
        data: intvValAry,
        lineStyle: {
          color: 'red' 
        }
      },
    ],

    // visualMap: {
    //   show: true,
    //   type: 'continuous',
    //   dimension: 1,
    //   min: 0,
    //   max: 100,
    //   inRange: {
    //     color: ['red', 'yellow', 'green']
    //   }
    // }
    // visualMap: {
    //   show: true,
    //   type: 'piecewise',
    //   dimension: 1,
    //   pieces: piecesAry
    // }
  
  
    // visualMap: {
    //   show: true,
    //     dimension: 1,  // 映射到y轴
    //     inRange: {
    //         color: ['#ff0000', '#00ff00'] // 设置颜色范围，红色到绿色
    //     },
    //     orient: 'horizontal',
    //     left: 'center',
    //     bottom: 10
    // },
  });
}

function getLineData (){
  const category: any[] = [];
  const lineData: any[] = [];

  for(let i = 0;i<dataList.value.length; i++) {
    category.push(dataList.value[i]['fillTime']);
    lineData.push(dataList.value[i]['fillVals']);
  }
  return {category, lineData };
}

async function getStandData() {
    const toValAry: any[] = [];
    const warnValAry: any[] = [];
    const intvValAry: any[] = [];
    let stToVal = metricObj.value.stTolVal;
    let toVal = metricObj.value.tolVal;
    let warnVal = metricObj.value.warnVal;
    let intvVal = metricObj.value.intvVal;
    for (let i = 0;i<dataList.value.length; i++) {
      toValAry.push(stToVal)
      warnValAry.push(toVal)
      intvValAry.push(warnVal)
    }

    let flag = toVal<warnVal?true:false;
    serialNames.value[0] = "低风险";
    serialNames.value[1] = "中风险";
    serialNames.value[2] = "高风险";


    return {toValAry, warnValAry,intvValAry};
}

function calc(resData,mtrcNoParmsObj) {
    let mtrcList = resData.mtrcList;
    let reportDataList = resData.dataList
    for(let i=0;i<mtrcList.length;i++) {
      let mtrc = mtrcList[i]
      let collFreq = mtrcList[i].collFreq
      mtrc['datas'] = []
      for(let j=0;j<reportDataList.length;j++){
          if(mtrcList[i]['mtrcNo'] ==reportDataList[j].mtrcNo){
            let obj = getDateStrVal(reportDataList[j],collFreq)
            mtrc['datas'].push(obj)
          }
        }
    }

    let firstMtrc = mtrcList[0]
    let firstDatas = firstMtrc.datas
    let retObj ={}
    for(let i=0;i<firstDatas.length;i++) {
      retObj[firstDatas[i].fillTime] = {}
      retObj[firstDatas[i].fillTime][firstDatas[i].mtrcNo] = firstDatas[i]['fillVals']
    }

    Object.entries(retObj).forEach(([fillTime, childData]) => { 
        let cTime = new Date(fillTime).getTime()
        for(let i=1;i<mtrcList.length;i++){
          let twoDatas = mtrcList[i].datas
          for(let j=0;j<twoDatas.length;j++) {
            let stTime = twoDatas[j]['stDate'].getTime();
            let endTime = twoDatas[j]['endDate'].getTime();
            let fillVal = twoDatas[j]['fillVals']
            let mtrcNo = twoDatas[j]['mtrcNo']
            if(cTime>=stTime && cTime<=endTime) {
              retObj[fillTime][mtrcNo] =fillVal 
              break;
            }
          }
        }
    })   

    const mtrcNo = metricObj.value.mtrcNo;
    const mtrcName = metricObj.value.mtrcName;
    Object.entries(retObj).forEach(([fillTime, childData]) => { 
      try {
        let formula = metricObj.value['formulas'];
        let ss = getTimeStr(fillTime)
        let tmpObj = {'mtrcName':mtrcName,'fillTime':ss,'mtrcNo':mtrcNo}
        Object.entries(childData).forEach(([ckey, value]) => { 
          Object.entries(mtrcNoParmsObj).forEach(([tkey, tval]) => { 
            if(ckey===tval) {
              formula = formula.replaceAll(tkey,value)
              return true
            }
          })
        })
        tmpObj['fillVals'] = eval(formula).toFixed(2) 
        let riskLevel = computeRiskLevel(tmpObj['fillVals'])
        tmpObj["riskLevel"] = riskLevel
        dataList.value.push(tmpObj)
        setYMaxMin()
        tabChange("chartLine");

      } catch(e) {
        console.log(e)
      }
      
    });
}


function getDateStrVal(data,freg) {

  let fillTime = data['fillTime'];

  fillTime = fillTime.substr(0,10)

  let stDate  = new Date(fillTime);
  let year = stDate.getFullYear();
  let month = stDate.getMonth();
  let dayWeek = stDate.getDay();
  let date = stDate.getDate();
   
 
  let oneDayTime = 24*60*60*1000
  let endDate = new Date();
  let retObj = {}
  try {
    switch(freg*1) {
      case 1:  //日期
        stDate = new Date(year,month,date,0,0,0);
        endDate = new Date(year,month,date,23,59,59);
        break;
      case 2: //每周
        let nowTime = new Date(year,month,date,0,0,1).getTime();
        let mondayTime = nowTime-(dayWeek-1)*oneDayTime;
        let sundayTime = nowTime+(7-dayWeek)*oneDayTime+oneDayTime;
        stDate = new Date(mondayTime);
        endDate =  new Date(sundayTime);
        break;
      case 3:  //每月
        stDate = new Date(year, month, 1,0,0,1);
        endDate = new Date(year, month+1, 0,23,59,59);
        break;
      case 4:   //每3月
        let m = Math.floor(month/3);
        stDate = new Date(year, m*3, 1,0,0,1);
        endDate = new Date(year, (m+1)*3, 0,0,0,0);
        break;
      case 5:  //每半年
        let k = month>5?1:0
        stDate = new Date(year, k*6, 1,0,0,1);
        endDate = new Date(year,(k+1)*6, 0,0,0,0);
        break;
      case 6: //每一年
        stDate = new Date(year, 0, 1,0,0,1);
        endDate = new Date(year, 11, 31,23,59,59);
        break;
      default:

    }

    retObj["stDate"] = stDate;
    retObj["endDate"] = endDate;
    retObj["endDate"] = endDate;
    retObj["freg"] = freg;
    retObj["mtrcNo"] = data['mtrcNo']
    retObj["fillVals"] =  data['fillVals']
    retObj["fillTime"] = fillTime;

  } catch(err) {
    console.log(err)
  }


  return retObj;

}

function setYMaxMin() {
  let toVal = metricObj.value.tolVal;
  let warnVal = metricObj.value.warnVal;
  let intvVal = metricObj.value.intvVal;

  let tmpAry =  [toVal,warnVal]
  for(let i=0;i<dataList.value.length;i++) {
    tmpAry.push(dataList.value[i].fillVals)
  }
  

  let max = Math.max(...tmpAry)
  let min = Math.min(...tmpAry)

   min = min-(max-min)*0.1;
   max = max+(max-min)*0.1

   yMin.value = Math.floor(min)
   yMax.value = Math.ceil(max)

   interval.value =  Math.floor((yMax.value-yMin.value)/10)
   interval.value = interval.value>0?interval.value:1


}

function getTimeStr(fillTime) {
  let collFreq = metricObj.value.collFreq;
  if(!fillTime) return 
  if(collFreq==1) {
    return fillTime.substr(5,5)
  } else  if(collFreq==2) {
    return fillTime.substr(5,5)
  } else  if(collFreq==3) {
    return fillTime.substr(0,7)
  } else  if(collFreq==4) {
    return fillTime.substr(0,7)
  } else  if(collFreq==5) {
    return fillTime.substr(0,7)
  } else  if(collFreq==6) {
    return fillTime.substr(0,4)
  } else {
    return fillTime.substr(11,16)
  }
  
}

function computeRiskLevel(fillVal) {
      const { stTolVal, tolVal, warnVal, intvVal } = metricObj.value;
      let flag =  tolVal < warnVal?true:false
      if(stTolVal !== undefined) {
        if (flag) {
            if(fillVal < stTolVal) return 0;
        } else {
            if(fillVal > stTolVal) return 0;
        }
      }
      if(intvVal !== undefined) {
        if (flag) {
            if(fillVal > intvVal) return 0;
        } else {
            if(fillVal < intvVal) return 0;
        }
      }
      if (flag) {
          if (fillVal <= tolVal) {
            return 1;
          }
          if (fillVal < warnVal) {
            return 2;
          }
          return 3;
      } else {
          if (fillVal >= tolVal) {
            return 1;
          }
          if (fillVal > warnVal) {
            return 2;
          }
          return 3;
      }
      return 0;
    }


</script>
