<script setup lang="ts" xmlns="http://www.w3.org/1999/html">
import {computed, onMounted, ref, watch, reactive, onUnmounted} from 'vue';
import Chart from 'primevue/chart';
import BudgetTransactionView from "@/components/budgets/BudgetTransactionView.vue";
import {
  getBudgetCategories,
  getBudgetInfo,
  getBudgetTransactions,
  updateBudgetCategoryRequest,
  getWarns,
  hideWarnRequest
} from "@/services/budgetsService";
import {Budget, BudgetCategory, Warn} from "@/models/Budget";
import {useRoute} from "vue-router";
import {formatAmount, formatDate, getMonthName, getMonthName2} from "@/utils/utils";
import ProgressBar from "primevue/progressbar";
import {Transaction} from "@/models/Transaction";
import Toast from "primevue/toast";
import LoadingView from "@/components/LoadingView.vue";
import ChartDataLabels from 'chartjs-plugin-datalabels';
import {Chart as ChartJS} from 'chart.js/auto';
import SelectButton from "primevue/selectbutton";
import Divider from "primevue/divider";
import {useDrawerStore} from "@/stores/drawerStore";
import {EventBus} from '@/utils/EventBus.ts';
import {useToast} from "primevue/usetoast";

// Зарегистрируем плагин
ChartJS.register(ChartDataLabels);


const loading = ref(true);
const updateLoading = ref(false);
const route = useRoute()
const detailedShowed = ref(false);
const selectedChart = ref({"label": "bar", "icon": "pi pi-chart-bar", "value": "bar"});
const modes = [
  {label: 'bar', icon: 'pi pi-chart-bar', value: 'bar'},
  {label: 'pie', icon: 'pi pi-chart-pie', value: 'pie'}
];


const value = ref(50)

const warnsOpened = ref(false);

const hideWarn = async (warnId: string) => {
  await hideWarnRequest(route.params.id, warnId)
  await fetchWarns()
}

const leftForUnplanned = ref(0)


const budget = ref<Budget>()
const warns = ref<[Warn]>()
const checkWarnsExists = computed(() => {

  return warns?.value?.length > 0;
});
const categories = ref<BudgetCategory[]>([])
const incomeCategories = ref<BudgetCategory[]>([])

const plannedIncomes = ref<Transaction[]>([])
const totalIncomes = computed(() => {
  let totalIncome = 0;
  plannedIncomes.value.forEach((i) => {
    totalIncome += i.amount
  })
  return totalIncome
})

const totalInstantIncomes = computed(() => {
  let totalIncome = 0;
  transactions.value.filter(t => t.type.code == 'INSTANT' && t.category.type.code == 'INCOME').forEach((i) => {
    totalIncome += i.amount
  })
  return totalIncome
})

const totalIncomeLeftToGet = computed(() => {
  let totalIncomeLeftToGet = 0;
  plannedIncomes.value.forEach(i => {
    if (!i.isDone) {
      totalIncomeLeftToGet += i.amount
    }
  })
  return totalIncomeLeftToGet
})

const totalLoans = computed(() => {
  let value = 0
  categories.value.filter((cat) => cat.category.id == "677bc767c7857460a491bd49").forEach(cat => {
    value += cat.currentLimit
  })
  return value
})

const loansRatio = computed(() => {

  return totalExpenses.value == 0 ? 0 : totalLoans.value / totalExpenses.value * 100
})


const savingRatio = computed(() => {

  return totalExpenses.value == 0 ? 0 : totalSaving.value / totalExpenses.value * 100
})

const totalSaving = computed(() => {
  let value = 0
  categories.value.filter((cat) => cat.category.id == "677bc767c7857460a491bd4f").forEach(cat => {
    value += cat.currentLimit
  })
  return value
})


const drawerOpened = ref(false)
const transactionType = ref('')
const categoryType = ref('')

const drawerStore = useDrawerStore()
const openDrawer = (selectedTransactionType = null, selectedCategoryType = null, categoryId = null) => {

  if (selectedTransactionType) {
    drawerStore.setTransactionType(selectedCategoryType)
  } else drawerStore.setCategoryType("INSTANT")
  if (selectedCategoryType) {
    drawerStore.setCategoryType(selectedCategoryType)
  } else drawerStore.setCategoryType("EXPENSE")
  if (categoryId) {
    drawerStore.setCategoryId(categoryId)
  } else drawerStore.setCategoryId(null)

  drawerOpened.value = true;
  drawerStore.visible = true
}

const closeDrawer = async () => {
  drawerOpened.value = false;
  // await updateTransactions()
}

const dailyRatio = computed(() => {
  const value = totalExpenses.value == 0 ? 0 : (totalExpenses.value - totalLoans.value - totalSaving.value) / totalExpenses.value

  return value * 100
})
const fetchPlannedIncomes = async () => {
  plannedIncomes.value = await getBudgetTransactions(route.params.id, 'PLANNED', 'INCOME')
}
const plannedExpenses = ref<Transaction[]>([])
const totalExpenses = computed(() => {
  let totalExpense = 0;
  categories.value.forEach((cat) => {
    let catValue = cat.currentLimit

    //   plannedExpenses.value.filter(t => t.category.id == cat.category.id).forEach((i) => {
    //
    //     catValue += i.amount
    //   })
    //
    totalExpense += catValue
  })

  return totalExpense
})


const totalPlannedExpenses = computed(() => {
  let expenses = 0
  plannedExpenses.value.forEach((t) => {
    expenses += t.amount
  })
  return expenses
})

const totalInstantExpenses = computed(() => {
  let totalExpenses = 0;
  transactions.value.filter(t => t.type.code == 'INSTANT' && t.category.type.code == 'EXPENSE').forEach((i) => {
    totalExpenses += i.amount
  })
  return totalExpenses
})
const totalExpenseLeftToSpend = computed(() => {
  let totalExpenseLeftToSpend = 0;
  plannedExpenses.value.forEach(i => {
    if (!i.isDone) {
      totalExpenseLeftToSpend += i.amount
    }
  })
  return totalExpenseLeftToSpend
})
const fetchPlannedExpenses = async () => {
  plannedExpenses.value = await getBudgetTransactions(route.params.id, 'PLANNED', 'EXPENSE')
  updateLoading.value = false
}
const transactions = ref<Transaction[]>([])

const selectedCategoryId = ref()
const selectCategoryType = (categoryId) => {
  if (selectedCategoryId.value == categoryId) {
    selectedCategoryId.value = null
  } else {
    selectedCategoryId.value = categoryId
  }
}
const filteredTransactions = computed(() => {
  return selectedCategoryId.value ? transactions.value.filter(i => i.category.id == selectedCategoryId.value) : transactions.value
})
const fetchBudgetTransactions = async () => {
  transactions.value = await getBudgetTransactions(route.params.id, 'INSTANT')
  updateLoading.value = false
}
// 1️⃣ Создаём отдельное состояние для категорий расходов и доходов
const expenseCategoriesState = reactive<Record<string, { isOpened: boolean }>>({});
const incomeCategoriesState = reactive<Record<string, { isOpened: boolean }>>({});

// 2️⃣ Инициализируем состояние для категорий расходов по plannedExpenses
watch(
    () => categories.value,
    (newExpenses) => {
      newExpenses.forEach((expense) => {
        // console.log(expense.category.id);
        const categoryId = expense.category.id;
        if (!(categoryId in expenseCategoriesState)) {
          expenseCategoriesState[categoryId] = {isOpened: true};
        }
      });
    },
    {immediate: true}
);

// 3️⃣ Инициализируем состояние для категорий доходов по plannedIncomes
watch(
    () => plannedIncomes.value,
    (newIncomes) => {
      newIncomes.forEach((income) => {
        const categoryId = income.category.id;
        if (!(categoryId in incomeCategoriesState)) {
          incomeCategoriesState[categoryId] = {isOpened: true};
        }
      });
    },
    {immediate: true}
);

// 4️⃣ Computed для группировки транзакций расходов по категориям
const categoriesTransactions = computed(() => {
  const grouped: Record<string, { name: any; transactions: any[]; isOpened: boolean }> = {};

  // Создаем группу для каждой категории из списка категорий расходов (categories)
  categories.value.forEach((category) => {
    grouped[category.category.id] = {
      name: category,
      transactions: [],
      isOpened: expenseCategoriesState[category.category.id]?.isOpened ?? true,
    };
  });

  // Добавляем транзакции расходов (plannedExpenses)
  plannedExpenses.value.forEach((plannedExpense) => {
    const categoryId = plannedExpense.category.id;
    if (!grouped[categoryId]) {
      grouped[categoryId] = {
        name: plannedExpense.category,
        transactions: [],
        isOpened: expenseCategoriesState[categoryId]?.isOpened ?? true,
      };
    }
    grouped[categoryId].transactions.push(plannedExpense);
  });

  // Преобразуем объект в массив, сортируем, затем превращаем обратно в объект
  return Object.fromEntries(
      Object.entries(grouped).sort(([, a], [, b]) => {
        // Сортируем по количеству транзакций (по убыванию)
        if (b.transactions.length !== a.transactions.length) {
          return b.transactions.length - a.transactions.length;
        }
        // Если количество транзакций одинаковое, сортируем по currentLimit (по убыванию)
        return (b.name.currentLimit ?? 0) - (a.name.currentLimit ?? 0);
      })
  );
});

// 5️⃣ Computed для группировки транзакций доходов по категориям
const categoriesIncomeTransactions = computed(() => {
  const grouped: Record<string, { name: any; transactions: any[]; isOpened: boolean }> = {};

  plannedIncomes.value.forEach((plannedIncome) => {
    const categoryId = plannedIncome.category.id;
    if (!grouped[categoryId]) {
      const categoryDetails = incomeCategories.value.find(
          (cat) => cat.category.id === categoryId
      );
      grouped[categoryId] = {
        name: categoryDetails,
        transactions: [],
        isOpened: incomeCategoriesState[categoryId]?.isOpened ?? true,
      };
    }
    grouped[categoryId].transactions.push(plannedIncome);
  });

  return grouped;
});

const updateTransactions = async () => {
  setTimeout(async () => {
    await Promise.all([fetchBudgetInfo(), fetchWarns()])

  },)

}


const fetchBudgetCategories = async () => {
  categories.value = await getBudgetCategories(route.params.id)
  categories.value = [...categories.value];
  updateLoading.value = false
}

const transactionCategoriesSums = computed(() => {
  // Используем reduce для создания массива сумм по категориям
  return transactions.value.reduce((acc, transaction) => {
    const category = transaction.category;

    // Проверяем, существует ли категория в аккумуляторе
    const existingCategory = acc.find(item => item.category.id === category.id);

    if (existingCategory) {
      // Если категория существует, добавляем сумму к текущей
      existingCategory.sum += transaction.amount;

    } else {
      // Если категории еще нет в аккумуляторе, добавляем ее
      acc.push({category: category, sum: transaction.amount});
    }

    return acc;
  }, []);
});


// const fetchBudgetTransactionCategoriesSums = async () => {
//
//   transactionCategoriesSums.value = await getBudgetCategoriesSums(route.params.id)
//   updateLoading.value = false
// }
const editingCategoryId = ref<string | null>(null);
const editableLimit = ref<Record<string, number>>({});

const startEditing = (category) => {
  editingCategoryId.value = category.name.category.id;
  editableLimit.value[category.name.category.id] = category.name.currentLimit;
};

const saveLimit = async (category) => {
  const categoryId = category.name.id;
  if (editableLimit.value[categoryId] !== undefined) {
    try {
      await updateLimitOnBackend(categoryId, editableLimit.value[categoryId]);
      category.name.currentLimit = editableLimit.value[categoryId]; // Обновляем локально
    } catch (error) {
      console.error("Ошибка обновления лимита:", error);
    }
  }
  editingCategoryId.value = null; // Закрываем input
};

// Функция для отправки данных на бэкенд (замени URL и метод)
const updateLimitOnBackend = async (categoryId, newLimit) => {
  await fetch(`/api/categories/${categoryId}/limit`, {
    method: "PUT",
    headers: {"Content-Type": "application/json"},
    body: JSON.stringify({limit: newLimit}),
  });
};

const toast = useToast();
const budgetInfo = ref<Budget>();
const fetchBudgetInfo = async (test) => {
  try {
    await getBudgetInfo(route.params.id).then((data) => {
          budget.value = data
          plannedExpenses.value = budget.value?.plannedExpenses
          plannedIncomes.value = budget.value?.plannedIncomes
          transactions.value = budget.value?.transactions
          categories.value = budget.value?.categories
          incomeCategories.value = budget.value?.incomeCategories
          updateLoading.value = false
        }
    ).catch((error) => {
      loading.value = false
      updateLoading.value = false

      toast.add({
        severity: 'error',
        summary: 'Ошибка!',
        detail: error.response?.data?.message || 'Ошибка при создании транзакции',
        life: 3000
      });
    })
  } catch (error) {
    toast.add({severity: 'error', summary: "Ошибка при получении бюджета", detail: error.message, life: 3000});
  }
  updateLoading.value = false
  loading.value = false


}


const updateBudgetCategory = async (category, newValue) => {
  category.currentLimit = newValue
  // loading.value = true
  await updateBudgetCategoryRequest(budget.value.id, category)
  await fetchBudgetInfo()
  setTimeout(async () => {
    await fetchWarns()
  }, 0)
  editingCategoryId.value = null
}

const twentyFour = computed(() => {
  let twentyFour = new Date(budget.value?.dateFrom)
  twentyFour.setDate(24)
  return twentyFour
})

const incomesByPeriod = computed(() => {
  let incomesUntil25 = 0
  let incomesFrom25 = 0
  plannedIncomes.value.forEach((i) => {
    i.date = new Date(i.date)

    if (i.date >= budget.value?.dateFrom && i.date <= twentyFour.value) {

      incomesUntil25 += i.amount
    } else {
      incomesFrom25 += i.amount
    }
  })

  return [incomesUntil25, incomesFrom25]
})


const expensesByPeriod = computed(() => {
  let expensesUntil25 = 0
  let expensesFrom25 = 0
  let totalPlannedExpensesSum = 0
  plannedExpenses.value.forEach((i) => {
    i.date = new Date(i.date)
    if (i.date >= budget.value?.dateFrom && i.date <= twentyFour.value) {
      expensesUntil25 += i.amount
    } else {
      expensesFrom25 += i.amount
    }
    totalPlannedExpensesSum += i.amount
  })
  categories.value.forEach((i) => {
    expensesUntil25 += (i.currentLimit - i.currentPlanned) / 2
    expensesFrom25 += (i.currentLimit - i.currentPlanned) / 2

  })

  return [expensesUntil25, expensesFrom25]
})

const pieChartData = computed(() => {

  let labels = []
  let values = []
  categories.value.forEach((i) => {
    labels.push(i.category.name)
    values.push(i.currentLimit / totalExpenses.value)
  })
  return {
    labels: labels,
    datasets: [
      {
        clip: {left: 100, top: false, right: 50, bottom: 0},
        radius: '100%',
        data: values,
        backgroundColor: [
          'rgba(6, 182, 212, 0.2)', 'rgba(249, 115, 22, 0.2)', 'rgba(50, 205, 50, 0.2)',
          'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)',
          'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)',
          'rgba(123, 239, 178, 0.2)', 'rgba(255, 105, 180, 0.2)', 'rgba(147, 112, 219, 0.2)',
          'rgba(60, 179, 113, 0.2)', 'rgba(100, 149, 237, 0.2)', 'rgba(220, 20, 60, 0.2)',
          'rgba(255, 140, 0, 0.2)', 'rgba(72, 61, 139, 0.2)', 'rgba(210, 105, 30, 0.2)',
          'rgba(106, 90, 205, 0.2)', 'rgba(199, 21, 133, 0.2)', 'rgba(32, 178, 170, 0.2)',
          'rgba(65, 105, 225, 0.2)', 'rgba(218, 165, 32, 0.2)', 'rgba(255, 127, 80, 0.2)',
          'rgba(46, 139, 87, 0.2)', 'rgba(139, 69, 19, 0.2)', 'rgba(75, 0, 130, 0.2)',
          'rgba(255, 69, 0, 0.2)', 'rgba(244, 164, 96, 0.2)'
        ],
        hoverBackgroundColor: [
          'rgba(6, 182, 212, 1)', 'rgba(249, 115, 22, 1)', 'rgba(50, 205, 50, 1)',
          'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)',
          'rgba(123, 239, 178, 1)', 'rgba(255, 105, 180, 1)', 'rgba(147, 112, 219, 1)',
          'rgba(60, 179, 113, 1)', 'rgba(100, 149, 237, 1)', 'rgba(220, 20, 60, 1)',
          'rgba(255, 140, 0, 1)', 'rgba(72, 61, 139, 1)', 'rgba(210, 105, 30, 1)',
          'rgba(106, 90, 205, 1)', 'rgba(199, 21, 133, 1)', 'rgba(32, 178, 170, 1)',
          'rgba(65, 105, 225, 1)', 'rgba(218, 165, 32, 1)', 'rgba(255, 127, 80, 1)',
          'rgba(46, 139, 87, 1)', 'rgba(139, 69, 19, 1)', 'rgba(75, 0, 130, 1)',
          'rgba(255, 69, 0, 1)', 'rgba(244, 164, 96, 1)'
        ]

      }
    ]
  };
})
const pieChartOptions = ref({
  layout: {
    padding: {
      left: 50, // Добавляем отступ слева
      right: 50 // Добавляем отступ справа
    }
  },
  plugins: {
    legend: {
      display: false // Отключаем легенду
    },
    datalabels: {
      anchor: 'end', // Позиция метки относительно данных
      align: 'top', // Выравнивание метки
      formatter: (value, context) => {
        const label = context.chart.data.labels[context.dataIndex];
        const percentage = (value * 100).toFixed(0);
        return percentage >= 2 ? `${label} ${percentage}%` : '';
      },
      color: 'black', // Цвет текста метки
      font: {
        size: 12 // Устанавливаем меньший размер шрифта
      }
    },
    tooltip: {
      enabled: true, // Включить tooltips
      callbacks: {
        title: function (tooltipItems) {
          return tooltipItems[0].dataset.label;
        },
        label: function (tooltipItems) {
          return Number(tooltipItems.formattedValue * 100).toFixed(0) + '%';
        }
      }
    }
  }
});


const incomeExpenseChartData = computed(() => {

  return {
    labels: ['до 25 ', 'с 25'],
    datasets: [
      {
        label: 'Пополнения',
        data: incomesByPeriod.value,
        backgroundColor: ['rgba(6, 182, 212, 0.2)', 'rgba(6, 182, 212, 0.2)'],
        borderColor: ['rgb(6, 182, 212)', 'rgb(6, 182, 212)'],
        borderWidth: 1
      },
      {
        label: 'Расходы',
        data: expensesByPeriod.value,
        backgroundColor: ['rgba(249, 115, 22, 0.2)', 'rgba(249, 115, 22, 0.2)'],
        borderColor: ['rgb(249, 115, 22)', 'rgb(249, 115, 22)'],
        borderWidth: 1
      }
    ]
  }
})
const incomeExpenseChartOptions = ref({

  plugins: {
    legend: {
      display: false // Отключаем легенду
    },
    datalabels: {
      anchor: 'end', // Позиция метки относительно данных
      align: 'top', // Выравнивание метки
      formatter: (value) => {
        // const label = context.chart.data.labels[context.dataIndex];

        return formatAmount(value) + '₽';
        // return percentage >= 2 ? `${percentage} ` : '';
      },
      color: 'black', // Цвет текста метки
      font: {
        size: 12 // Устанавливаем меньший размер шрифта
      }
    },
    tooltip: {
      enabled: true, // Включить tooltips
      callbacks: {
        title: function (tooltipItems) {
          return tooltipItems[0].dataset.label;
        },
        label: function (tooltipItems) {
          return formatAmount(tooltipItems.raw) + '₽';
        }
      }
    }
  }
})

const fetchWarns = async (hidden: Boolean = null) => {
  warns.value = await getWarns(route.params.id, hidden)
}

const catsExpanded = ref(true);

const expandCats = (value: boolean) => {
  catsExpanded.value = value;

  // Обновляем состояние для категорий доходов
  for (const categoryId in incomeCategoriesState) {
    if (Object.prototype.hasOwnProperty.call(incomeCategoriesState, categoryId)) {
      incomeCategoriesState[categoryId].isOpened = value;

    }
  }

  // Обновляем состояние для категорий расходов
  for (const categoryId in expenseCategoriesState) {
    if (Object.prototype.hasOwnProperty.call(expenseCategoriesState, categoryId)) {
      expenseCategoriesState[categoryId].isOpened = value;

    }
  }
};

const calendarOpened = ref(localStorage.getItem('budgetCalendarOpened') === "1");

// Используем computed для получения значения
const calendarExpanded = computed(() => calendarOpened.value);

// Функция для переключения состояния
const toggleCalendar = () => {
  // Переключаем состояние
  calendarOpened.value = !calendarOpened.value;

  // Сохраняем в localStorage
  localStorage.setItem('budgetCalendarOpened', calendarOpened.value ? "1" : "0");
};

const calendar = ref<{ date: Date, dateStr: string, expenses: any[], expensesSum: number }[]>([]);

watch([budget, plannedExpenses], () => {
  if (!budget.value?.dateFrom || !budget.value?.dateTo) {
    calendar.value = [];
    return;
  }

  const result: { date: Date, dateStr: string, expenses: any[], expensesSum: number, }[] = [];

  const startDate = new Date(budget.value.dateFrom);
  const endDate = new Date(budget.value.dateTo);
  let currentDate = new Date(startDate);
  let lastDateWithExpenses = null;
  let periodStart = null;

  while (currentDate <= endDate) {
    const formattedDate = currentDate.toISOString().split("T")[0];
    const expenses = plannedExpenses.value.filter((transaction) => {
      return transaction.date === formattedDate;
    });
    const expensesSum = expenses.reduce((sum, expense) => {
      return !expense.isDone ? sum + (expense.amount || 0) : sum;
    }, 0);

    if (expenses.length == 0) {
      if (!periodStart) periodStart = new Date(currentDate); // Сохраняем начало периода без трат
    } else {
      if (lastDateWithExpenses && periodStart) {
        // Добавляем период без трат, если он был
        result.push({
          date: currentDate,
          dateStr: periodStart.toLocaleDateString('ru-RU') === new Date(new Date(currentDate).setDate(currentDate.getDate() - 1)).toLocaleDateString('ru-RU')
              ? periodStart.getUTCDate() + " " + getMonthName2(periodStart.getMonth(), "род") + " " + periodStart.getUTCFullYear() + ' трат нет.'
              : `В период с ${periodStart.toLocaleDateString('ru-RU')} по ${new Date(new Date(currentDate).setDate(currentDate.getDate() - 1)).toLocaleDateString('ru-RU')} трат нет.`,
          expenses: [],
          expensesSum: 0,
        });
        periodStart = null;
      }

      // Добавляем день с тратами
      lastDateWithExpenses = new Date(currentDate)
      result.push({
        date: currentDate,
        dateStr: currentDate.getUTCDate() + " " + getMonthName2(currentDate.getMonth(), "род") + " " + currentDate.getUTCFullYear(),
        expenses: expenses,
        expensesSum: expensesSum,
      });

      // lastDateWithExpenses = new Date(currentDate); // Сохраняем дату с тратами
    }

    currentDate.setDate(currentDate.getDate() + 1);
  }

  // Добавляем последний период без трат, если он был
  if (lastDateWithExpenses && periodStart) {
    result.push({
      date: currentDate,
      dateStr: `В период с ${periodStart.toLocaleDateString('ru-RU')} по ${lastDateWithExpenses.toLocaleDateString('ru-RU')} трат нет.`,
      expenses: [],
      expensesSum: 0
    });
    periodStart = null;
  }

  calendar.value = result;
}, {immediate: true});

onMounted(() => {
  updateLoading.value = true;

  fetchBudgetInfo()
  fetchWarns()
  EventBus.on('transactions-updated', fetchBudgetInfo, true);
})

  onUnmounted(async () => {
    EventBus.off('transactions-updated', fetchBudgetInfo);
  })
</script>

<template>
  <Toast/>
  <LoadingView v-if="loading"/>

  <div v-else class="px-4 bg-gray-100 h-full ">

    <div class=" flex flex-col gap-3">
      <div class="flex flex-row justify-between ">
        <div class="flex flex-col gap-2">
          <h2 class="text-4xl  font-bold">Бюджет {{ budget.name }} </h2>
          <div class="flex flex-row gap-2 text-xl">{{ formatDate(budget.dateFrom) }} -
            {{ formatDate(budget.dateTo) }}
          </div>
        </div>

        <div class="flex flex-col gap-2 justify-center">
          <button class="flex flex-row bg-white py-6 px-4 shadow-lg rounded-lg items-center h-6 justify-center gap-2"
                  @click="warnsOpened = !warnsOpened">
            <span class="bg-gray-300 p-1 rounded font-bold">{{
                warns ? warns.length : 0
              }}</span><span>Уведомлений</span>
          </button>

          <div v-if="warnsOpened"
               class="absolute h-fit max-h-128 w-128 overflow-auto  bg-white shadow-lg rounded-lg top-32 right-4 z-50">
            <div v-if="checkWarnsExists" class="flex flex-col p-4">
              <div v-for="warn in warns">
                <div class="flex flex-row items-center gap-2 justify-between">

                  <div class="flex flex-row items-center gap-2">
                    <div class="text-2xl">{{ warn.message.icon }}</div>
                    <div class="flex flex-col">
                      <span class="font-bold">{{ warn.message.title }}</span>
                      <span v-html="warn.message.body"></span>
                    </div>
                  </div>
                  <button @click="hideWarn(warn.id)"><i class="pi pi-times" style="font-size: 0.7rem"></i></button>
                </div>
                <Divider/>
              </div>
            </div>
            <div v-else class="flex items-center justify-center p-16">
              <button @click="fetchWarns(true)">Показать скрытые</button>
            </div>
          </div>

        </div>
      </div>

      <!--      hui {{calendar}}-->

      <div class="flex flex-col gap-2">
        <!-- Аналитика и плановые доходы/расходы -->
        <div class="grid grid-cols-1 lg:grid-cols-3 gap-4 items-start ">
          <div class="flex flex-col gap-4">
            <!-- Блок Аналитики (25%) -->
            <div
                class="bg-white p-4 shadow-lg rounded-lg flex flex-col gap-4 items-start ">
              <h3 class="text-xl font-bold">Аналитика</h3>

              <SelectButton v-model="selectedChart" :options="modes" optionLabel="label" optionIcon="icon">
                <template #option="slotProps">
                  <i :class="slotProps.option.icon"></i>
                </template>
              </SelectButton>
              <Chart v-if="selectedChart.value=='bar'" type="bar" :data="incomeExpenseChartData"
                     :options="incomeExpenseChartOptions" class="!w-full"
                     style="width: 100%"/>

              <Chart v-if="selectedChart.value=='pie'" type="pie" :data="pieChartData" :options="pieChartOptions"
                     class="chart "/>

              <div class="flex gap-5 items-center  justify-items-center w-full ">
                <div class="w-full">
                  <button class="grid grid-cols-2 gap-5 items-center w-full" @click="detailedShowed = !detailedShowed">
                    <div class="flex flex-col items-center font-bold ">
                      <h4 class="text-lg font-bold">Поступления</h4>

                      <div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
                        +{{ formatAmount(totalIncomes) }}
                        ₽
                      </div>
                      <!--              <p>Total Incomes</p>-->
                    </div>
                    <div class="flex flex-col items-center ">
                      <h4 class="text-lg font-bold ">Расходы</h4>

                      <div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center"
                           :class="totalExpenses > totalIncomes ? ' text-red-700' : ''">
                        -{{ formatAmount(totalExpenses) }} ({{ formatAmount(totalExpenses - totalIncomes) }})
                        ₽
                      </div>
                    </div>
                  </button>


                  <div class="grid grid-cols-2 !gap-1 mt-4" :class="detailedShowed ? 'block' : 'hidden'">
                    <div class="flex flex-col items-center font-bold ">
                      <p class="font-light ">в первый период</p>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center  w-full ">
                        +{{ formatAmount(incomesByPeriod[0]) }} ₽
                      </div>
                    </div>
                    <div class="flex flex-col  items-center">
                      <p class="font-light ">в первый период</p>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center  w-full ">
                        -{{ formatAmount(expensesByPeriod[0]) }} ₽
                      </div>
                    </div>
                    <div class="flex flex-col  items-center">
                      <p class="font-light ">во второй период</p>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center   w-full ">
                        +{{ formatAmount(incomesByPeriod[1]) }} ₽
                      </div>

                    </div>
                    <div class="flex flex-col  items-center">
                      <p class="font-light ">во второй период</p>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center   w-full ">
                        -{{ formatAmount(expensesByPeriod[1]) }} ₽
                      </div>
                    </div>

                  </div>
                </div>

              </div>
              <div class="grid gap-5 items-center  justify-items-center w-full">
                <div class="w-full">
                  <button class="grid grid-cols-3 justify-between  gap-5 items-end w-full"
                          @click="detailedShowed = !detailedShowed">
                    <div class="flex flex-col items-center">
                      <h4 class="text-sm lg:text-base">Долги</h4>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
                        {{ loansRatio.toFixed(0) }} %
                      </div>
                      <!--              <p>Total Incomes</p>-->
                    </div>
                    <div class="flex flex-col items-center ">
                      <span class="text-sm lg:text-base">Сбережения</span>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center"
                           :class="savingRatio < 30 ? '!font-bold text-red-700' : ''">
                        {{ savingRatio.toFixed(0) }} %
                      </div>
                    </div>
                    <div class="flex flex-col items-center ">
                      <h4 class="text-sm lg:text-base">Ежедневные</h4>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
                        {{ dailyRatio.toFixed(0) }} %
                      </div>
                    </div>
                  </button>

                </div>
                <div class="w-full">
                  <button class="grid grid-cols-2 justify-between  gap-5 items-end w-full"
                          @click="detailedShowed = !detailedShowed">
                    <div class="flex flex-col items-center">
                      <h4 class="text-sm lg:text-base">Факт. поступления ✅</h4>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
                        {{ formatAmount(totalInstantIncomes) }} ₽
                      </div>
                      <!--              <p>Total Incomes</p>-->
                    </div>
                    <div class="flex flex-col items-center ">
                      <span class="text-sm lg:text-base">Факт. траты 📛</span>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
                        {{ formatAmount(totalInstantExpenses) }} ₽
                      </div>
                    </div>

                  </button>
                  <div class="flex flex-col items-center w-full ">
                    <span class="text-sm lg:text-base">Остаток на траты</span>
                    <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
                      {{ formatAmount(totalInstantIncomes - totalInstantExpenses) }} ₽
                    </div>
                  </div>
                  <div class="grid grid-cols-2 !gap-1 mt-4" :class="detailedShowed ? 'block' : 'hidden'">
                    <div v-for="categorySum in transactionCategoriesSums" class="flex flex-col items-center font-bold ">
                      <p class="font-light ">{{ categorySum.category.icon }} {{ categorySum.category.name }}</p>
                      <div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner text-center  w-full ">
                        {{ formatAmount(categorySum.sum) }} ₽
                      </div>
                    </div>
                  </div>
                </div>

              </div>
              <ProgressBar :value="value" class="mt-2 col-span-2" style="height: 1rem !important;"></ProgressBar>

            </div>
            <div class=" h-fit overflow-y-auto gap-4 flex-col row-span-6  hidden lg:flex">
              <div class="flex flex-row gap-4">
                <h3 class="text-2xl font-bold">Транзакции</h3>
                <button @click="openDrawer('INSTANT', 'EXPENSE')">
                  <span class="font-light text-sm">+ Добавить</span>
                </button>
              </div>
              <div class=" flex gap-2 overflow-x-auto ">

                <button v-for="categorySum in transactionCategoriesSums"
                        @click="selectCategoryType(categorySum.category.id)"
                        class="rounded-xl border p-1 bg-white border-gray-300 mb-2 min-w-fit px-2"
                        :class="selectedCategoryId == categorySum.category.id ? '!bg-blue-100' : ''">
                  <p><span class="text-sm font-bold">{{ categorySum.category.name }}</span>: {{ categorySum.sum }} ₽</p>

                </button>
              </div>
              <div class="flex flex-col gap-1 max-h-tlist overflow-y-auto ">
                <BudgetTransactionView v-for="transaction in filteredTransactions" :key="transaction.id"
                                       :transaction="transaction"
                                       :is-list="true"
                                       @transaction-updated="updateTransactions"
                                       @transaction-checked="updateTransactions"
                />
              </div>
            </div>

          </div>

          <div class="grid grid-cols-1 gap-4 row-span-3 col-span-2">
            <div>
              <!-- Планируемые доходы -->
              <div>
                <div class="flex flex-row gap-4 items-center mb-4">
                  <h3 class="text-2xl font-bold text-emerald-500 ">Поступления</h3>
                  <button @click="openDrawer('PLANNED', 'INCOME')">
                    <!--                    <i class="pi pi-plus-circle text-green-500" style="font-size: 1rem;"/>-->
                    <span class="font-light text-sm">+ Добавить</span>
                  </button>

                  <button class="font-light text-sm" @click="catsExpanded ? expandCats(false) : expandCats(true)">
                    {{ catsExpanded ? 'Скрыть все' : 'Раскрыть все' }}
                  </button>
                </div>
                <ul class="space-y-2">


                  <li v-for="(category, categoryId) in categoriesIncomeTransactions" :key="categoryId"

                      class="flex flex-col p-4 shadow-lg rounded-lg bg-white transition-transform duration-300 ">

                    <div class="flex flex-row justify-between w-full items-center transition-transform duration-300">
                      <!--                      {{category}}-->
                      <span class="text-lg font-bold items-center">{{
                          category.name.category.name
                        }} {{ category.name.icon }}</span>

                      <div class="flex flex-row gap-4">

                        <span>{{
                            formatAmount(category.name.currentSpent)
                          }} / {{ formatAmount(category.name.currentLimit) }} ₽</span>

                        <button :class="{'rotate-90': incomeCategoriesState[categoryId].isOpened}"
                                @click="incomeCategoriesState[categoryId].isOpened = !incomeCategoriesState[categoryId].isOpened">
                          <i class="pi pi-angle-right transition-transform duration-300 text-5xl"></i>
                        </button>
                      </div>
                    </div>
                    <transition
                        enter-active-class="transition ease-out duration-300"
                        enter-from-class="opacity-0 transform -translate-y-2"
                        enter-to-class="opacity-100 transform translate-y-0"
                        leave-active-class="transition ease-in duration-300"
                        leave-from-class="opacity-100 transform translate-y-0"
                        leave-to-class="opacity-0 transform -translate-y-2"
                    >
                      <div v-if="incomeCategoriesState[categoryId].isOpened">
                        <BudgetTransactionView
                            v-for="transaction in category.transactions"
                            :key="transaction._id"
                            :transaction="transaction"
                            :is-list="false"
                            @transaction-updated="updateTransactions"
                            @transaction-checked="updateTransactions"
                        />
                      </div>
                    </transition>
                  </li>
                </ul>
              </div>
            </div>
            <div>
              <!-- Планируемые расходы -->
              <div class="pb-4">

                <div class="flex flex-row gap-4 items-center mb-4">
                  <h3 class="text-2xl font-bold text-rose-500 ">Расходы</h3>
                  <button @click="openDrawer('PLANNED', 'EXPENSE')">
                    <span class="font-light text-sm">+ Добавить</span>
                  </button>
                </div>
                <div class="flex flex-col gap-4 pb-4">
                  <div class="flex flex-row gap-2"><span class="text-lg font-bold items-center">Календарь</span>
                    <button class="font-light text-sm" @click="toggleCalendar">
                      {{ calendarExpanded ? 'Скрыть' : 'Раскрыть' }}

                    </button>
                  </div>

                  <div v-for="day, dayOne in calendar" class="flex flex-col justify-between p-4 shadow-lg rounded-lg "
                       v-if="calendarExpanded == '1'"
                       :class="day.date.toISOString().split('T')[0] == new Date().toISOString().split('T')[0]? 'bg-emerald-200' : 'bg-white '">
                    <div class="flex flex-row gap-2 items-center ">
                      <span class="font-bold text-xl">{{ day.dateStr }} </span>
                      <span
                          v-if="day.expensesSum>0">Трат по плану: {{ formatAmount(day.expensesSum) }} ₽</span>
                    </div>

                    <BudgetTransactionView v-for="expense in day.expenses" :key="expense.id"
                                           :transaction="expense"
                                           :is-list="false"
                                           @transaction-updated="updateTransactions"
                                           @transaction-checked="updateTransactions"
                    />

                  </div>
                </div>
                <ul class="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <li v-for="(category, categoryId) in categoriesTransactions" :key="categoryId"
                      class="flex flex-col justify-between p-4 shadow-lg rounded-lg bg-white  ">
                    <div class="">
                      <div class="flex flex-row justify-between w-full items-center">
                        <div class="flex flex-row col-span-2 gap-2 items-center">
                      <span class=" font-bold line-clamp-1" style="font-size: 1.25rem">{{
                          category.name.category.icon
                        }} {{ category.name.category.name }}</span>
                          <button @click="openDrawer('INSTANT', 'EXPENSE', category.name.category.id)">
                            <i class="pi pi-plus-circle"/>
                          </button>
                        </div>
                        <div class="flex flex-row w-fit gap-1 justify-between">

                          <span>{{ formatAmount(category.name.currentSpent) }} </span>
                          <span> / </span>
                          <!-- Если редактируемая категория — показываем input -->
                          <input
                              v-if="editingCategoryId === category.name.category.id"
                              v-model.number="editableLimit[category.name.category.id]"
                              @blur="(category)"
                              @keyup.enter="updateBudgetCategory(category.name, editableLimit[category.name.category.id])"
                              type="number"
                              class=" border-b  w-20 p-0 "
                              autofocus
                          />
                          <!-- Если НЕ редактируем, показываем текст -->
                          <span v-else @click="startEditing(category)"
                                class=" p-0 cursor-pointer hover:underline text-left"> {{
                              formatAmount(category.name.currentLimit)
                            }} ₽</span>
                          <button v-if="category.transactions.length>0"
                                  :class="{'rotate-90': expenseCategoriesState[categoryId].isOpened}"
                                  @click="expenseCategoriesState[categoryId].isOpened = !expenseCategoriesState[categoryId].isOpened">
                            <i class="pi pi-angle-right transition-transform duration-300 text-5xl"></i>
                          </button>
                        </div>
                      </div>
                      <transition
                          enter-active-class="transition ease-out duration-300"
                          enter-from-class="opacity-0 transform -translate-y-2"
                          enter-to-class="opacity-100 transform translate-y-0"
                          leave-active-class="transition ease-in duration-300"
                          leave-from-class="opacity-100 transform translate-y-0"
                          leave-to-class="opacity-0 transform -translate-y-2"
                      >
                        <div v-if="expenseCategoriesState[categoryId].isOpened" class="pt-2 pl-2">
                          <BudgetTransactionView
                              v-for="transaction in category.transactions"
                              :key="transaction._id"
                              :transaction="transaction"
                              :is-list="false"
                              @transaction-updated="updateTransactions"
                              @transaction-checked="updateTransactions"
                          />
                          <div
                              class="flex justify-between bg-white  min-w-fit  max-h-fit flex-row items-center  gap-4 w-full ">
                            <div>
                              <p class=" font-bold text-gray-700 dark:text-gray-400">
                                🗓️ Остаток на внеплановые
                              </p>
                            </div>
                            <div class="text-lg line-clamp-1 ">
                              {{
                                formatAmount(category.name.currentLimit - category.name.currentPlanned)
                              }} ₽
                            </div>
                          </div>
                        </div>
                      </transition>
                    </div>
                    <div class="flex flex-col gap-0">
                      <div class="flex flex-row justify-between w-full items-center">
                        <span class="font-bold">🗓️ Остаток всего:</span>
                        <span class="font-bold text-lg">{{
                            formatAmount(category.name.currentLimit - category.name.currentSpent)
                          }} ₽</span>
                      </div>
                    </div>
                  </li>
                </ul>
              </div>
            </div>
          </div>
          <div class=" h-fit gap-4 flex-col row-span-6 lg:hidden ">
            <div class="flex flex-row ">
              <h3 class="text-2xl font-bold">Транзакции</h3>
              <button @click="openDrawer('INSTANT', 'EXPENSE')">
                <span class="font-light text-sm">+ Добавить</span>
              </button>
            </div>
            <div class=" flex gap-2 overflow-x-auto">
              <button v-for="categorySum in transactionCategoriesSums"
                      @click="selectCategoryType(categorySum.category.id)"
                      class="rounded-xl border p-1 bg-white border-gray-300 mb-2 min-w-fit px-2"
                      :class="selectedCategoryId == categorySum.category.id ? '!bg-blue-100' : ''">
                <p><span class="text-sm font-bold">{{ categorySum.category.name }}</span>: {{ categorySum.sum }} ₽</p>

              </button>
            </div>

            <div class="grid  grid-cols-1 gap-1 max-h-tlist overflow-y-auto ">
              <BudgetTransactionView v-for="transaction in filteredTransactions" :key="transaction.id"
                                     :transaction="transaction"
                                     :is-list="true"
                                     @transaction-updated="updateTransactions"


              />
            </div>
          </div>
        </div>


      </div>
    </div>

    <!--    <TransactionForm v-if="drawerOpened" :visible="drawerOpened" :transaction-type="transactionType"-->
    <!--                     :category-type="categoryType" @close-drawer="closeDrawer" @transaction-updated="updateTransactions"-->
    <!--                     @delete-transaction="updateTransactions"-->
    <!--                     @create-transaction="updateTransactions"/>-->
  </div>

  <div id="footer" class="h-24 bg-gray-100"/>

</template>

<style scoped>
/* Добавляем стили для стилизации */
.card {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}


.max-h-tlist {
  //max-height: 1170px; /* Ограничение высоты списка */
}


.box-shadow-inner {
  box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.3);
}

.chart {
  width: 70%;
}

</style>