<script setup lang="ts">
import { computed, ref } from 'vue';
import Chart from 'primevue/chart';
import Button from 'primevue/button';
import CategoryTransactionsModal from './CategoryTransactionsModal.vue';
import { DashboardCategory, DashboardWeek } from '@/models/dashboard';
import { Transaction } from '@/models/transaction';
import { TransactionType } from '@/models/enums';
import { formatAmount } from '@/utils/utils';
import dayjs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';

dayjs.extend(isoWeek);

const props = defineProps<{
  categories: DashboardCategory[];
  transactions: Transaction[];
  weeks: DashboardWeek[];
  startDate: Date;
  endDate: Date;
}>();

const chartType = ref<'category' | 'weekly'>('category');
const isCategoriesExpanded = ref(false);

// Modal state
const isModalVisible = ref(false);
const selectedCategory = ref<{ id: number; name: string; icon: string } | null>(null);

const openCategoryModal = (category: DashboardCategory) => {
  selectedCategory.value = {
    id: category.category.id,
    name: category.category.name,
    icon: category.category.icon
  };
  isModalVisible.value = true;
};

const expenses = computed(() => props.categories.filter(c => c.category.type === TransactionType.EXPENSE));

// --- Category Chart Logic ---
const categoryData = computed(() => {
  return expenses.value
    .map(c => ({
      ...c,
      name: c.category.name,
      amount: c.currentPeriodAmount,
    }))
    .sort((a, b) => b.amount - a.amount);
});

const totalExpenseAmount = computed(() => {
  return expenses.value.reduce((sum, c) => sum + c.currentPeriodAmount, 0);
});

const topCategories = computed(() => {
  return categoryData.value.map(cat => ({
    ...cat,
    percentage: totalExpenseAmount.value ? Math.round((cat.amount / totalExpenseAmount.value) * 100) : 0
  }));
});

const displayedCategories = computed(() => {
  return isCategoriesExpanded.value ? topCategories.value : topCategories.value.slice(0, 5);
});

const categoryChartData = computed(() => {
  const labels = categoryData.value.map(c => c.name);
  const data = categoryData.value.map(c => c.amount);

  // Generate colors
  const backgroundColors = [
    '#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6',
    '#ec4899', '#06b6d4', '#84cc16', '#6366f1', '#14b8a6'
  ];

  return {
    labels,
    datasets: [
      {
        data,
        backgroundColor: backgroundColors.slice(0, labels.length),
        hoverBackgroundColor: backgroundColors.slice(0, labels.length)
      }
    ]
  };
});

const categoryChartOptions = computed(() => {
  return {
    plugins: {
      legend: {
        display: false // Hide default legend to use our custom list
      }
    }
  };
});

const getCategoryColor = (index: number) => {
  const colors = [
    'bg-blue-500', 'bg-red-500', 'bg-emerald-500', 'bg-amber-500', 'bg-violet-500',
    'bg-pink-500', 'bg-cyan-500', 'bg-lime-500', 'bg-indigo-500', 'bg-teal-500'
  ];
  return colors[index % colors.length];
};

// --- Weekly Chart Logic ---

const weeklyChartData = computed(() => {
  return {
    labels: props.weeks.map(w => `${dayjs(w.startDate).format('D MMM')} - ${dayjs(w.endDate).format('D MMM')}`),
    datasets: [
      {
        label: 'Expenses',
        data: props.weeks.map(w => w.expenseSum),
        backgroundColor: '#3b82f6',
        borderRadius: 8
      }
    ]
  };
});

const weeklyChartOptions = computed(() => {
  return {
    plugins: {
      legend: {
        display: false
      }
    },
    scales: {
      y: {
        beginAtZero: true,
        grid: {
          color: 'rgba(0, 0, 0, 0.05)'
        }
      },
      x: {
        grid: {
          display: false
        }
      }
    }
  };
});
</script>

<template>
  <div class="flex flex-col gap-1">
    <span class="text-xl !font-semibold pl-1">Expences by category </span>

    <div
      class="bg-surface-0 dark:bg-surface-900 p-4 rounded-xl shadow-sm border border-surface-200 dark:border-surface-700">
      <div class="flex flex-col gap-6">

        <!-- Chart Switcher -->
        <div class="flex justify-center">
          <div class="bg-surface-100 dark:bg-surface-800 p-1 rounded-lg inline-flex">
            <button @click="chartType = 'category'"
              class="px-4 py-1.5 rounded-md text-sm font-medium transition-all duration-200"
              :class="chartType === 'category' ? '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'">
              By Category
            </button>
            <button @click="chartType = 'weekly'"
              class="px-4 py-1.5 rounded-md text-sm font-medium transition-all duration-200"
              :class="chartType === 'weekly' ? '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'">
              Last 4 Weeks
            </button>
          </div>
        </div>

        <div class="flex flex-col md:flex-row items-start gap-8">
          <!-- Chart Area -->
          <div class="w-full md:w-1/2 flex justify-center h-[250px] items-center top-4">
            <Chart v-if="chartType === 'category'" type="doughnut" :data="categoryChartData"
              :options="categoryChartOptions" class="w-full max-w-[250px]" />
            <Chart v-else type="bar" :data="weeklyChartData" :options="weeklyChartOptions" class="w-full h-full" />
          </div>

          <!-- Legend / Details Area -->
          <div class="w-full md:w-1/2 flex flex-col gap-3">
            <template v-if="chartType === 'category'">
              <div class="categories-wrapper">
                <div :class="['categories-content', { 'expanded': isCategoriesExpanded }]">
                  <div v-for="(category, index) in displayedCategories" :key="category.name"
                    class="flex items-center justify-between p-2 rounded-lg hover:bg-surface-50 dark:hover:bg-surface-800 transition-colors cursor-pointer"
                    @click="openCategoryModal(category)">
                    <div class="flex items-center gap-3">
                      <div class="w-3 h-3 rounded-full" :class="getCategoryColor(index)"></div>
                      <span class="font-medium text-surface-700 dark:text-surface-200">{{ category.name }}</span>
                    </div>
                    <div class="flex items-center gap-3">
                      <div class="flex items-center font-semibold gap-1 text-surface-900 dark:text-surface-0">
                        <div class="flex items-center gap-0">
                          <span>{{ formatAmount(category.amount) }}</span>
                          <span class="ml-0.5">₽</span>
                        </div>
                        <span class="text-xs text-surface-500 dark:text-surface-400 ml-1">({{
                          formatAmount(category.previousPeriodAmount) }})</span>

                      </div>
                      <div
                        class="flex items-center text-sm gap-1 text-surface-500 dark:text-surface-400 w-10 text-right !w-full">
                        <div class="flex items-center gap-0">
                          <span>{{ category.percentage }}</span>
                          <span class="ml-0.5">%</span>
                        </div>
                        <span class="text-xs  ml-1 !w-fit"
                          :class="category.changeDiffPercentage > 0 ? 'text-red-500' : 'text-green-500'">({{
                            (category.changeDiffPercentage > 0 ? '+' : '') + Math.round(category.changeDiffPercentage)
                          }}%)</span>

                      </div>
                    </div>
                  </div>
                </div>
                <div v-if="!isCategoriesExpanded && topCategories.length > 5" class="categories-fade"></div>
              </div>
              <Button v-if="topCategories.length > 5" :label="isCategoriesExpanded ? 'Show less' : 'Show more'"
                :icon="isCategoriesExpanded ? 'pi pi-chevron-up' : 'pi pi-chevron-down'" class="expand-button"
                @click="isCategoriesExpanded = !isCategoriesExpanded" />
            </template>

            <template v-else>
              <div class="flex flex-col gap-4">
                <div v-for="week in props.weeks" :key="week.startDate.toString()" class="flex flex-col gap-2">
                  <div class="flex items-center justify-between p-2 bg-surface-50 dark:bg-surface-800 rounded-lg">
                    <span class="font-medium text-surface-700 dark:text-surface-200">{{
                      dayjs(week.startDate).format('D MMM') }} - {{ dayjs(week.endDate).format('D MMM') }}</span>
                    <span class="font-semibold text-surface-900 dark:text-surface-0">{{ formatAmount(week.expenseSum) }}
                      ₽</span>
                  </div>

                  <!-- Categories List -->
                  <div
                    class="flex flex-col gap-1 pl-2 border-l-2 border-surface-100 dark:border-surface-700 ml-2 h-fit">
                    <div v-for="cat in week.categories.slice(0, 5)" :key="cat.categoryId"
                      class="flex items-center justify-between py-1 px-2 text-sm hover:bg-surface-50 dark:hover:bg-surface-800 rounded transition-colors">
                      <div class="flex items-center gap-2 overflow-hidden">
                        <span class="text-lg">{{ cat.categoryIcon }}</span>
                        <span class="text-surface-600 dark:text-surface-300 truncate">{{ cat.categoryName }}</span>
                      </div>
                      <span class="font-medium text-surface-900 dark:text-surface-100 whitespace-nowrap">{{
                        cat.sum ? formatAmount(cat.sum) : 0 }} ₽</span>
                    </div>
                    <div v-if="week.categories.length > 5" class="text-xs text-surface-400 pl-2 pt-1">
                      +{{ week.categories.length - 5 }} more
                    </div>
                  </div>
                </div>
              </div>
            </template>
          </div>
        </div>
      </div>
    </div>

    <!-- Category Transactions Modal -->
    <CategoryTransactionsModal v-model:visible="isModalVisible" :categoryId="selectedCategory?.id ?? null"
      :categoryName="selectedCategory?.name ?? ''" :categoryIcon="selectedCategory?.icon ?? ''" :startDate="startDate"
      :endDate="endDate" />
  </div>
</template>

<style scoped>
.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  background-color: var(--surface-300);
  border-radius: 20px;
}

.dark .custom-scrollbar::-webkit-scrollbar-thumb {
  background-color: var(--surface-700);
}

.categories-wrapper {
  position: relative;
}

.categories-content {
  max-height: 300px;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.categories-content.expanded {
  max-height: 2000px;
}

.categories-fade {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 80px;
  background: linear-gradient(to bottom,
      transparent 0%,
      rgba(255, 255, 255, 0.7) 50%,
      rgba(255, 255, 255, 0.95) 100%);
  pointer-events: none;
  transition: opacity 0.3s ease;
}

:global(.dark) .categories-fade {
  background: linear-gradient(to bottom,
      transparent 0%,
      rgba(24, 24, 27, 0.7) 50%,
      rgba(24, 24, 27, 0.95) 100%);
}

.expand-button {
  margin-top: 1rem;
  align-self: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
  border: none !important;
  color: white !important;
  padding: 0.625rem 1.5rem !important;
  border-radius: 2rem !important;
  font-weight: 500 !important;
  font-size: 0.875rem !important;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
  transition: all 0.3s ease !important;
}

.expand-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4) !important;
  background: linear-gradient(135deg, #764ba2 0%, #667eea 100%) !important;
}

.expand-button:active {
  transform: translateY(0);
}
</style>
