<script setup lang="ts">
import { onMounted, watch, reactive,PropType } from 'vue'
import merge from 'lodash/merge'
import cloneDeep from 'lodash/cloneDeep'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import config from './config'

const props = defineProps({
  chartConfig: {
    type: Object as PropType<config>,
    default: () => ({})
  }
})
type DataProps = {
  name: string | number
  value: string | number
  [key: string]: string | number
}

interface StateProps {
  defaultConfig: {
    dataset: {
      dimensions: Array<string>
      source: Array<DataProps>
    }
    colors: Array<string>
    unit: string
    showValue: boolean
    itemHeight: number
  }
  mergedConfig: any
  capsuleLength: Array<number>
  capsuleValue: Array<string | Object>
  labelData: Array<number>
  capsuleItemHeight: string
}

const state = reactive<StateProps>({
  defaultConfig: {
    dataset: { dimensions: ['name', 'value'], source: [] },
    colors: ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293'],
    unit: '',
    showValue: false,
    itemHeight: 10
  },
  mergedConfig: null,
  capsuleLength: [],
  capsuleValue: [],
  labelData: [],
  capsuleItemHeight: ''
})

watch(
  () => props.chartConfig.option,
  newVal => {
    calcData(newVal)
  },
  {
    deep: true
  }
)

function calcData(data:any) {
  mergeConfig(props.chartConfig.option)

  calcCapsuleLengthAndLabelData()
}

function mergeConfig(data:any) {
  state.mergedConfig = merge(cloneDeep(state.defaultConfig), data || {})
}

function calcCapsuleLengthAndLabelData() {
  const { source } = state.mergedConfig.dataset
  if (!source.length) return

  state.capsuleItemHeight = handle(state.mergedConfig.itemHeight)
  const capsuleValue = source.map((item: DataProps) => item[state.mergedConfig.dataset.dimensions[1]])

  const maxValue = Math.max(...capsuleValue)

  state.capsuleValue = capsuleValue

  state.capsuleLength = capsuleValue.map((v: any) => (maxValue ? v / maxValue : 0))

  const oneFifth = maxValue / 5

  const labelData = Array.from(new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))))

  state.labelData = labelData
}
const handle = (val: string | number) => {
  return val + 'px'
}
onMounted(() => {
  calcData(props.chartConfig.option)
})

// 预览
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
    calcData(newData)
})
</script>
<template>
  <div class="dv-capsule-chart">
    <template v-if="state.mergedConfig">
      <div class="label-column">
        <div
          v-for="item in state.mergedConfig.dataset.source"
          :key="item[state.mergedConfig.dataset.dimensions[0]]"
          :style="{ height: state.capsuleItemHeight, lineHeight: state.capsuleItemHeight }"
        >
          {{ item[state.mergedConfig.dataset.dimensions[0]] }}
        </div>
        <div class="laset">&nbsp;</div>
      </div>

      <div class="capsule-container">
        <div
          v-for="(capsule, index) in state.capsuleLength"
          :key="index"
          class="capsule-item"
          :style="{ height: state.capsuleItemHeight }"
        >
          <div
            class="capsule-item-column"
            :style="`width: ${capsule * 100}%; background-color: ${
              state.mergedConfig.colors[index % state.mergedConfig.colors.length]
            };height:calc(100% - ${2}px);`"
          >
            <div v-if="state.mergedConfig.showValue" class="capsule-item-value">
              {{ state.capsuleValue[index] }}
            </div>
          </div>
        </div>

        <div class="unit-label">
          <div v-for="(label, index) in state.labelData" :key="label + index">
            {{ label }}
          </div>
        </div>
      </div>

      <div v-if="state.mergedConfig.unit" class="unit-text">
        {{ state.mergedConfig.unit }}
      </div>
    </template>
  </div>
</template>

<style lang="scss" scoped>
.dv-capsule-chart {
  position: relative;
  display: flex;
  flex-direction: row;
  box-sizing: border-box;
  padding: 10px 16px 10px 10px;
  color: #fff;

  .label-column {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    box-sizing: border-box;
    padding-right: 10px;
    text-align: right;
    font-size: 12px;
    >div:not(:last-child){
        margin: 5px 0;
    }
 
  }

  .capsule-container {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }

  .capsule-item {
    box-shadow: 0 0 3px #999;
    height: 10px;
    margin: 5px 0px;
    border-radius: 5px;

    .capsule-item-column {
      position: relative;
      height: 8px;
      margin-top: 1px;
      border-radius: 5px;
      transition: all 0.3s;
      display: flex;
      justify-content: flex-end;
      align-items: center;

      .capsule-item-value {
        font-size: 12px;
        transform: translateX(100%);
      }
    }
  }

  .unit-label {
    height: 20px;
    font-size: 12px;
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .unit-text {
    text-align: right;
    display: flex;
    align-items: flex-end;
    font-size: 12px;
    line-height: 20px;
    margin-left: 10px;
  }
}
</style>
