<script setup lang="ts">
import LoadingView from "@/components/LoadingView.vue";
import {computed, onMounted, ref, watch} from "vue";
import {getCategories, getCategoriesSumsRequest} from "@/services/categoryService";
import DataTable from "primevue/datatable";
import Column from "primevue/column";
import Chart from "primevue/chart";

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";
import {useSpaceStore} from "@/stores/spaceStore";
import router from "@/router";
import Button from "primevue/button";

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


const loading = ref(false);
const categoriesCatalog = ref([])
const categoriesCatalogGrouped = computed(() => {
  const cats = {}
   categoriesCatalog.value.forEach(category => {
    // Получаем значение type.code для текущей категории
    const typeCode = "<b>"+category.type.name+"</b>";

    // Если группы для данного typeCode ещё нет – создаём пустой массив
    if (!cats[typeCode]) {
      cats[typeCode] = [];
    }

    // Добавляем категорию в соответствующую группу
     cats[typeCode].push(category);
  })
  return cats
})

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 filterText = ref(null)


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

    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: string
    if (difference > 0) {
      color = "text-red-500"
    } else color = "text-green-600"
    sums[key] = "<p>" + formatter.value.format(sums[key]) + `</p><p class='${color}'>(` + difference.toFixed(0) + "%)</p>";
  });


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

const spaceStore  = useSpaceStore()
const selectedSpace = computed(() => spaceStore.space)

watch( selectedSpace, async (newValue, oldValue) => {
  if (newValue != oldValue) {
    await fetchCategoriesSums()
  }
})


const fetchCategoriesSums = async () => {
  loading.value = true;
  await getCategoriesSumsRequest(selectedSpace.value?.id).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().then((data) => {
    categoriesCatalog.value = data.data
    selectedCategory.value = data.data[0]
  })
}

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

<template>
  <LoadingView v-if="loading"/>
  <div v-else class="p-4 pb-20 lg:pb-4 bg-gray-100  flex flex-col gap-4 h-full items-center justify-items-center ">
    <div v-if="!selectedSpace" class="flex w-full h-full items-center justify-center">
      <p>Сперва нужно выбрать Пространство.
        <button class="text-blue-500 hover:underline" @click="router.push('/spaces').then((res) => router.go(0))">Перейти</button>
      </p>
    </div>
    <div v-else-if="dataTableCategories.length==0">
      Начните записывать траты и здесь появится информация.
    </div>
    <div v-else class="!items-center w-5/6  bg-white">
      <Accordion value="1" class=" " @tab-open="isChartOpen=true"
                 @tab-close="closeChart">
        <AccordionPanel value="0">
          <AccordionHeader>График</AccordionHeader>
          <AccordionContent>


            <div v-if="isChartOpen"
                 class="grid grid-cols-1 lg:grid-cols-6 w-full items-start justify-items-start">
              <!-- Список категорий -->
              <div class="sm:col-span-1 w-full h-56 lg:h-[42rem] p-2 overflow-y-scroll outline outline-1 outline-gray-300 rounded-lg">
<!--                <IconField>-->

<!--                  <InputText v-model="filterText" placeholder="Поиск категории"/>-->
<!--                  <InputIcon class="pi pi-search"/>-->
<!--                </IconField>-->
                <ul class=" min-w-fit w-full">

                  <li v-for="(category,catType) in categoriesCatalogGrouped"
                     >
                    <span v-html="catType"/>
                    <ul>
                      <li v-for="cat in category"  class="px-2 py-2 hover:bg-blue-50 rounded-md line-clamp- w-full"
                          :class="selectedCategory.id == cat.id? '!bg-emerald-50 text-emerald-700': '' " @click="selectedCategory=cat"> {{cat.name}}</li>
                    </ul>
                  </li>
                </ul>
              </div>

              <!-- Контейнер для графика с горизонтальной прокруткой -->
              <div class="sm:col-span-5 overflow-x-auto w-full">
                <!-- «Растяжка», чтобы было за что «скроллить» -->
                <div class="min-w-[550px] md:min-w-[650px] lg:min-w-[850px]">
                  <Chart
                      type="line"
                      :data="preparedChartData"
                      :options="chartOptions"
                      class="h-72 sm:h-full sm:w-full "
                  />
                </div>
              </div>
            </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) 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>
  </div>
</template>

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


</style>
