<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import { useSpaceStore } from '@/stores/spaceStore';
import { DashboardService } from '@/services/dashboard-service';
import { DashboardData } from '@/models/dashboard';
import Chart from 'primevue/chart';
import Button from 'primevue/button';
import dayjs from 'dayjs';
import ProgressSpinner from 'primevue/progressspinner';
import { formatAmount } from '@/utils/utils';

const spaceStore = useSpaceStore();
const period = ref<'3m' | '6m'>('3m');
const monthlyData = ref<{ label: string; data: DashboardData }[]>([]);
const isLoading = ref(false);
const expandedMonths = ref<Set<string>>(new Set());

const toggleMonth = (label: string) => {
    if (expandedMonths.value.has(label)) {
        expandedMonths.value.delete(label);
    } else {
        expandedMonths.value.add(label);
    }
}

const getSortedCategories = (categories: DashboardData['categories']) => {
    return categories
        .filter(c => c.category.type === 'EXPENSE' && c.currentPeriodAmount > 0)
        .sort((a, b) => b.currentPeriodAmount - a.currentPeriodAmount);
}

const calculateMonthDateRange = (monthsBack: number) => {
    const baseDate = dayjs().subtract(monthsBack, 'month');
    const currentDay = dayjs().date();

    // Logic from DashboardView: 
    // If current date is 1-9, the "current" fiscal month is actually the previous calendar month.
    // e.g. Dec 5 -> Fiscal Nov (Nov 10 - Dec 9).

    // We want to generate ranges going back from "current fiscal month".

    // Let's establish "Fiscal Month 0" (Current).
    // If today is Dec 11: Fiscal Month is Dec (Dec 10 - Jan 9).
    // If today is Dec 5: Fiscal Month is Nov (Nov 10 - Dec 9).

    let fiscalMonthStart = dayjs();

    if (currentDay >= 1 && currentDay <= 9) {
        fiscalMonthStart = fiscalMonthStart.subtract(1, 'month').date(10);
    } else {
        fiscalMonthStart = fiscalMonthStart.date(10);
    }

    // Now move back `monthsBack` times
    const start = fiscalMonthStart.subtract(monthsBack, 'month');
    const end = start.add(1, 'month').date(9);

    return { startDate: start.toDate(), endDate: end.toDate() };
};

const fetchAnalyticsData = async () => {
    if (!spaceStore.selectedSpaceId) return;

    isLoading.value = true;
    monthlyData.value = [];

    const monthsToFetch = period.value === '3m' ? 3 : 6;
    const requests = [];

    for (let i = monthsToFetch - 1; i >= 0; i--) {
        const { startDate, endDate } = calculateMonthDateRange(i);
        const label = dayjs(startDate).format('MMMM'); // e.g. "November"

        requests.push(
            DashboardService.fetchDashboardData(spaceStore.selectedSpaceId, startDate, endDate)
                .then(data => ({ label, data }))
        );
    }

    try {
        monthlyData.value = await Promise.all(requests);
    } catch (e) {
        console.error("Failed to fetch analytics data", e);
    } finally {
        isLoading.value = false;
    }
};

const totalExpense = computed(() => {
    return monthlyData.value.reduce((acc, curr) => acc + curr.data.totalExpense, 0);
});

const averageExpense = computed(() => {
    // Avoid division by zero
    if (monthlyData.value.length === 0) return 0;
    return Math.round(totalExpense.value / monthlyData.value.length);
});

const aggregatedCategories = computed(() => {
    const categoryMap = new Map<number, {
        name: string,
        icon: string,
        totalAmount: number,
        count: number
    }>();

    monthlyData.value.forEach(month => {
        month.data.categories.forEach(cat => {
            // Check if it's an expense category
            // We can infer it if currentPeriodAmount > 0 and type logic 
            // Default logic from DashboardCharts: filter type === TransactionType.EXPENSE
            // But here we rely on DashboardCategory data. 
            // Typically positive amount in DashboardCategory means it exists.
            // Let's assume we filter expense categories (usually most relevant for budget).
            // DashboardCategory has 'category.type'. Let's check it.
            if (cat.category.type === 'EXPENSE') { // using string 'EXPENSE' as enum might not be imported or used directly here
                const existing = categoryMap.get(cat.category.id);
                if (existing) {
                    existing.totalAmount += cat.currentPeriodAmount;
                    existing.count += 1;
                } else {
                    categoryMap.set(cat.category.id, {
                        name: cat.category.name,
                        icon: cat.category.icon,
                        totalAmount: cat.currentPeriodAmount,
                        count: 1
                    });
                }
            }
        });
    });

    const categories = Array.from(categoryMap.values()).map(c => ({
        ...c,
        averageAmount: Math.round(c.totalAmount / monthlyData.value.length), // Avg over the selected period (3 or 6 months)
        percentage: totalExpense.value ? Math.round((c.totalAmount / totalExpense.value) * 100) : 0
    }));

    return categories.sort((a, b) => b.totalAmount - a.totalAmount);
});


const chartData = computed(() => {
    const labels = monthlyData.value.map(d => d.label);
    const expenses = monthlyData.value.map(d => d.data.totalExpense);

    return {
        labels,
        datasets: [
            {
                label: 'Expenses',
                data: expenses,
                backgroundColor: '#ef4444',
                borderRadius: 8
            }
        ]
    };
});

const chartOptions = {
    plugins: {
        legend: {
            display: false
        }
    },
    scales: {
        y: {
            beginAtZero: true,
            grid: {
                color: 'rgba(0, 0, 0, 0.05)'
            }
        },
        x: {
            grid: {
                display: false
            }
        }
    }
};

onMounted(() => {
    fetchAnalyticsData();
});

watch(() => period.value, () => {
    fetchAnalyticsData();
});

watch(() => spaceStore.selectedSpaceId, (newId) => {
    if (newId) fetchAnalyticsData();
});

</script>

<template>
    <div class="flex flex-col gap-6 w-full pb-20 px-2 lg:px-0">
        <!-- Header -->
        <div class="flex items-center justify-between">
            <h1 class="text-2xl font-semibold text-surface-900 dark:text-surface-0">Analytics</h1>

            <div class="bg-surface-100 dark:bg-surface-800 p-1 rounded-lg inline-flex">
                <button @click="period = '3m'"
                    class="px-4 py-1.5 rounded-md text-sm font-medium transition-all duration-200"
                    :class="period === '3m' ? 'bg-white dark:bg-surface-700 shadow-sm !text-primary-600 !dark:text-primary-400' : 'text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-surface-200'">
                    3 Months
                </button>
                <button @click="period = '6m'"
                    class="px-4 py-1.5 rounded-md text-sm font-medium transition-all duration-200"
                    :class="period === '6m' ? 'bg-white dark:bg-surface-700 shadow-sm !text-primary-600 !dark:text-primary-400' : 'text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-surface-200'">
                    6 Months
                </button>
            </div>
        </div>

        <div v-if="isLoading" class="flex justify-center py-10">
            <ProgressSpinner />
        </div>

        <div v-else class="flex flex-col gap-6">

            <!-- Aggregated Stats Cards -->
            <div class="grid grid-cols-2 gap-4">
                <div
                    class="bg-surface-0 dark:bg-surface-900 p-4 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700">
                    <span class="text-surface-500 dark:text-surface-400 text-sm">Total Expenses</span>
                    <div class="text-xl font-bold text-surface-900 dark:text-surface-0 mt-1">
                        {{ formatAmount(totalExpense) }} ₽
                    </div>
                </div>
                <div
                    class="bg-surface-0 dark:bg-surface-900 p-4 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700">
                    <span class="text-surface-500 dark:text-surface-400 text-sm">Average Monthly</span>
                    <div class="text-xl font-bold text-surface-900 dark:text-surface-0 mt-1">
                        {{ formatAmount(averageExpense) }} ₽
                    </div>
                </div>
            </div>

            <!-- Chart -->
            <div
                class="bg-surface-0 dark:bg-surface-900 p-4 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700">
                <h2 class="text-lg font-semibold mb-4 text-surface-900 dark:text-surface-0">Expenses Overview</h2>
                <div class="h-[300px] w-full">
                    <Chart type="bar" :data="chartData" :options="chartOptions" class="h-full w-full" />
                </div>
            </div>

            <!-- Category Breakdown -->
            <div class="flex flex-col gap-3">
                <h2 class="text-lg font-semibold text-surface-900 dark:text-surface-0">Top Categories</h2>
                <div
                    class="bg-surface-0 dark:bg-surface-900 p-2 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700 flex flex-col">
                    <div v-for="cat in aggregatedCategories" :key="cat.name"
                        class="flex items-center justify-between p-3 hover:bg-surface-50 dark:hover:bg-surface-800 rounded-lg transition-colors">

                        <div class="flex items-center gap-3">
                            <div class="text-2xl">{{ cat.icon }}</div>
                            <div class="flex flex-col">
                                <span class="font-medium text-surface-700 dark:text-surface-200">{{ cat.name }}</span>
                                <span class="text-xs text-surface-500">avg. {{ formatAmount(cat.averageAmount) }}
                                    ₽/mo</span>
                            </div>
                        </div>

                        <div class="flex flex-col items-end">
                            <span class="font-semibold text-surface-900 dark:text-surface-0">{{
                                formatAmount(cat.totalAmount) }} ₽</span>
                            <span class="text-xs text-surface-500">{{ cat.percentage }}%</span>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Detailed Stats -->
            <div class="flex flex-col gap-3">
                <h2 class="text-lg font-semibold text-surface-900 dark:text-surface-0">Monthly Breakdown</h2>
                <div v-for="item in monthlyData" :key="item.label" class="flex flex-col gap-2">
                    <div @click="toggleMonth(item.label)"
                        class="bg-surface-0 dark:bg-surface-900 p-4 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700 flex justify-between items-center cursor-pointer hover:bg-surface-50 dark:hover:bg-surface-800 transition-colors">

                        <div class="flex items-center gap-2">
                            <i :class="expandedMonths.has(item.label) ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"
                                class="text-surface-500 text-sm"></i>
                            <span class="font-medium text-lg text-surface-700 dark:text-surface-200">{{ item.label
                            }}</span>
                        </div>

                        <div class="flex flex-col items-end">
                            <span class="font-bold text-red-500">- {{ formatAmount(item.data.totalExpense) }} ₽</span>
                            <span class="text-sm text-green-500">+ {{ formatAmount(item.data.totalIncome) }} ₽</span>
                        </div>
                    </div>

                    <!-- Expanded Category List -->
                    <div v-if="expandedMonths.has(item.label)" class="pl-4 pr-2">
                        <div
                            class="bg-surface-0 dark:bg-surface-900 p-2 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700 flex flex-col">
                            <div v-for="cat in getSortedCategories(item.data.categories)" :key="cat.category.id"
                                class="flex items-center justify-between p-2 hover:bg-surface-50 dark:hover:bg-surface-800 rounded-lg transition-colors text-sm">

                                <div class="flex items-center gap-3">
                                    <div class="text-xl">{{ cat.category.icon }}</div>
                                    <span class="font-medium text-surface-700 dark:text-surface-200">{{
                                        cat.category.name }}</span>
                                </div>

                                <div class="font-semibold text-surface-900 dark:text-surface-0">
                                    {{ formatAmount(cat.currentPeriodAmount) }} ₽
                                </div>
                            </div>
                            <div v-if="getSortedCategories(item.data.categories).length === 0"
                                class="p-2 text-center text-surface-500">
                                No expenses this month
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
```
