<template>
  <m-card :title="legendOnly ? '图例' : '图层控制'" :width="width" :height="panelHeight">
    <div class="layer-panel" :class="{ 'is-legend-only': legendOnly }">
      <div v-if="!legendOnly" class="layer-panel-list">
        <button
          v-for="layer in panelLayers"
          :key="layer.key"
          class="layer-panel-item"
          :class="{
            'is-active': layer.key === modelValue,
            'is-checked': layer.key === modelValue,
          }"
          type="button"
          @mousedown.prevent
          @click="handleLayerClick($event, layer.key)"
        >
          <span>{{ layer.name }}</span>
          <i></i>
        </button>
        <div v-if="!panelLayers.length" class="layer-panel-empty">暂无图层配置</div>
      </div>

      <div class="layer-panel-legend">
        <div class="layer-panel-section-title">图例</div>
        <div
          v-if="panelLegends.length"
          class="layer-panel-legend-grid"
          :class="{ 'is-single': legendSingle }"
        >
          <button
            v-for="item in panelLegends"
            :key="item.key || item.name"
            class="layer-panel-legend-row"
            :class="{
              'is-selected': isLegendItemSelectable(item) && item.key === selectedLegendKey,
              'is-checkable': isLegendItemSelectable(item),
              'is-disabled': !isLegendItemSelectable(item),
            }"
            type="button"
            :disabled="!isLegendItemSelectable(item)"
            :title="item.name"
            @mousedown.prevent
            @click="handleLegendClick($event, item)"
          >
            <span
              class="legend-swatch"
              :style="{
                backgroundColor: item.fillColor,
                borderColor: item.strokeColor || item.fillColor,
              }"
            ></span>
            <span class="legend-name">{{ item.name }}</span>
            <i v-if="isLegendItemSelectable(item)" class="legend-check"></i>
          </button>
        </div>
        <div v-else class="layer-panel-empty is-legend">暂无图例</div>
      </div>
    </div>
  </m-card>
</template>

<script setup>
import { computed } from "vue"
import mCard from "@/components/mCard/index.vue"
import { getLayersByTopic } from "@/config/layers"

const props = defineProps({
  topicKey: {
    type: String,
    required: true,
  },
  modelValue: {
    type: String,
    default: "",
  },
  legends: {
    type: Array,
    default: () => [],
  },
  selectedLegendKey: {
    type: String,
    default: "",
  },
  height: {
    type: Number,
    default: 0,
  },
  width: {
    type: Number,
    default: 232,
  },
  layers: {
    type: Array,
    default: null,
  },
  legendOnly: {
    type: Boolean,
    default: false,
  },
})

const emit = defineEmits(["update:modelValue", "update:selectedLegendKey"])

const panelLayers = computed(() => Array.isArray(props.layers) ? props.layers : getLayersByTopic(props.topicKey))
const panelLegends = computed(() => Array.isArray(props.legends) ? props.legends : [])
const legendSelectable = computed(() => panelLegends.value.filter(isSelectableLegend).length > 1)
const legendSingle = computed(() => panelLegends.value.length === 1)
const panelHeight = computed(() => {
  if (props.height) return props.height
  return 430
})

function handleLayerClick(event, layerKey) {
  event.currentTarget?.blur?.()
  emit("update:modelValue", props.modelValue === layerKey ? "" : layerKey)
}

function handleLegendClick(event, item) {
  event.currentTarget?.blur?.()
  if (!isLegendItemSelectable(item)) return
  emit("update:selectedLegendKey", props.selectedLegendKey === item.key ? "" : item.key)
}

function isSelectableLegend(item) {
  if (item?.selectable === false) return false
  return Boolean(item?.key && (item.cqlFilter || item.rankingValueKey))
}

function isLegendItemSelectable(item) {
  return legendSelectable.value && isSelectableLegend(item)
}
</script>

<style lang="scss">
.layer-panel {
  display: grid;
  grid-template-rows: minmax(150px, 210px) minmax(0, 1fr);
  gap: 12px;
  height: 100%;
  box-sizing: border-box;
  padding: 12px 12px 14px;
  overflow: hidden;

  &.is-legend-only {
    grid-template-rows: minmax(0, 1fr);
    gap: 0;
    padding: 10px 12px 12px;

    .layer-panel-legend {
      padding-top: 0;
      border-top: 0;
    }

    .layer-panel-section-title {
      display: none;
    }

    .layer-panel-legend-grid {
      grid-template-columns: 1fr;
      justify-content: stretch;
      gap: 8px;
      max-height: 100%;
      padding-right: 0;
      overflow: hidden;
    }

    .layer-panel-legend-row {
      min-height: 28px;
      padding: 4px 2px;
    }
  }

  &-list {
    display: flex;
    flex-direction: column;
    gap: 7px;
    min-height: 0;
    padding-right: 4px;
    overflow-y: auto;
  }

  &-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 27px;
    flex: 0 0 27px;
    padding: 0 9px;
    border: 1px solid rgba(48, 220, 255, 0.22);
    background: rgba(3, 20, 32, 0.58);
    color: rgba(255, 255, 255, 0.74);
    font-size: 12px;
    cursor: pointer;

    span {
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    i {
      width: 8px;
      height: 8px;
      border: 1px solid rgba(255, 255, 255, 0.42);
      border-radius: 50%;
    }

    &.is-active {
      color: #fff;
      border-color: rgba(48, 220, 255, 0.7);
      background: linear-gradient(90deg, rgba(21, 121, 130, 0.52), rgba(3, 20, 32, 0.78));
    }

    &.is-checked {
      i {
        border-color: #30dcff;
        background: #30dcff;
        box-shadow: 0 0 12px rgba(48, 220, 255, 0.88);
      }
    }

    &.is-checked:not(.is-active) {
      color: rgba(255, 255, 255, 0.88);
      border-color: rgba(48, 220, 255, 0.42);
      background: rgba(3, 20, 32, 0.72);
    }
  }

  &-legend {
    min-height: 0;
    padding-top: 9px;
    border-top: 1px solid rgba(48, 220, 255, 0.18);
    overflow: visible;
  }

  &-section-title {
    position: relative;
    margin-bottom: 7px;
    padding-left: 10px;
    color: rgba(219, 249, 255, 0.9);
    font-size: 13px;
    font-weight: 600;
    line-height: 16px;

    &::before {
      content: "";
      position: absolute;
      left: 0;
      top: 4px;
      width: 4px;
      height: 8px;
      background: #30dcff;
      box-shadow: 0 0 10px rgba(48, 220, 255, 0.7);
    }
  }

  &-legend-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 96px));
    justify-content: center;
    align-content: start;
    gap: 7px 8px;
    max-height: calc(100% - 24px);
    padding-right: 4px;
    overflow-y: auto;

    &.is-single {
      grid-template-columns: minmax(0, 128px);
    }
  }

  &-legend-row {
    display: grid;
    grid-template-columns: 15px minmax(0, 1fr);
    align-items: start;
    column-gap: 6px;
    min-width: 0;
    min-height: 22px;
    padding: 3px 2px;
    border: 1px solid transparent;
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;

    &:disabled {
      opacity: 1;
    }

    &.is-checkable {
      grid-template-columns: 15px minmax(0, 1fr) 12px;
    }

    &.is-selected {
      border-color: rgba(48, 220, 255, 0.42);
      background: rgba(48, 220, 255, 0.08);

      .legend-check {
        border-color: #30dcff;
        background: #30dcff;
        box-shadow: 0 0 10px rgba(48, 220, 255, 0.76);

        &::after {
          opacity: 1;
        }
      }
    }

    &.is-disabled {
      cursor: default;
    }
  }

  .legend-swatch {
    width: 15px;
    height: 10px;
    margin-top: 3px;
    border: 1px solid;
    box-shadow: 0 0 12px rgba(48, 220, 255, 0.18);
  }

  .legend-name {
    display: -webkit-box;
    min-width: 0;
    color: rgba(255, 255, 255, 0.82);
    font-size: 12px;
    line-height: 14px;
    overflow: hidden;
    word-break: break-all;
    white-space: normal;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }

  .legend-check {
    position: relative;
    width: 11px;
    height: 11px;
    margin-top: 2px;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 2px;

    &::after {
      content: "";
      position: absolute;
      left: 3px;
      top: 1px;
      width: 3px;
      height: 6px;
      border: solid rgba(3, 20, 32, 0.95);
      border-width: 0 1px 1px 0;
      opacity: 0;
      transform: rotate(45deg);
    }
  }

  &-empty {
    color: rgba(255, 255, 255, 0.52);
    line-height: 48px;
    text-align: center;

    &.is-legend {
      line-height: 28px;
    }
  }

  &-list,
  &-legend-grid {
    scrollbar-width: thin;
    scrollbar-color: rgba(48, 220, 255, 0.42) rgba(48, 220, 255, 0.08);

    &::-webkit-scrollbar {
      width: 4px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(48, 220, 255, 0.42);
    }

    &::-webkit-scrollbar-track {
      background: rgba(48, 220, 255, 0.08);
    }
  }
}
</style>
