"use client";
import {
RiArrowDownSFill,
RiArrowUpSFill,
RiExternalLinkLine,
RiPieChartLine,
RiWallet3Line,
} from "@remixicon/react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useMemo } from "react";
import { Cell, Pie, PieChart, Tooltip } from "recharts";
import { CategoryIconBadge } from "@/components/categorias/category-icon-badge";
import { useIsMobile } from "@/hooks/use-mobile";
import MoneyValues from "@/components/money-values";
import { type ChartConfig, ChartContainer } from "@/components/ui/chart";
import type { ExpensesByCategoryData } from "@/lib/dashboard/categories/expenses-by-category";
import { getCategoryColor } from "@/lib/utils/category-colors";
import { formatPeriodForUrl } from "@/lib/utils/period";
import { WidgetEmptyState } from "../widget-empty-state";
type ExpensesByCategoryWidgetWithChartProps = {
data: ExpensesByCategoryData;
period: string;
};
const formatPercentage = (value: number) => {
return `${Math.abs(value).toFixed(0)}%`;
};
const formatCurrency = (value: number) =>
new Intl.NumberFormat("pt-BR", {
style: "currency",
currency: "BRL",
}).format(value);
type ChartDataItem = {
category: string;
name: string;
value: number;
percentage: number;
fill: string | undefined;
href: string | undefined;
};
export function ExpensesByCategoryWidgetWithChart({
data,
period,
}: ExpensesByCategoryWidgetWithChartProps) {
const router = useRouter();
const isMobile = useIsMobile();
const periodParam = formatPeriodForUrl(period);
// Configuração do chart com as mesmas cores dos ícones das categorias (getCategoryColor)
const chartConfig = useMemo(() => {
const config: ChartConfig = {};
if (data.categories.length <= 7) {
data.categories.forEach((category, index) => {
config[category.categoryId] = {
label: category.categoryName,
color: getCategoryColor(index),
};
});
} else {
// Top 7 + Outros
const top7 = data.categories.slice(0, 7);
top7.forEach((category, index) => {
config[category.categoryId] = {
label: category.categoryName,
color: getCategoryColor(index),
};
});
config.outros = {
label: "Outros",
color: getCategoryColor(7),
};
}
return config;
}, [data.categories]);
// Preparar dados para o gráfico de pizza - Top 7 + Outros (com href para navegação)
const chartData = useMemo((): ChartDataItem[] => {
const buildItem = (
categoryId: string,
name: string,
value: number,
percentage: number,
fill: string | undefined,
): ChartDataItem => ({
category: categoryId,
name,
value,
percentage,
fill,
href:
categoryId === "outros"
? undefined
: `/categorias/${categoryId}?periodo=${periodParam}`,
});
if (data.categories.length <= 7) {
return data.categories.map((category) =>
buildItem(
category.categoryId,
category.categoryName,
category.currentAmount,
category.percentageOfTotal,
chartConfig[category.categoryId]?.color,
),
);
}
const top7 = data.categories.slice(0, 7);
const others = data.categories.slice(7);
const othersTotal = others.reduce((sum, cat) => sum + cat.currentAmount, 0);
const othersPercentage = others.reduce(
(sum, cat) => sum + cat.percentageOfTotal,
0,
);
const top7Data = top7.map((category) =>
buildItem(
category.categoryId,
category.categoryName,
category.currentAmount,
category.percentageOfTotal,
chartConfig[category.categoryId]?.color,
),
);
if (others.length > 0) {
top7Data.push(
buildItem(
"outros",
"Outros",
othersTotal,
othersPercentage,
chartConfig.outros?.color,
),
);
}
return top7Data;
}, [data.categories, chartConfig, periodParam]);
if (data.categories.length === 0) {
return (