<template>
  <q-card class="panel-card panel-card--soft panel-card--channels" flat>
    <div class="panel-title">Canais de Aquisição</div>

    <div class="channel-chart-wrap">
      <div class="channel-chart-box">
        <Pie :data="chartData" :options="chartOptions" />
      </div>
    </div>

    <div class="channel-legend">
      <div
        v-for="channel in legendItems"
        :key="channel.key"
        class="channel-legend-item"
      >
        <span class="channel-dot" :style="{ backgroundColor: channel.color }" />

        <span class="channel-name">{{ channel.label }}</span>

        <span class="channel-total">
          {{ formatInteger(channel.reservations_count) }} reservas
        </span>
      </div>
    </div>
  </q-card>
</template>

<script setup>
import { computed } from "vue";
import { Pie } from "vue-chartjs";
import { formatInteger } from "src/helpers/utils";

const props = defineProps({
  channels: {
    type: Array,
    default: () => [],
  },
});

const channelPalette = Object.freeze([
  "#FF3B30",
  "#00A6FB",
  "#FFC400",
  "#34C759",
  "#0052FF",
  "#FF7A00",
  "#5856D6",
  "#00C7BE",
  "#E53935",
  "#1D4ED8",
]);

const normalize = (channel) => {
  const value = String(channel ?? "").toLowerCase();

  if (value.includes("airbnb")) {
    return "airbnb";
  }

  if (value.includes("booking")) {
    return "booking";
  }

  if (
    value.includes("direto") ||
    value.includes("direct") ||
    value.includes("site") ||
    value.includes("whatsapp") ||
    value.includes("instagram")
  ) {
    return "direto";
  }

  if (value.includes("vrbo")) {
    return "vrbo";
  }

  return "outros";
};

const buildFallbackColor = (index) => {
  const hue = (index * 47) % 360;

  return `hsl(${hue} 84% 52%)`;
};

const resolveChannelColor = (index) =>
  channelPalette[index] ?? buildFallbackColor(index);

const legendItems = computed(() =>
  props.channels.map((c, index) => ({
    key: `${normalize(c.channel)}-${index}`,
    label: c.channel,
    reservations_count: Number(c.reservations_count ?? 0),
    color: resolveChannelColor(index),
  })),
);

const hasChannels = computed(() => legendItems.value.length > 0);

const chartData = computed(() => ({
  labels: hasChannels.value
    ? legendItems.value.map((item) => item.label)
    : ["Sem dados"],
  datasets: [
    {
      data: hasChannels.value
        ? legendItems.value.map((item) => item.reservations_count)
        : [1],
      backgroundColor: hasChannels.value
        ? legendItems.value.map((item) => item.color)
        : ["#D9E3E7"],
      borderColor: "transparent",
      borderWidth: 0,
    },
  ],
}));

const chartOptions = computed(() => ({
  responsive: true,
  maintainAspectRatio: false,
  plugins: {
    legend: { display: false },
    tooltip: { enabled: false },
  },
}));
</script>

<style scoped>
.panel-title {
  margin-bottom: 16px;
  font-size: 19px;
  font-weight: 400;
  color: #08514c;
}

.channel-chart-wrap {
  display: flex;
  justify-content: center;
  min-width: 0;
  padding: 8px 0 16px;
}

.channel-chart-box {
  width: min(120px, 100%);
  height: 120px;
  margin-bottom: 74px;
}

.channel-legend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 14px;
  justify-items: center;
  text-align: center;
  min-width: 0;
}

.channel-legend-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  vertical-align: middle;
}

.channel-dot {
  display: inline-flex;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.channel-name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  color: #273136;
  min-width: 0;
  overflow-wrap: anywhere;
  text-align: center;
}

.channel-total {
  font-size: 14px;
  font-weight: 400;
  color: #5f6d73;
  overflow-wrap: anywhere;
}

@media (max-width: 640px) {
  .channel-chart-wrap {
    padding: 0 0 12px;
  }

  .channel-chart-box {
    width: min(160px, 100%);
    height: 160px;
    margin-bottom: 24px;
  }

  .channel-legend {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  .channel-name {
    font-size: 14px;
  }

  .channel-total {
    font-size: 13px;
  }
}
</style>
