<template>
  <div class="flex flex-col">
    <!-- Toolbar con switches de secciones -->
    <UDashboardToolbar>
      <template #right>
        <div class="flex items-center gap-3">
          <USwitch
            v-model="pageSections.totalesCafe"
            size="xs"
            label="Totales"
          />
          <USwitch
            v-model="pageSections.totalesVerde"
            size="xs"
            label="Verde"
          />
          <USwitch
            v-model="pageSections.tablaIngresos"
            size="xs"
            label="Tabla"
          />
          <USwitch
            v-model="pageSections.top10Clientes"
            size="xs"
            label="Top 10"
          />
          <USwitch
            v-model="pageSections.graficas"
            size="xs"
            label="Gráficas"
          />
        </div>
      </template>
    </UDashboardToolbar>

    <div class="flex flex-col gap-8 p-6">
      <!-- Loading State -->
      <UCard v-if="loading && !ingresosStore.hasData" class="brand-card border border-transparent">
        <div class="flex flex-col items-center justify-center gap-4 py-10 text-[var(--brand-text-muted)]">
          <div class="flex items-center gap-3">
            <span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[#c08040] border-t-transparent align-middle" aria-hidden="true" />
            <span class="text-sm uppercase tracking-[0.3em]">Cargando datos...</span>
          </div>
          <UProgress
            v-if="loadingProgress > 0"
            :model-value="loadingProgress"
            :max="100"
            size="sm"
            class="w-64"
          />
          <span v-if="loadingProgress > 0" class="text-xs text-[var(--brand-text-muted)]">
            {{ Math.round(loadingProgress) }}%
          </span>
        </div>
      </UCard>

      <!-- Error State -->
      <div v-else-if="error" class="rounded-lg border border-red-500/40 bg-red-500/18 p-4 text-sm text-red-200">
        <p>Error al cargar datos: {{ error }}</p>
      </div>

      <!-- Main Content -->
      <template v-else>
      <!-- Loading overlay when filtering data -->
      <Transition
        enter-active-class="transition-opacity duration-200"
        enter-from-class="opacity-0"
        enter-to-class="opacity-100"
        leave-active-class="transition-opacity duration-200"
        leave-from-class="opacity-100"
        leave-to-class="opacity-0"
      >
        <div
          v-if="isFilteringData"
          class="fixed inset-0 z-[60] flex items-center justify-center bg-black/50 backdrop-blur-sm"
        >
          <UCard class="brand-card border border-[#c08040]/30">
            <div class="flex flex-col items-center justify-center gap-4 py-6 px-8">
              <span class="inline-flex h-12 w-12 animate-spin rounded-full border-4 border-[#c08040] border-t-transparent" />
              <div class="flex flex-col items-center gap-2">
                <span class="text-lg font-semibold text-[var(--brand-text)]">Filtrando datos...</span>
                <span class="text-sm text-[var(--brand-text-muted)]">Por favor espere</span>
              </div>
            </div>
          </UCard>
        </div>
      </Transition>

      <!-- Metadatos Cards -->
      <div class="grid grid-cols-1 md:grid-cols-2 gap-5">
        <MetadatosCard v-if="ingresosMetadata" :metadata="ingresosMetadata" :compact="true" />
        <MetadatosCard v-if="clientesMetadata" :metadata="clientesMetadata" :compact="true" />
      </div>

      <!-- Filtros Activos Badge Card -->
      <Transition
        enter-active-class="transition-all duration-300 ease-out"
        enter-from-class="opacity-0 -translate-y-2"
        enter-to-class="opacity-100 translate-y-0"
        leave-active-class="transition-all duration-200 ease-in"
        leave-from-class="opacity-100 translate-y-0"
        leave-to-class="opacity-0 -translate-y-2"
      >
        <IngresosFiltrosActivos
          v-if="hasFiltrosActivos"
          :clientes="clientes"
          :selected-cliente-ids="selectedClienteIds"
          :selected-preset="selectedPreset"
          :fecha-desde="fechaDesde"
          :fecha-hasta="fechaHasta"
          :selected-tipos="selectedTipos"
          :selected-estados="selectedEstados"
          :selected-ubicaciones="selectedUbicaciones"
          :selected-calidades="selectedCalidades"
          :include-anulados="includeAnulados"
          :no-filter="noFilter"
          :tipos-options="tiposCafeOptions"
          :estados-options="estadosOptions"
          @update:selected-cliente-ids="selectedClienteIds = $event"
          @update:fecha-desde="fechaDesde = $event"
          @update:fecha-hasta="fechaHasta = $event"
          @update:selected-preset="selectedPreset = $event"
          @update:selected-tipos="selectedTipos = $event"
          @update:selected-estados="selectedEstados = $event"
          @update:selected-ubicaciones="selectedUbicaciones = $event"
          @update:selected-calidades="selectedCalidades = $event"
          @update:include-anulados="includeAnulados = $event"
          @update:no-filter="noFilter = $event"
          @show-cliente-selector="showClienteSelectorTemp = true"
          @show-filtros="filtrosCollapsed = false"
        />
      </Transition>

      <!-- Selector de clientes temporal (cuando se hace clic en "Agregar cliente") -->
      <Transition
        enter-active-class="transition-all duration-300 ease-out"
        enter-from-class="opacity-0 -translate-y-2"
        enter-to-class="opacity-100 translate-y-0"
        leave-active-class="transition-all duration-200 ease-in"
        leave-from-class="opacity-100 translate-y-0"
        leave-to-class="opacity-0 -translate-y-2"
      >
        <UCard v-if="showClienteSelectorTemp" class="brand-card border border-blue-500/30">
          <template #header>
            <div class="flex items-center justify-between">
              <h3 class="text-sm font-semibold text-[var(--brand-text)]">Agregar más clientes</h3>
              <UButton
                size="xs"
                variant="ghost"
                color="neutral"
                icon="i-lucide-x"
                @click="showClienteSelectorTemp = false"
              />
            </div>
          </template>
          <ClienteSelector
            :clientes="clientes"
            :selected-ids="selectedClienteIds"
            @update:selected-ids="handleClienteSelection"
          />
        </UCard>
      </Transition>

      <!-- Filtros Card Colapsable -->
      <Transition
        enter-active-class="transition-all duration-300 ease-out"
        enter-from-class="opacity-0 -translate-y-2"
        enter-to-class="opacity-100 translate-y-0"
        leave-active-class="transition-all duration-200 ease-in"
        leave-from-class="opacity-100 translate-y-0"
        leave-to-class="opacity-0 -translate-y-2"
      >
        <UCard v-show="!filtrosCollapsed" class="brand-card border border-transparent">
          <template #header>
            <div class="flex items-center justify-between">
              <div class="flex items-center gap-2">
                <UIcon name="i-lucide-filter" class="size-4 text-[#c08040]" />
                <h3 class="text-sm font-semibold text-[var(--brand-text)]">Filtros Disponibles</h3>
              </div>
              <UButton
                size="xs"
                variant="ghost"
                color="neutral"
                icon="i-lucide-chevron-up"
                @click="filtrosCollapsed = true"
              >
                Ocultar
              </UButton>
            </div>
          </template>

          <InformeIngresosFiltrosPanel
            :clientes="clientes"
            :selected-cliente-ids="selectedClienteIds"
            :selected-preset="selectedPreset"
            :fecha-desde="fechaDesde"
            :fecha-hasta="fechaHasta"
            :selected-tipos="selectedTipos"
            :selected-estados="selectedEstados"
            :selected-ubicaciones="selectedUbicaciones"
            :selected-calidades="selectedCalidades"
            :tipos-options="tiposCafeOptions"
            :estados-options="estadosOptions"
            :ubicaciones-options="ubicacionesOptions"
            :calidades-options="calidadesOptions"
            :include-anulados="includeAnulados"
            :no-filter="noFilter"
            @update:selected-cliente-ids="selectedClienteIds = $event"
            @update:selected-preset="selectedPreset = $event"
            @update:fecha-desde="fechaDesde = $event"
            @update:fecha-hasta="fechaHasta = $event"
            @update:selected-tipos="selectedTipos = $event"
            @update:selected-estados="selectedEstados = $event"
            @update:selected-ubicaciones="selectedUbicaciones = $event"
            @update:selected-calidades="selectedCalidades = $event"
            @update:include-anulados="includeAnulados = $event"
            @update:no-filter="noFilter = $event"
            @hide-filtros="filtrosCollapsed = true"
          />
        </UCard>
      </Transition>

      <!-- Totales por Café -->
      <UCard v-show="pageSections.totalesCafe" class="brand-card border border-transparent">
        <template #header>
          <div class="flex items-center justify-between">
            <div>
              <h2 class="text-xl font-bold brand-section-title">Totales por Café</h2>
              <p class="text-xs text-[var(--brand-text-muted)] mt-1">
                {{ showMonetaryView ? 'Vista de valores monetarios' : 'Vista de quintales (qq) y libras (lb)' }}
              </p>
            </div>
            <UButton
              size="sm"
              color="neutral"
              variant="outline"
              @click="showMonetaryView = !showMonetaryView"
            >
              <template #leading>
                <UIcon :name="showMonetaryView ? 'i-lucide-scale' : 'i-lucide-dollar-sign'" />
              </template>
              {{ showMonetaryView ? 'Ver qq/lb' : 'Ver Monetario' }}
            </UButton>
          </div>
        </template>

        <IngresosTotalesIngresoCompra v-if="!showMonetaryView" :metrics="ingresosMetrics" />
        <IngresosTotalesMonetarios v-else :metrics="ingresosMetrics" />
      </UCard>

      <!-- Totales Netos de Verde -->
      <IngresosTotalesVerde v-if="hasVerdeData" v-show="pageSections.totalesVerde" :metrics="ingresosMetrics" />

      <!-- Backdrop para fullscreen -->
      <Transition
        enter-active-class="transition-opacity duration-300"
        enter-from-class="opacity-0"
        enter-to-class="opacity-100"
        leave-active-class="transition-opacity duration-300"
        leave-from-class="opacity-100"
        leave-to-class="opacity-0"
      >
        <div
          v-if="isTableFullscreen"
          class="fixed inset-0 bg-black/80 z-40 backdrop-blur-sm"
          @click="toggleTableFullscreen"
        />
      </Transition>

      <!-- Vista Tabla según tab activo -->
      <UCard
        v-show="pageSections.tablaIngresos"
        :class="[
          'brand-card border border-transparent transition-all duration-300',
          isTableFullscreen ? 'fixed inset-4 z-50 rounded-lg overflow-auto' : ''
        ]"
      >
        <template #header>
          <div class="flex flex-col gap-3">
            <div class="flex items-center justify-between">
              <div>
                <h2 :class="['text-xl font-bold', tableTitleClass]">{{ tableTitle }}</h2>
                <p class="text-xs text-[var(--brand-text-muted)] mt-1">
                  {{ tableDescription }}
                </p>
              </div>
              <UButton
                :icon="isTableFullscreen ? 'i-lucide-minimize' : 'i-lucide-maximize'"
                color="neutral"
                variant="ghost"
                size="sm"
                @click="toggleTableFullscreen"
                :title="isTableFullscreen ? 'Salir de pantalla completa' : 'Pantalla completa'"
              />
            </div>
            <div ref="viewSelectorRef" class="flex flex-col gap-3">
              <div class="grid grid-cols-2 gap-12">
                <button
                  v-for="option in viewOptions"
                  :key="option.value"
                  @click="selectedView = option.value"
                  :class="[
                    'relative inline-flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg border transition-all duration-200',
                    selectedView === option.value
                      ? `${option.borderColor} ${option.bgColor} shadow-lg ${option.shadowColor}`
                      : 'border-gray-600/30 bg-gray-700/20 hover:bg-gray-700/30'
                  ]"
                >
                  <UIcon
                    :name="option.icon"
                    :class="[
                      'relative z-10 w-5 h-5',
                      selectedView === option.value && option.color === 'cyan' ? 'text-cyan-400' :
                      selectedView === option.value && option.color === 'yellow' ? 'text-yellow-500' :
                      'text-gray-400'
                    ]"
                  />

                  <span
                    :class="[
                      'relative z-10 font-medium text-base whitespace-nowrap',
                      selectedView === option.value && option.color === 'cyan' ? 'text-cyan-400' :
                      selectedView === option.value && option.color === 'yellow' ? 'text-yellow-500' :
                      'text-gray-400'
                    ]"
                  >
                    {{ option.label }}
                  </span>

                  <!-- Badge con contador -->
                  <span
                    :class="[
                      'relative z-10 inline-flex items-center justify-center min-w-[24px] h-6 px-2 rounded-full text-xs font-bold transition-all',
                      selectedView === option.value && option.color === 'cyan' ? 'bg-cyan-500/30 text-cyan-300 border border-cyan-400/50' :
                      selectedView === option.value && option.color === 'yellow' ? 'bg-yellow-500/30 text-yellow-300 border border-yellow-400/50' :
                      option.color === 'cyan' ? 'bg-cyan-500/20 text-cyan-400/80 border border-cyan-500/30' :
                      option.color === 'yellow' ? 'bg-yellow-500/20 text-yellow-400/80 border border-yellow-500/30' :
                      'bg-gray-500/20 text-gray-400 border border-gray-500/30'
                    ]"
                  >
                    {{ getViewCount(option.value) }}
                  </span>
                </button>
              </div>
            </div>
          </div>
        </template>

        <!-- Vista de Ingresos (con expansión de clientes) -->
        <IngresosVistaTablaIngresos
          v-if="selectedView === 'ingresos'"
          :records="ingresosFiltrados"
          :clientes="clientes"
        />

        <!-- Vista de Clientes (con expansión de ingresos) -->
        <ClientesVistaTablaClientes
          v-else-if="selectedView === 'clientes'"
          :records="clientesFiltrados"
          :ingresos="ingresosFiltrados"
        />
      </UCard>

      <!-- Top 10 Clientes -->
      <IngresosTopClientes v-show="pageSections.top10Clientes" :ingresos="ingresosFiltrados" :clientes="clientesFiltrados" />

      <!-- Sección de Gráficas: Acumuladores -->
      <div v-show="pageSections.graficas" class="space-y-6 w-full">
        <div class="flex items-center gap-3 mb-4">
          <div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
          <h2 class="text-2xl font-bold brand-section-title">Acumuladores en el Tiempo</h2>
          <div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
        </div>

        <!-- Gráfica de Acumulación -->
        <div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
          <IngresosGraficaAcumuladoresUva :ingresos="ingresosFiltrados" />
        </div>

        <!-- Gráfica de Pagado vs Depósito -->
        <div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
          <IngresosGraficaDinamicaPagadoDeposito :ingresos="ingresosFiltrados" />
        </div>
      </div>

      <!-- Sección de Gráficas: Series Temporales -->
      <div v-show="pageSections.graficas" class="space-y-6 w-full">
        <div class="flex items-center gap-3 mb-4">
          <div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
          <h2 class="text-2xl font-bold brand-section-title">Series Temporales</h2>
          <div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
        </div>

        <!-- Serie de Ingresos Diarios -->
        <div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
          <IngresosGraficaSerieIngresos :ingresos="ingresosFiltrados" />
        </div>

        <!-- Serie de Inversión Diaria -->
        <div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
          <IngresosGraficaSerieInversion :ingresos="ingresosFiltrados" />
        </div>
      </div>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useTableDataStore } from '~/stores/tableDataFactory'
import { useMetadataStore } from '~/stores/metadata'
import { useIngresosMetrics } from '~/composables/useIngresosMetrics'
import type { IngresoRecord } from '~/composables/useIngresosMetrics'

// Define page metadata
definePageMeta({
  layout: 'informe',
  title: 'Informe Ingresos'
})

// Obtener estado colapsado y visibilidad de secciones desde el layout
const { filtrosCollapsed, metadatosCollapsed, pageSections, setFiltrosResumen, setDatasourceCounts, setFilteredResults, setActiveFilters, setMetadatosNeedUpdate } = useInformeLayout()

// Computed properties invertidos para switches (ON = visible, OFF = oculto)
const showFiltros = computed({
  get: () => !filtrosCollapsed.value,
  set: (value) => { filtrosCollapsed.value = !value }
})

const showMetadatos = computed({
  get: () => !metadatosCollapsed.value,
  set: (value) => { metadatosCollapsed.value = !value }
})

// View modes - now only 2 options
type ViewMode = 'ingresos' | 'clientes'
const selectedView = ref<ViewMode>('ingresos')

const viewOptions = [
  {
    value: 'ingresos' as ViewMode,
    label: 'Ingresos',
    icon: 'i-lucide-trending-up',
    color: 'cyan',
    gradient: 'from-cyan-500 to-cyan-600',
    borderColor: 'border-cyan-500/50',
    bgColor: 'bg-cyan-500/10',
    shadowColor: 'shadow-cyan-500/20'
  },
  {
    value: 'clientes' as ViewMode,
    label: 'Clientes',
    icon: 'i-lucide-users',
    color: 'yellow',
    gradient: 'from-yellow-500 to-yellow-600',
    borderColor: 'border-yellow-500/50',
    bgColor: 'bg-yellow-500/10',
    shadowColor: 'shadow-yellow-500/20'
  }
]

// Dynamic table title and description
const tableTitle = computed(() => {
  switch (selectedView.value) {
    case 'ingresos':
      return 'Tabla de Ingresos'
    case 'clientes':
      return 'Tabla de Clientes'
    default:
      return 'Tabla de Datos'
  }
})

const tableTitleClass = computed(() => {
  switch (selectedView.value) {
    case 'ingresos':
      return 'text-cyan-400'
    case 'clientes':
      return 'text-yellow-500'
    default:
      return 'brand-section-title'
  }
})

const tableDescription = computed(() => {
  switch (selectedView.value) {
    case 'ingresos':
      return `${ingresosFiltrados.value.length} ingresos (expandibles para ver cliente)`
    case 'clientes': {
      const clientesConIngresos = clientesFiltrados.value.filter(c =>
        ingresosFiltrados.value.some(i => i.cliente_id === c.id)
      ).length
      return `${clientesConIngresos} clientes con ingresos (expandibles para ver detalles)`
    }
    default:
      return 'Selecciona una vista'
  }
})

// Ref for view selector element
const viewSelectorRef = ref<HTMLElement | null>(null)

// Watch for view changes and scroll to keep the selector in view
watch(selectedView, (newView, oldView) => {
  nextTick(() => {
    if (viewSelectorRef.value) {
      viewSelectorRef.value.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }
  })
})

interface ClienteRecord extends Record<string, unknown> {
  id: number
  created_at: string
  updated_at: string
  name: string
  cedula?: number
  ubicacion?: string
  grupo_estudio?: string
  empleado?: boolean
  avatar_url?: string
  telefono?: string
  idciat?: number
}

// Initialize stores
const ingresosStore = useTableDataStore<IngresoRecord>('ingresos')
const clientesStore = useTableDataStore<ClienteRecord>('clientes')

// Reactive data from stores
const ingresos = computed(() => ingresosStore.allRecords as IngresoRecord[])
const clientes = computed(() => clientesStore.allRecords as ClienteRecord[])

// -------------------------------
// Filtros con persistencia en cookies
// -------------------------------
const includeAnulados = useCookie<boolean>('informe-ingresos-anulados', { default: () => false })
const noFilter = useCookie<boolean>('informe-ingresos-no-filter', { default: () => false })

type PresetValue =
  | '' | 'custom' | 'hoy' | 'semana' | 'mes' | 'ytd'
  | 'cosecha-20-21' | 'cosecha-21-22' | 'cosecha-22-23'
  | 'cosecha-23-24' | 'cosecha-24-25' | 'cosecha-25-26'

const selectedPreset = useCookie<PresetValue>('informe-ingresos-preset', { default: () => 'hoy' })
const fechaDesde = useCookie<string | null>('informe-ingresos-fecha-desde', { default: () => null })
const fechaHasta = useCookie<string | null>('informe-ingresos-fecha-hasta', { default: () => null })
const selectedClienteIds = useCookie<number[]>('informe-ingresos-clientes', { default: () => [] })

// Filtros avanzados
const selectedTipos = useCookie<string[]>('informe-ingresos-tipos', { default: () => [] })
const selectedEstados = useCookie<string[]>('informe-ingresos-estados', { default: () => [] })
const selectedUbicaciones = useCookie<string[]>('informe-ingresos-ubicaciones', { default: () => [] })
const selectedCalidades = useCookie<string[]>('informe-ingresos-calidades', { default: () => [] })

// Debounce para manejar cambios de filtros
let filterChangeTimeout: ReturnType<typeof setTimeout> | null = null

// Watch para actualizar filtrados cuando cambien los filtros o los datos
watch([ingresos, selectedClienteIds, fechaDesde, fechaHasta, selectedTipos, selectedEstados, selectedUbicaciones, selectedCalidades, includeAnulados], () => {
  // Cancelar timeout previo si existe
  if (filterChangeTimeout) {
    clearTimeout(filterChangeTimeout)
  }

  // Actualizar noFilter si es necesario
  const hasAnyFilter = selectedClienteIds.value.length > 0 ||
    fechaDesde.value !== null ||
    fechaHasta.value !== null ||
    selectedTipos.value.length > 0 ||
    selectedEstados.value.length > 0 ||
    selectedUbicaciones.value.length > 0 ||
    selectedCalidades.value.length > 0 ||
    includeAnulados.value

  if (hasAnyFilter && noFilter.value) {
    noFilter.value = false
  }

  // Debounce para evitar múltiples actualizaciones rápidas
  filterChangeTimeout = setTimeout(() => {
    updateFiltrados()
  }, 100)
}, { immediate: true })

// Opciones para filtros avanzados
const tiposCafeOptions = [
  { value: 'uva', label: 'Uva' },
  { value: 'oreado', label: 'Oreado' },
  { value: 'mojado', label: 'Mojado' },
  { value: 'verde', label: 'Verde' }
]

const estadosOptions = [
  { value: 'pagado', label: 'Pagado' },
  { value: 'pendiente', label: 'Pendiente' }
]

// Ubicaciones dinámicas basadas en los clientes
const ubicacionesOptions = computed(() => {
  const ubicaciones = new Set<string>()
  clientes.value?.forEach(c => {
    if (c.ubicacion) {
      ubicaciones.add(c.ubicacion)
    }
  })
  return Array.from(ubicaciones).sort().map(u => ({ value: u, label: u }))
})

// Calidades dinámicas basadas en los ingresos
const calidadesOptions = computed(() => {
  const calidades = new Set<string>()
  ingresos.value?.forEach(i => {
    if (i.calidad) {
      calidades.add(i.calidad)
    }
  })
  return Array.from(calidades).sort().map(c => ({ value: c, label: c }))
})

// Labels for selected filters
const selectedTiposLabels = computed(() => {
  return selectedTipos.value
    .map(v => tiposCafeOptions.find(o => o.value === v)?.label)
    .filter(Boolean)
    .join(', ')
})

const selectedEstadosLabels = computed(() => {
  return selectedEstados.value
    .map(v => estadosOptions.find(o => o.value === v)?.label)
    .filter(Boolean)
    .join(', ')
})

const selectedCalidadesLabels = computed(() => {
  return selectedCalidades.value.join(', ')
})

// Check if advanced filters are active
const hasAdvancedFilters = computed(() => {
  return selectedTipos.value.length > 0 ||
    selectedEstados.value.length > 0 ||
    selectedUbicaciones.value.length > 0 ||
    selectedCalidades.value.length > 0
})

// Clear advanced filters
function clearAdvancedFilters() {
  selectedTipos.value = []
  selectedEstados.value = []
  selectedUbicaciones.value = []
  selectedCalidades.value = []
}

async function onToggleAnulados(newValue: boolean | 'indeterminate') {
  if (newValue === true) {
    // Pedir confirmación al activar
    const confirmed = confirm(
      '⚠️ ADVERTENCIA\n\n' +
      'Está a punto de incluir registros ANULADOS en los cálculos.\n\n' +
      'Esto puede afectar significativamente los resultados financieros y métricas.\n\n' +
      '¿Está seguro de que desea continuar?'
    )

    if (!confirmed) {
      // Si cancela, revertir el cambio
      includeAnulados.value = false
      console.log('User cancelled including anulados')
    } else {
      console.log('User confirmed including anulados')
    }
  } else {
    // Al desactivar, no pedir confirmación
    console.log('Anulados disabled')
  }
}

const rangoLegible = computed(() => {
  if (!fechaDesde.value && !fechaHasta.value) return 'Sin filtro de fecha'
  const f = fechaDesde.value ?? '—'
  const t = fechaHasta.value ?? '—'
  return `${f} → ${t}`
})

function isAnulado(row: any): boolean {
  const estado = (row?.estado ?? '').toString().toLowerCase()
  const fechaAn = row?.fecha_anulado ?? null
  return estado === 'anulado' || !!fechaAn
}

function isWithinDate(row: any, from?: string | null, to?: string | null): boolean {
  // Intentar con 'fecha' primero, luego con 'created_at'
  const fechaStr = row?.fecha || row?.created_at
  if (!fechaStr) return false

  const fecha = new Date(fechaStr)
  if (isNaN(fecha.getTime())) return false

  if (from) {
    const fd = new Date(from + 'T00:00:00-06:00')
    if (fecha < fd) return false
  }
  if (to) {
    const td = new Date(to + 'T23:59:59-06:00')
    if (fecha > td) return false
  }
  return true
}

function isClienteSelected(clienteId: number): boolean {
  // Si no hay clientes seleccionados, mostrar todos
  if (selectedClienteIds.value.length === 0) return true
  // Si hay clientes seleccionados, filtrar por ellos
  return selectedClienteIds.value.includes(clienteId)
}

function matchesTipoCafe(ingreso: IngresoRecord): boolean {
  if (selectedTipos.value.length === 0) return true
  return selectedTipos.value.includes(ingreso.tipo)
}

function matchesEstado(ingreso: IngresoRecord): boolean {
  if (selectedEstados.value.length === 0) return true
  return selectedEstados.value.includes(ingreso.estado)
}

function matchesUbicacion(ingreso: IngresoRecord): boolean {
  if (selectedUbicaciones.value.length === 0) return true
  const cliente = clientes.value?.find(c => c.id === ingreso.cliente_id)
  return cliente?.ubicacion ? selectedUbicaciones.value.includes(cliente.ubicacion) : false
}

function matchesCalidad(ingreso: IngresoRecord): boolean {
  if (selectedCalidades.value.length === 0) return true
  return ingreso.calidad ? selectedCalidades.value.includes(ingreso.calidad) : false
}

// Get selected clientes for display cards
const clientesSeleccionados = computed((): ClienteRecord[] => {
  if (selectedClienteIds.value.length === 0) return []
  return (clientes.value ?? []).filter(c => selectedClienteIds.value.includes(c.id))
})

// Remove a cliente from selection
function removeCliente(clienteId: number) {
  selectedClienteIds.value = selectedClienteIds.value.filter(id => id !== clienteId)
}

// Helper para calcular ingresos filtrados
function calculateIngresosFiltrados() {
  return (ingresos.value ?? [])
    .filter(r => (includeAnulados.value ? true : !isAnulado(r)))
    .filter(r => isWithinDate(r, fechaDesde.value, fechaHasta.value))
    .filter(r => isClienteSelected(r.cliente_id))
    .filter(r => matchesTipoCafe(r))
    .filter(r => matchesEstado(r))
    .filter(r => matchesUbicacion(r))
    .filter(r => matchesCalidad(r))
}

// Usar shallowRef para controlar cuando se actualiza
const ingresosFiltrados = shallowRef<IngresoRecord[]>([])

// Función para actualizar filtrados de forma controlada
async function updateFiltrados() {
  // Activar loading
  isFilteringData.value = true

  // Esperar a que el DOM se actualice
  await nextTick()

  // Dar dos frames para asegurar que el loading se renderice
  await new Promise(resolve => requestAnimationFrame(() => {
    requestAnimationFrame(resolve)
  }))

  // Ahora sí, calcular los filtrados
  ingresosFiltrados.value = calculateIngresosFiltrados()

  // Esperar un frame más para que Vue procese los cambios
  await new Promise(resolve => requestAnimationFrame(resolve))

  // Desactivar loading
  isFilteringData.value = false
}

const clientesFiltrados = computed((): ClienteRecord[] => {
  // Si hay clientes seleccionados, filtrar por ellos
  if (selectedClienteIds.value.length === 0) return clientes.value ?? []
  return (clientes.value ?? []).filter(c => selectedClienteIds.value.includes(c.id))
})

// Métricos basados en filtrados
const ingresosMetrics = useIngresosMetrics(ingresosFiltrados)

// Detectar si hay filtros activos (incluyendo "Sin filtros")
const hasFiltrosActivos = computed(() => {
  return selectedClienteIds.value.length > 0 ||
    fechaDesde.value !== null ||
    fechaHasta.value !== null ||
    selectedTipos.value.length > 0 ||
    selectedEstados.value.length > 0 ||
    selectedUbicaciones.value.length > 0 ||
    selectedCalidades.value.length > 0 ||
    includeAnulados.value ||
    noFilter.value
})

// Watch para mostrar automáticamente el panel de filtros si no hay barras visibles
watch([hasFiltrosActivos, filtrosCollapsed], () => {
  // Si no hay filtros activos Y el panel de filtros está colapsado, expandirlo
  if (!hasFiltrosActivos.value && filtrosCollapsed.value) {
    filtrosCollapsed.value = false
  }
})

// Toggle para vista de totales
const showMonetaryView = ref(false)

// Toggle para fullscreen de tabla
const isTableFullscreen = ref(false)

function toggleTableFullscreen() {
  isTableFullscreen.value = !isTableFullscreen.value

  // Prevenir scroll del body cuando está en fullscreen
  if (isTableFullscreen.value) {
    document.body.style.overflow = 'hidden'
  } else {
    document.body.style.overflow = ''
  }
}

// Estado temporal para mostrar selector de clientes desde el botón "+"
const showClienteSelectorTemp = ref(false)

function handleClienteSelection(newIds: number[]) {
  selectedClienteIds.value = newIds
  // Cerrar el selector temporal cuando se hace una selección
  if (newIds.length > selectedClienteIds.value.length) {
    nextTick(() => {
      showClienteSelectorTemp.value = false
    })
  }
}

// Atajo de teclado para salir de fullscreen con Escape
const handleEscape = (e: KeyboardEvent) => {
  if (e.key === 'Escape' && isTableFullscreen.value) {
    toggleTableFullscreen()
  }
}

// Cleanup cuando se desmonta el componente
onUnmounted(() => {
  window.removeEventListener('keydown', handleEscape)
  document.body.style.overflow = ''
})

// Verificar si hay datos de verde para mostrar la sección
const hasVerdeData = computed(() => {
  return ingresosMetrics.totalLbNetoVerde.value > 0 ||
         ingresosMetrics.inversionVerdeHastaFecha.value > 0 ||
         ingresosMetrics.totalLbNetoCompradoVerde.value > 0
})

// Función para obtener el conteo de registros según la vista
function getViewCount(view: ViewMode): number {
  switch (view) {
    case 'ingresos':
      return ingresosFiltrados.value.length
    case 'clientes':
      // Solo contar clientes que tienen ingresos en los datos filtrados
      return clientesFiltrados.value.filter(c =>
        ingresosFiltrados.value.some(i => i.cliente_id === c.id)
      ).length
    default:
      return 0
  }
}

// Loading and error states
const loading = computed(() => ingresosStore.isLoading || clientesStore.isLoading)
const error = computed(() => ingresosStore.error || clientesStore.error)
const loadingProgress = ref(0)
const isFilteringData = ref(false)

// Metadatos desde el store de metadata
const metadataStore = useMetadataStore()

const ingresosMetadata = computed(() => {
  const meta = metadataStore.metadata.find((t: any) => t.table === 'vista_detalle_ingresos')
  return meta ? { ...meta, name: 'ingresos' } : null
})

const clientesMetadata = computed(() => {
  const meta = metadataStore.metadata.find((t: any) => t.table === 'clientes')
  return meta ? { ...meta, name: 'clientes' } : null
})

// Detectar si los metadatos necesitan actualización
const metadatosNeedUpdate = computed(() => {
  // Comparar count de ingresos
  if (ingresosMetadata.value && ingresosMetadata.value.count) {
    if (ingresos.value.length !== ingresosMetadata.value.count) {
      return true
    }
  }

  // Comparar count de clientes
  if (clientesMetadata.value && clientesMetadata.value.count) {
    if (clientes.value.length !== clientesMetadata.value.count) {
      return true
    }
  }

  return false
})

// Actualizar el estado de warning en el layout
watch(metadatosNeedUpdate, (needsUpdate) => {
  setMetadatosNeedUpdate(needsUpdate)
}, { immediate: true })

// Load data on mount
onMounted(async () => {
  try {
    // Cargar metadatos primero
    // if (metadataStore.metadata.length === 0) {
    //   await (metadataStore as any).loadMetadata()
    // }

    // Cache primero para UX
    // await Promise.all([
    //   ingresosStore.loadFromCache(),
    //   clientesStore.loadFromCache()
    // ])

    // Si falta data, cargar en lotes
    // if (!ingresosStore.hasData || !clientesStore.hasData) {
    //   loadingProgress.value = 0
    //   let ingresosProgress = 0
    //   let clientesProgress = 0

    //   await Promise.all([
    //     ingresosStore.loadAllDataInBatches((progress) => {
    //       ingresosProgress = progress
    //       loadingProgress.value = (ingresosProgress + clientesProgress) / 2
    //     }),
    //     clientesStore.loadAllDataInBatches((progress) => {
    //       clientesProgress = progress
    //       loadingProgress.value = (ingresosProgress + clientesProgress) / 2
    //     })
    //   ])

    //   loadingProgress.value = 0
    // }
  } catch (err) {
    console.error('Error loading data:', err)
  } finally {
    // Re-evaluar presets dinámicos (hoy, semana, mes, ytd) al montar
    const dynamicPresets = ['hoy', 'semana', 'mes', 'ytd']
    if (selectedPreset.value && dynamicPresets.includes(selectedPreset.value)) {
      // Forzar re-evaluación del preset para obtener fechas actualizadas
      const currentPreset = selectedPreset.value
      selectedPreset.value = ''
      nextTick(() => {
        selectedPreset.value = currentPreset as PresetValue
      })
    }

    // Si no hay preset, usar 'hoy' por defecto
    if (!selectedPreset.value) {
      selectedPreset.value = 'hoy'
    }

    includeAnulados.value = false

    // Clear advanced filters on mount
    selectedTipos.value = []
    selectedEstados.value = []
    selectedUbicaciones.value = []
  }

  // Listener para escape key en fullscreen
  window.addEventListener('keydown', handleEscape)

  // Enviar counts de datasources al layout
  setDatasourceCounts({
    ingresos: ingresos.value.length,
    clientes: clientes.value.length
  })

  // Watch para actualizar counts de datasources cuando cambien
  watch([ingresos, clientes], () => {
    setDatasourceCounts({
      ingresos: ingresos.value.length,
      clientes: clientes.value.length
    })
  })

  // Watch para actualizar resultados filtrados en el navbar
  watch([ingresosFiltrados, clientesFiltrados], () => {
    setFilteredResults({
      ingresos: ingresosFiltrados.value.length,
      clientes: clientesFiltrados.value.length
    })
  }, { immediate: true })

  // Actualizar resumen de filtros cuando cambien
  watch([selectedClienteIds, fechaDesde, fechaHasta, selectedTipos, selectedEstados, selectedUbicaciones, selectedCalidades, includeAnulados], () => {
    const filtrosActivos: string[] = []

    if (selectedClienteIds.value.length > 0) {
      filtrosActivos.push(`${selectedClienteIds.value.length} cliente${selectedClienteIds.value.length > 1 ? 's' : ''}`)
    }
    if (fechaDesde.value || fechaHasta.value) {
      filtrosActivos.push('rango de fechas')
    }
    if (selectedTipos.value.length > 0) {
      filtrosActivos.push(`${selectedTipos.value.length} tipo${selectedTipos.value.length > 1 ? 's' : ''}`)
    }
    if (selectedEstados.value.length > 0) {
      filtrosActivos.push(`${selectedEstados.value.length} estado${selectedEstados.value.length > 1 ? 's' : ''}`)
    }
    if (selectedUbicaciones.value.length > 0) {
      filtrosActivos.push(`${selectedUbicaciones.value.length} ubicación${selectedUbicaciones.value.length > 1 ? 'es' : ''}`)
    }
    if (selectedCalidades.value.length > 0) {
      filtrosActivos.push(`${selectedCalidades.value.length} calidad${selectedCalidades.value.length > 1 ? 'es' : ''}`)
    }
    if (includeAnulados.value) {
      filtrosActivos.push('incluye anulados')
    }

    if (filtrosActivos.length > 0) {
      setFiltrosResumen(
        filtrosActivos.length,
        filtrosActivos.join(', '),
        ingresosFiltrados.value.length
      )
    } else {
      setFiltrosResumen(0, '', ingresosFiltrados.value.length)
    }
  }, { immediate: true })

  // Actualizar filtros activos detallados para el navbar
  watch([selectedClienteIds, fechaDesde, fechaHasta, selectedTipos, selectedEstados, selectedUbicaciones, selectedCalidades, includeAnulados, clientes], () => {
    const filters: any[] = []

    // Clientes seleccionados (mostrar cada cliente)
    if (selectedClienteIds.value.length > 0) {
      selectedClienteIds.value.forEach(id => {
        const cliente = clientes.value?.find(c => c.id === id)
        if (cliente) {
          filters.push({
            type: 'cliente',
            label: `👤 ${cliente.name}`,
            value: id,
            onRemove: () => {
              selectedClienteIds.value = selectedClienteIds.value.filter(cid => cid !== id)
            }
          })
        }
      })
    }

    // Rango de fechas
    if (fechaDesde.value || fechaHasta.value) {
      filters.push({
        type: 'fechas',
        label: `📅 ${fechaDesde.value || '—'} → ${fechaHasta.value || '—'}`,
        value: { desde: fechaDesde.value, hasta: fechaHasta.value },
        onRemove: () => {
          fechaDesde.value = null
          fechaHasta.value = null
          selectedPreset.value = ''
        }
      })
    }

    // Tipos de café
    if (selectedTipos.value.length > 0) {
      selectedTipos.value.forEach(tipo => {
        const tipoObj = tiposCafeOptions.find(t => t.value === tipo)
        if (tipoObj) {
          filters.push({
            type: 'tipo',
            label: `☕ ${tipoObj.label}`,
            value: tipo,
            onRemove: () => {
              selectedTipos.value = selectedTipos.value.filter(t => t !== tipo)
            }
          })
        }
      })
    }

    // Estados
    if (selectedEstados.value.length > 0) {
      selectedEstados.value.forEach(estado => {
        const estadoObj = estadosOptions.find(e => e.value === estado)
        if (estadoObj) {
          filters.push({
            type: 'estado',
            label: `✓ ${estadoObj.label}`,
            value: estado,
            onRemove: () => {
              selectedEstados.value = selectedEstados.value.filter(e => e !== estado)
            }
          })
        }
      })
    }

    // Ubicaciones
    if (selectedUbicaciones.value.length > 0) {
      selectedUbicaciones.value.forEach(ubicacion => {
        filters.push({
          type: 'ubicacion',
          label: `📍 ${ubicacion}`,
          value: ubicacion,
          onRemove: () => {
            selectedUbicaciones.value = selectedUbicaciones.value.filter(u => u !== ubicacion)
          }
        })
      })
    }

    // Calidades
    if (selectedCalidades.value.length > 0) {
      selectedCalidades.value.forEach(calidad => {
        filters.push({
          type: 'calidad',
          label: `⭐ ${calidad}`,
          value: calidad,
          onRemove: () => {
            selectedCalidades.value = selectedCalidades.value.filter(c => c !== calidad)
          }
        })
      })
    }

    // Incluir anulados
    if (includeAnulados.value) {
      filters.push({
        type: 'anulados',
        label: '⚠️ Con anulados',
        value: true,
        onRemove: () => {
          includeAnulados.value = false
        }
      })
    }

    setActiveFilters(filters)
  }, { immediate: true })
})
</script>

<style scoped>
.cliente-card-enter-active,
.cliente-card-leave-active {
  transition: all 0.3s ease;
}

.cliente-card-enter-from {
  opacity: 0;
  transform: scale(0.9) translateY(-10px);
}

.cliente-card-leave-to {
  opacity: 0;
  transform: scale(0.9) translateY(10px);
}

.cliente-card-move {
  transition: transform 0.3s ease;
}
</style>
