<script setup lang="ts">
import LoadingView from "@/components/LoadingView.vue";
import {computed, onMounted, ref} from "vue";
import {getCategories, getCategoriesSumsRequest} from "@/services/categoryService";
import DataTable from "primevue/datatable";
import Column from "primevue/column";
import Chart from "primevue/chart";
import Listbox from "primevue/listbox";
import Select from "primevue/select";
import Accordion from "primevue/accordion";
import AccordionPanel from "primevue/accordionpanel";
import AccordionHeader from "primevue/accordionheader";
import AccordionContent from "primevue/accordioncontent"
import ChartDataLabels from 'chartjs-plugin-datalabels';
import {Chart as ChartJS} from 'chart.js/auto';
import {Colors} from 'chart.js';
import {getMonthName} from "@/utils/utils";

ChartJS.register(ChartDataLabels);
ChartJS.register(Colors);


const loading = ref(true);
const categoriesCatalog = ref([])
const categories = ref([]);
const dataTableCategories = ref([]);
const tableColumns = ref([]);
const chartData = ref(null)
const selectedCategory = ref()
const formatter = ref(new Intl.NumberFormat('ru-RU', {style: 'currency', currency: 'RUB', minimumFractionDigits: 0, maximumFractionDigits:0}))
const isChartOpen = ref(false)

const closeChart = () => {
  setTimeout(() => {
    isChartOpen.value = false;
  }, 500)
}


const preparedChartData = computed(() => {
  if (categories.value && selectedCategory.value) {
    const r = Math.random() * 255
    const g = Math.random() * 255
    const b = Math.random() * 255
    const colorLine = `rgba(${r}, ${g}, ${b},1)` // Случайный цвет для графика
    const colorBackground = `rgba(${r}, ${g}, ${b},0.2)` // Случайный цвет для графика
    return {
      labels: categories.value[0].monthlySums.map((month) => month.date), // Используем даты как метки
      datasets: [{
        label: categories.value.filter((it) => selectedCategory.value.id == it._id)[0].categoryName, // Название категории
        data: categories.value.filter((it) => selectedCategory.value.id == it._id)[0].monthlySums.map((month) => month.total), // Данные по total
        borderColor: colorLine,
        fill: true,
        backgroundColor: colorBackground,
        tension: 0.4
      }]

    }
  }
})

const chartOptions = {
  responsive: true,
  plugins: {
    legend: {
      display: true,
      position: "top",
    },
    title: {
      display: true,
      text: "График расходов по категориям",
    },
    colors: {
      enabled: true,
    },
    datalabels: {
      formatter: function (value) {
        return formatter.value.format(value);
      },

      align: 'top',
      offset: 2,
      labels: {
        title: {
          font: {
            weight: 'bold'
          }
        },
        value: {
          color: 'green'
        }
      }
    }
  },
  scales: {
    x: {
      title: {
        display: true,
        text: "Месяц",
      },
    },
    y: {
      title: {
        display: true,
        text: "Сумма",
      },
    },
  },
}

// Преобразование данных для таблицы
const prepareTableData = (categories) => {
  // 1. Собираем все уникальные значения date из monthlySums
  const allDates = [
    ...new Set(
        categories.flatMap((category) =>
            category.monthlySums.map((sumItem) => sumItem.date)
        )
    ),
  ];

  // 2. Сортируем даты.
  //    Если у вас формат "YYYY-MM-DD", лексикографическая сортировка работает корректно хронологически:
  // allDates.sort((a, b) => a.localeCompare(b));

  // (Если хотите гарантированно использовать объекты Date, можно так:
  // allDates.sort((a, b) => new Date(a) - new Date(b));
  // Но тогда поля колонки будут тоже строками вида "2024-09-01" — обычно это ок.)

  // 3. Формируем колонки для DataTable:
  //    - Первый столбец: "category"
  //    - Далее по одному столбцу на каждую дату
  tableColumns.value = [
    {field: "category", header: "Категория"},
    ...allDates.map((dateStr) => ({field: dateStr, header: dateStr})),
    {field: "avg", header: "Среднее"},
  ];
  console.log(tableColumns.value[0].field);
  const sums = {}
  // 4. Формируем строки (для каждой категории)
  const rows = categories.map((category) => {
    // Начинаем со строки, где есть поле с именем категории
    const row = {category: category.categoryIcon + " " + category.categoryName};
    let categorySum = 0
    // Для каждой даты проверяем, есть ли в monthlySums соответствующая запись
    allDates.forEach((dateStr) => {
      const found = category.monthlySums.find((m) => m.date === dateStr);

      if (found.difference != 0) {
        if (found.difference > 0) {
          row[dateStr] = found ? formatter.value.format(found.total) + "<p class='text-red-500 text-sm'> (+ " + found.difference + "%)</p>" : 0;
        } else {
          row[dateStr] = found ? formatter.value.format(found.total) + "<p class='text-green-600 text-sm'>  (" + found.difference + "%)</p>" : 0;
        }
      } else {
        row[dateStr] = found ? formatter.value.format(found.total) : 0;
      }
      if (!sums[dateStr]) {
        sums[dateStr] = 0
      }
      sums[dateStr] += found.total
      categorySum += found.total
    });
    row["avg"] = formatter.value.format(categorySum/allDates.length);

    return row;
  });


  let previousSum = 0;
  Object.keys(sums).forEach(key => {

    console.log(previousSum)
    let difference = previousSum != 0 ? ((sums[key] - previousSum) / previousSum) * 100 : 0
    if (sums[key] != previousSum) {
      previousSum = sums[key];
    }
    let color = ""
    if (difference > 0) {
      color = "text-red-500"
    } else color = "text-green-600"
    sums[key] = formatter.value.format(sums[key]) + `<p class='${color}'>(` + difference.toFixed(0) + "%)</p>";
  });


  rows.push(sums);
  return rows;
};


const fetchCategoriesSums = async () => {
  loading.value = true;
  await getCategoriesSumsRequest().then((data) => {
    data.data.forEach((category) => {
      category.monthlySums.forEach((monthlySum) => {
        monthlySum.date = getMonthName(new Date(monthlySum.date).getMonth()) + " " + new Date(monthlySum.date).getFullYear()
      })
    })
    categories.value = data.data;
    console.log(categories.value);

    dataTableCategories.value = prepareTableData(data.data);

  });

  loading.value = false;
};

const fetchCategoriesCatalog = async () => {
  await getCategories("EXPENSE").then((data) => {
    categoriesCatalog.value = data.data
    selectedCategory.value = data.data[0]
  })
}

onMounted(async () => {
  await Promise.all([fetchCategoriesSums(), fetchCategoriesCatalog()])
  // await fetchCategoriesSums();
});
</script>

<template>
  <LoadingView v-if="loading"/>
  <div v-else class="p-4 bg-gray-100 h-full flex flex-col gap-4 items-center justify-items-center ">

    <Accordion value="0" class=" !w-5/6 !items-center !justify-items-start" @tab-open="isChartOpen=true"
               @tab-close="closeChart">
      <AccordionPanel value="1">
        <AccordionHeader>График</AccordionHeader>
        <AccordionContent class="items-center justify-items-center ">

          <!--          <Select v-model="selectedCategory" :options="categoriesCatalog" optionLabel="name"-->
          <!--                  placeholder="Выберите категории"-->
          <!--                  :maxSelectedLabels="3" class="w-full md:w-80"/>-->
          <div v-if="isChartOpen" class="flex flex-row items-start justify-items-start w-full">
            <Listbox v-model="selectedCategory" :options="categoriesCatalog" filter optionLabel="name"
                     class="!w-fit !h-5/6 md:w-56">

              <template #option="slotProps">
                <div>{{ slotProps.option.icon }} {{ slotProps.option.name }}</div>
              </template>

            </Listbox>
            <Chart type="line" :data="preparedChartData" :options="chartOptions" class="!w-5/6 !h-full"/>
          </div>
        </AccordionContent>
      </AccordionPanel>
    </Accordion>


    <DataTable :value="dataTableCategories" responsiveLayout="scroll" filter stripedRows class="w-5/6   items-center">
      <Column
          :field="tableColumns[0].field"
          :header="tableColumns[0].header"
          :bodyCellClass="'bold-column'"
          :headerCellClass="'bold-column'"
          class="font-bold"
      />

      <!-- Остальные колонки -->
      <Column
          v-for="(col, index) in tableColumns.slice(1)"
          :key="col.field"
          :field="col.field"
          :header="col.header"
      >
        <template #body="{ data }">
          <span v-html="data[col.field] " class="text-center"></span>
        </template>
      </Column>
    </DataTable>
  </div>
</template>

<style>
.p-accordioncontent-content {
  display: flex;
  flex-direction: row;
  align-items: start;
  align-content: center;
  justify-content: center;
}

.p-listbox-list-container {
  max-height: 100% !important;
}
</style>
