<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 fixedChannelColors = Object.freeze({
  airbnb: "#FF385C",
  booking: "#60A5FA",
  decolar: "#22C55E",
  direto: "#F59E0B",
  vrbo: "#0EA5E9",
  sem_canal: "#B0BEC5",
  raniery_kohler: "#A855F7",
});

const fallbackChannelPalette = Object.freeze([
  "#A855F7",
  "#8B5CF6",
  "#C084FC",
  "#9333EA",
  "#D946EF",
  "#7C3AED",
  "#E879F9",
  "#6D28D9",
]);

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

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

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

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

  if (
    value.includes("sem canal") ||
    value.includes("sem_canal") ||
    value.includes("no channel")
  ) {
    return "sem_canal";
  }

  if (value.includes("raniery kohler")) {
    return "raniery_kohler";
  }

  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 = (channel) => {
  const seed = String(channel ?? "").trim().toLowerCase();

  let hash = 0;

  for (let index = 0; index < seed.length; index += 1) {
    hash = (hash * 31 + seed.charCodeAt(index)) % fallbackChannelPalette.length;
  }

  return fallbackChannelPalette[hash];
};

const resolveChannelColor = (channel) => {
  const normalizedChannel = normalize(channel);

  return fixedChannelColors[normalizedChannel] ?? buildFallbackColor(channel);
};

const legendItems = computed(() =>
  props.channels.map((c) => ({
    key: String(c.channel ?? ""),
    label: c.channel,
    reservations_count: Number(c.reservations_count ?? 0),
    color: resolveChannelColor(c.channel),
  })),
);

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: "#FFFFFF",
      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>
