<template>
  <QuestionSummary :title="props.title" :text="props.text">
    <div class="mb-6 inline-grid grid-cols-[140px_auto] grid-rows-2 gap-x-2">
      <h4 class="text-xl font-bold">{{ $t("feedback.average") }}:</h4>
      <span
        class="col-start-2 row-span-2 inline-flex h-9 w-11 items-center justify-center rounded text-xl font-bold"
        :style="ratingValueStyle"
      >
        {{ rating.toFixed(1) }}
      </span>
      <h5 class="text-base">{{ answers }} {{ $t("feedback.answers") }}</h5>
    </div>
    <div
      class="relative grid grid-cols-3 pt-3 grid-areas-rating-scale-slim md:grid-cols-8 md:grid-areas-rating-scale"
    >
      <div
        class="gradient relative z-10 h-2 overflow-visible grid-in-bar"
        :style="gradientStyle"
      ></div>
      <div class="empty-bar absolute h-2 w-full bg-gray-300 grid-in-bar"></div>
      <div class="circle-wrapper relative grid-in-bar">
        <div
          class="circle absolute -top-3 z-20 h-8 w-8 -translate-x-1/2 rounded-full p-[3px] before:block before:h-full before:w-full before:rounded-full before:bg-white"
          :style="circleStyle"
        ></div>
      </div>
      <div
        v-for="(legend, i) of legends"
        :key="legend.index"
        :class="{
          'items-start grid-in-fst before:left-0 md:before:left-1/2': legend.index == 1,
          'grid-in-mid before:left-0 md:grid-in-snd md:before:left-1/2':
            legend.index == 2,
          'hidden before:left-1/2 md:inline-flex md:grid-in-trd': legend.index == 3,
          'items-end text-right grid-in-fth before:right-0 after:absolute after:left-0 after:top-0 after:h-4 after:w-px after:bg-gray-500 md:before:left-1/2 md:before:right-auto md:after:hidden':
            legend.index == 4,
        }"
        class="legend relative inline-flex flex-col pt-4 before:absolute before:top-0 before:h-4 before:w-px before:bg-gray-500 md:items-center"
      >
        <Popover class="relative">
          <PopoverButton class="focus:outline-none">
            <div
              :class="[
                { hidden: legend.index === 3 || legend.index === 2 },
                'md:block',
              ]"
            >
              {{ legend.index }}
            </div>

            <p
              :class="[
                { hidden: legend.index === 3 || legend.index === 2 },
                'md:block',
              ]"
            >
              {{ legend.label }}
            </p>
          </PopoverButton>
          <PopoverPanel
            class="absolute top-[-150%] z-10 w-[120px] border border-gray-500 bg-white p-1 text-left text-sm"
          >
            <p>
              {{ `"${legend.label}" ${numberOfRatings[i]} ${$t("feedback.answers")}` }}
            </p>
          </PopoverPanel>
        </Popover>
      </div>
    </div>
  </QuestionSummary>
</template>

<script setup lang="ts">
import QuestionSummary from "@/components/ui/QuestionSummary.vue";
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/vue";
import { computed } from "vue";
import { useI18n } from "vue-i18n";

const { t } = useI18n();

type RGB = [number, number, number];
const red: RGB = [221, 103, 81]; // red-600
const yellow: RGB = [250, 200, 82]; // yellow-500
const lightGreen: RGB = [120, 222, 163]; // green-500
const darkGreen: RGB = [91, 183, 130]; // green-600

const legends = [
  { index: 1, label: t("feedback.veryUnhappy") },
  { index: 2, label: t("feedback.unhappy") },
  { index: 3, label: t("feedback.happy") },
  { index: 4, label: t("feedback.veryHappy") },
];

const props = defineProps<{
  ratings: number[];
  title: string;
  text: string;
}>();

const rating = computed((): number => {
  const sum = props.ratings.reduce((a, b) => a + b, 0);
  return sum / props.ratings.length;
});

const weight = computed(() => {
  return rating.value % 1;
});

const scale = computed(() => {
  return Math.floor(rating.value);
});

const answers = computed(() => props.ratings.length);

const numberOfRatings = computed(() => {
  return legends.map(
    (legend) => props.ratings.filter((rating) => rating === legend.index).length
  );
});

const colors = computed(() => {
  switch (scale.value) {
    case 1:
      return [red, yellow];
    case 2:
      return [yellow, lightGreen];
    case 3:
    default:
      return [lightGreen, darkGreen];
  }
});

const blendColorValue = (v1: number, v2: number, weight: number) => {
  return v1 * (1 - weight) + v2 * weight;
};

const blendColors = (c1: RGB, c2: RGB, weight: number): RGB => {
  const [r1, g1, b1] = c1;
  const [r2, g2, b2] = c2;
  return [
    blendColorValue(r1, r2, weight),
    blendColorValue(g1, g2, weight),
    blendColorValue(b1, b2, weight),
  ];
};

const getRGBString = ([r, g, b]: RGB) => {
  return `rgb(${Math.floor(r)}, ${Math.floor(g)}, ${Math.floor(b)})`;
};

// const getRGBStyle = (c1: RGB, c2: RGB, weight: number) => {
//   return getRGBString(blendColors(c1, c2, weight));
// };

const percent = computed(() => {
  return (scale.value - 1) * 33.33 + weight.value * 33.33;
});

const leftPosition = computed(() => {
  return `${percent.value.toPrecision(3)}%`;
});

const rightClip = computed(() => {
  return `${Math.round(100 - percent.value)}%`;
});

const blendedColor = computed(() => {
  return blendColors(colors.value[0], colors.value[1], weight.value);
});

const backgroundColor = getRGBString(blendedColor.value);

const circleStyle = {
  backgroundColor,
  left: leftPosition.value,
};

const gradientStyle = {
  clipPath: `inset(0 ${rightClip.value} 0 0)`,
};

const ratingValueStyle = {
  backgroundColor,
};

console.log(props);
</script>

<style lang="postcss" scoped>
.gradient {
  background-color: theme(colors.yellow.400);
  background: linear-gradient(
    90deg,
    theme(colors.red.600) 0%,
    theme(colors.yellow.500) 33%,
    theme(colors.green.500) 66%,
    theme(colors.green.600) 100%
  );
}
</style>
