/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { defineComponent, PropType, ref } from 'vue'
import initChart from '@/components/chart'
import { useI18n } from 'vue-i18n'
import type { Ref } from 'vue'

const props = {
  height: {
    type: [String, Number] as PropType<string | number>,
    default: window.innerHeight - 174
  },
  width: {
    type: [String, Number] as PropType<string | number>,
    default: '100%'
  },
  seriesData: {
    type: Array as PropType<Array<any>>,
    default: () => []
  },
  links: {
    default: () => []
  },
  labelShow: {
    type: Boolean as PropType<boolean>,
    default: true
  }
}

const GraphChart = defineComponent({
  name: 'GraphChart',
  props,
  setup(props) {
    const graphChartRef: Ref<HTMLDivElement | null> = ref(null)
    const { t } = useI18n()

    const legendData = [
      { color: '#2D8DF0', name: t('project.workflow.online') },
      { color: '#f37373', name: t('project.workflow.workflow_offline') },
      { color: '#ba3e3e', name: t('project.workflow.schedule_offline') }
    ]

    const getCategory = (schedulerStatus: number, workflowStatus: number) => {
      switch (true) {
        case workflowStatus === 0:
          return 1
        case workflowStatus === 1 && schedulerStatus === 0:
          return 2
        case workflowStatus === 1 && schedulerStatus === 1:
        default:
          return 0
      }
    }

    const option: any = {
      tooltip: {
        confine: true,
        backgroundColor: '#fff',
        formatter: (params: any) => {
          if (!params.data.name) {
            return false
          }

          const {
            name,
            scheduleStartTime,
            scheduleEndTime,
            crontab,
            workFlowPublishStatus,
            schedulePublishStatus
          } = params.data

          return `
            ${t('project.workflow.workflow_name')}：${name}<br/>
            ${t(
              'project.workflow.schedule_start_time'
            )}：${scheduleStartTime}<br/>
            ${t('project.workflow.schedule_end_time')}：${scheduleEndTime}<br/>
            ${t('project.workflow.crontab_expression')}：${
            crontab ? crontab : ' - '
          }<br/>
            ${t(
              'project.workflow.workflow_publish_status'
            )}：${workFlowPublishStatus}<br/>
            ${t(
              'project.workflow.schedule_publish_status'
            )}：${schedulePublishStatus}<br/>
          `
        }
      },
      legend: {
        data: legendData?.map((item) => {
          return {
            name: item.name,
            itemStyle: {
              color: item.color
            }
          }
        })
      },
      series: [
        {
          type: 'graph',
          layout: 'force',
          draggable: true,
          force: {
            repulsion: 300,
            edgeLength: 200
          },
          symbol: 'roundRect',
          symbolSize: 70,
          roam: true,
          label: {
            show: props.labelShow,
            formatter: (val: any) => {
              let newStr = ''
              const str = val.data.name.split('')

              for (let i = 0, s; (s = str[i++]); ) {
                newStr += s
                if (!(i % 10)) newStr += '\n'
              }

              return newStr.length > 60 ? newStr.slice(0, 60) + '...' : newStr
            }
          },
          edgeSymbol: ['circle', 'arrow'],
          edgeSymbolSize: [4, 10],
          edgeLabel: {
            fontSize: 20
          },
          data: props.seriesData.map((item) => {
            const category = getCategory(
              Number(item.schedulePublishStatus),
              Number(item.workFlowPublishStatus)
            )
            const itemStyle = {
              color: ''
            }

            if (category === 1) {
              itemStyle.color = '#f37373'
            } else if (category === 2) {
              itemStyle.color = '#ba3e3e'
            } else if (category === 0) {
              itemStyle.color = '#2D8DF0'
            }

            return {
              name: item.name,
              id: item.id,
              category,
              workFlowPublishStatus:
                Number(item.workFlowPublishStatus) === 0
                  ? t('project.workflow.offline')
                  : t('project.workflow.online'),
              schedulePublishStatus:
                Number(item.schedulePublishStatus) === 0
                  ? t('project.workflow.offline')
                  : t('project.workflow.online'),
              crontab: item.crontab,
              scheduleStartTime: item.scheduleStartTime
                ? item.scheduleStartTime
                : '-',
              scheduleEndTime: item.scheduleEndTime
                ? item.scheduleEndTime
                : '-',
              itemStyle
            }
          }),
          links: props.links,
          lineStyle: {
            opacity: 0.9,
            width: 2,
            curveness: 0
          },
          nodeScaleRatio: 0,
          zoom: 1,
          categories: legendData
        }
      ]
    }

    initChart(graphChartRef, option)

    return { graphChartRef }
  },
  render() {
    const { height, width } = this
    return (
      <div
        ref='graphChartRef'
        style={{
          height: typeof height === 'number' ? height + 'px' : height,
          width: typeof width === 'number' ? width + 'px' : width
        }}
      />
    )
  }
})

export default GraphChart
