<!-- nuxt4-app/app/components/ingresos/TopClientes.vue -->
<template>
  <UCard class="brand-card border border-transparent">
    <template #header>
      <div class="flex items-center justify-between gap-4">
        <div class="flex-1">
          <h2 class="text-xl font-bold brand-section-title">
            {{ viewModeTitle }}
          </h2>
          <p class="text-xs text-[var(--brand-text-muted)] mt-1">
            Clasificados por: <span class="font-semibold text-[var(--brand-primary)]">{{ categoriaActual.label }}</span>
          </p>

          <!-- Estadísticas de ranking -->
          <div class="flex items-center gap-2 mt-2 text-xs flex-wrap">
            <div v-if="rankingStats.clientesArriba > 0" class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-purple-500/10 border border-purple-500/30">
              <UIcon name="i-lucide-arrow-up" class="w-3 h-3 text-purple-400" />
              <span class="text-purple-300 font-semibold">{{ rankingStats.clientesArriba }}</span>
              <span class="text-[var(--brand-text-muted)]">arriba</span>
              <span class="text-purple-400 font-mono">({{ rankingStats.porcentajeArriba.toFixed(1) }}%)</span>
            </div>

            <div v-if="rankingStats.clientesAbajo > 0" class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-gray-500/10 border border-gray-500/30">
              <UIcon name="i-lucide-arrow-down" class="w-3 h-3 text-[var(--brand-text-muted)]" />
              <span class="text-gray-300 font-semibold">{{ rankingStats.clientesAbajo }}</span>
              <span class="text-[var(--brand-text-muted)]">abajo</span>
              <span class="text-[var(--brand-text-muted)] font-mono">({{ rankingStats.porcentajeAbajo.toFixed(1) }}%)</span>
            </div>

            <div class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-[var(--brand-primary)]/10 border border-[var(--brand-primary)]/30">
              <UIcon name="i-lucide-users" class="w-3 h-3 text-[var(--brand-primary)]" />
              <span class="text-[var(--brand-primary)] font-semibold">{{ rankingStats.totalClientes }}</span>
              <span class="text-[var(--brand-text-muted)]">total</span>
            </div>

            <!-- Acumulado mostrado -->
            <div class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-green-500/10 border border-green-500/30">
              <UIcon name="i-lucide-trending-up" class="w-3 h-3 text-green-400" />
              <span class="text-green-400 font-semibold">{{ formatValue(acumulados.mostrados) }}</span>
              <span class="text-[var(--brand-text-muted)]">visible</span>
              <span class="text-green-400 font-mono">({{ acumulados.porcentajeMostrados.toFixed(1) }}%)</span>
            </div>

            <!-- Acumulado oculto -->
            <div v-if="acumulados.ocultos > 0" class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-orange-500/10 border border-orange-500/30">
              <UIcon name="i-lucide-trending-down" class="w-3 h-3 text-orange-400" />
              <span class="text-orange-400 font-semibold">{{ formatValue(acumulados.ocultos) }}</span>
              <span class="text-[var(--brand-text-muted)]">{{ viewMode === 'top' ? 'abajo' : viewMode === 'bottom' ? 'arriba' : 'fuera' }}</span>
              <span class="text-orange-400 font-mono">({{ acumulados.porcentajeOcultos.toFixed(1) }}%)</span>
            </div>
          </div>
        </div>
        <div class="flex items-center gap-2">
          <UInput
            v-model.number="cantidadClientes"
            type="number"
            :min="1"
            :max="100"
            size="sm"
            class="w-16"
            placeholder="10"
          />
          <div class="flex items-center gap-1 border border-[var(--brand-border)] rounded-md p-0.5">
            <UButton
              icon="i-lucide-arrow-down-wide-narrow"
              :color="viewMode === 'top' ? 'primary' : 'neutral'"
              :variant="viewMode === 'top' ? 'soft' : 'ghost'"
              size="xs"
              @click="viewMode = 'top'"
              title="Top N"
            >
              Top
            </UButton>
            <UButton
              icon="i-lucide-minus"
              :color="viewMode === 'average' ? 'warning' : 'neutral'"
              :variant="viewMode === 'average' ? 'soft' : 'ghost'"
              size="xs"
              @click="viewMode = 'average'"
              title="Average N*2+1"
            >
              Avg
            </UButton>
            <UButton
              icon="i-lucide-arrow-up-wide-narrow"
              :color="viewMode === 'bottom' ? 'error' : 'neutral'"
              :variant="viewMode === 'bottom' ? 'soft' : 'ghost'"
              size="xs"
              @click="viewMode = 'bottom'"
              title="Bottom N"
            >
              Bot
            </UButton>
          </div>
          <UInputMenu
            v-model="categoriaSeleccionada"
            :items="categorias"
            label-key="label"
            value-key="value"
            size="sm"
            icon="i-lucide-filter"
            placeholder="Seleccionar métrica"
          />
        </div>
      </div>
    </template>

    <div class="space-y-3">
      <div
        v-for="(item, index) in topClientes"
        :key="item.cliente.id"
        class="flex items-center gap-4 p-3 rounded-lg border border-[var(--brand-border)] bg-gradient-to-r from-[var(--brand-bg-secondary)] to-transparent hover:border-[var(--brand-primary)]/30 transition-all"
      >
        <!-- Ranking Badge -->
        <div
          :class="getRankingBadgeClass(index)"
        >
          {{ index + 1 }}
        </div>

        <!-- Cliente Info -->
        <div class="flex-1 min-w-0">
          <div class="font-semibold text-[var(--brand-text)] truncate">
            {{ item.cliente.name }}
          </div>
          <div class="text-xs text-[var(--brand-text-muted)] flex items-center gap-2">
            <span v-if="item.cliente.cedula" class="inline-flex items-center gap-1">
              <UIcon name="i-lucide-credit-card" class="w-3 h-3" />
              {{ item.cliente.cedula }}
            </span>
            <span v-if="item.cliente.ubicacion" class="inline-flex items-center gap-1">
              <UIcon name="i-lucide-map-pin" class="w-3 h-3" />
              {{ item.cliente.ubicacion }}
            </span>
          </div>
        </div>

        <!-- Metric Value -->
        <div class="flex-shrink-0 text-right min-w-[120px]">
          <div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-0.5">
            {{ categoriaActual.label }}
          </div>
          <div class="font-bold text-lg text-[var(--brand-primary)]">
            {{ formatValue(item.value) }}
          </div>
          <div class="text-xs text-[var(--brand-text-muted)]">
            {{ categoriaActual.unit }}
          </div>
        </div>
      </div>

      <!-- Empty State -->
      <div v-if="topClientes.length === 0" class="text-center py-8 text-[var(--brand-text-muted)]">
        <UIcon name="i-lucide-users-round" class="w-12 h-12 mx-auto mb-2 opacity-50" />
        <p>No hay datos disponibles para esta categoría</p>
        <p class="text-xs mt-1">{{ viewModeTitle }} - {{ categoriaActual.label }}</p>
      </div>
    </div>
  </UCard>
</template>

<script setup lang="ts">
import type { IngresoRecord } from '~/composables/useIngresosMetrics'

interface ClienteRecord {
  id: number
  name: string
  cedula?: number
  ubicacion?: string
  telefono?: string
  [key: string]: any
}

interface Props {
  ingresos: IngresoRecord[]
  clientes: ClienteRecord[]
}

const props = defineProps<Props>()

interface Categoria {
  value: string
  label: string
  unit: string
  calculate: (ingresos: IngresoRecord[]) => number
}

const categorias: Categoria[] = [
  {
    value: 'total-ingresos',
    label: 'Total de Ingresos',
    unit: 'registros',
    calculate: (ingresos) => ingresos.length
  },
  {
    value: 'peso-seco',
    label: 'Peso Seco Total',
    unit: 'qq',
    calculate: (ingresos) => ingresos.reduce((sum, i) => sum + (i.peso_seco || 0), 0)
  },
  {
    value: 'peso-neto',
    label: 'Peso Neto Total',
    unit: 'lb',
    calculate: (ingresos) => ingresos.reduce((sum, i) => sum + (i.peso_neto || 0), 0)
  },
  {
    value: 'inversion-total',
    label: 'Inversión Total',
    unit: 'L',
    calculate: (ingresos) => {
      return ingresos.reduce((sum, i) => {
        if (i.tipo === 'verde' || i.tipo === 'uva') {
          return sum + (i.precio * i.peso_neto)
        }
        if (i.tipo === 'oreado' || i.tipo === 'mojado') {
          return sum + ((i.precio / 2) * i.peso_seco)
        }
        return sum
      }, 0)
    }
  },
  {
    value: 'peso-uva',
    label: 'Peso Uva Total',
    unit: 'lb',
    calculate: (ingresos) => {
      return ingresos
        .filter(i => i.tipo === 'uva')
        .reduce((sum, i) => sum + (i.peso_neto || 0), 0)
    }
  },
  {
    value: 'peso-oreado',
    label: 'Peso Oreado Total',
    unit: 'qq',
    calculate: (ingresos) => {
      return ingresos
        .filter(i => i.tipo === 'oreado')
        .reduce((sum, i) => sum + (i.peso_seco || 0), 0)
    }
  },
  {
    value: 'peso-mojado',
    label: 'Peso Mojado Total',
    unit: 'qq',
    calculate: (ingresos) => {
      return ingresos
        .filter(i => i.tipo === 'mojado')
        .reduce((sum, i) => sum + (i.peso_seco || 0), 0)
    }
  },
  {
    value: 'peso-verde',
    label: 'Peso Verde Total',
    unit: 'lb',
    calculate: (ingresos) => {
      return ingresos
        .filter(i => i.tipo === 'verde')
        .reduce((sum, i) => sum + (i.peso_neto || 0), 0)
    }
  }
]

const categoriaSeleccionada = ref('total-ingresos')
const viewMode = ref<'top' | 'average' | 'bottom'>('top')
const cantidadClientes = ref(10)

const categoriaActual = computed(() => {
  return categorias.find(c => c.value === categoriaSeleccionada.value) ?? categorias[0]
})

const viewModeTitle = computed(() => {
  const cantidad = viewMode.value === 'average' ? cantidadClientes.value * 2 + 1 : cantidadClientes.value
  switch (viewMode.value) {
    case 'top':
      return `Top ${cantidadClientes.value} Clientes`
    case 'average':
      return `Average ${cantidad} Clientes`
    case 'bottom':
      return `Bottom ${cantidadClientes.value} Clientes`
    default:
      return `Top ${cantidadClientes.value} Clientes`
  }
})

interface TopClienteItem {
  cliente: ClienteRecord
  value: number
}

interface RankingStats {
  totalClientes: number
  clientesArriba: number
  clientesAbajo: number
  porcentajeArriba: number
  porcentajeAbajo: number
}

function getRankingBadgeClass(index: number): string {
  const baseClass = 'flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm'

  if (viewMode.value === 'average') {
    // En modo average, el índice central es el oro - DESTACADO
    const centralIndex = cantidadClientes.value
    if (index === centralIndex) {
      return `${baseClass} bg-yellow-500/30 text-yellow-400 border-2 border-yellow-500/70 shadow-lg shadow-yellow-500/50 scale-110`
    }

    // Posiciones antes del central: versiones más poderosas (degradado de morado a azul)
    if (index < centralIndex) {
      const normalizedPosition = index / centralIndex

      if (normalizedPosition < 0.2) {
        return `${baseClass} bg-purple-600/40 text-purple-200 border-2 border-purple-500/70 shadow-lg shadow-purple-500/30`
      } else if (normalizedPosition < 0.4) {
        return `${baseClass} bg-purple-500/35 text-purple-300 border-2 border-purple-400/60 shadow-md`
      } else if (normalizedPosition < 0.6) {
        return `${baseClass} bg-indigo-500/30 text-indigo-300 border-2 border-indigo-400/55 shadow`
      } else if (normalizedPosition < 0.8) {
        return `${baseClass} bg-blue-500/25 text-blue-300 border-2 border-blue-400/50`
      } else {
        return `${baseClass} bg-cyan-500/20 text-cyan-400 border border-cyan-400/45`
      }
    }

    // Posiciones después del central: versiones más básicas (degradado de gris a casi invisible)
    if (index > centralIndex) {
      const distanceFromCenter = index - centralIndex
      const normalizedDistance = distanceFromCenter / cantidadClientes.value

      if (normalizedDistance < 0.2) {
        return `${baseClass} bg-gray-400/20 text-gray-300 border border-gray-400/40`
      } else if (normalizedDistance < 0.4) {
        return `${baseClass} bg-gray-500/15 text-[var(--brand-text-muted)] border border-gray-500/35`
      } else if (normalizedDistance < 0.6) {
        return `${baseClass} bg-gray-600/10 text-gray-500 border border-gray-600/25`
      } else if (normalizedDistance < 0.8) {
        return `${baseClass} bg-gray-700/8 text-gray-600 border border-gray-700/20`
      } else {
        return `${baseClass} bg-gray-800/5 text-gray-700 border border-gray-800/15`
      }
    }
  }

  // Modo Top o Bottom (lógica normal)
  if (index === 0) {
    return `${baseClass} bg-yellow-500/20 text-yellow-400 border-2 border-yellow-500/50`
  }
  if (index === 1) {
    return `${baseClass} bg-gray-400/20 text-gray-300 border-2 border-gray-400/50`
  }
  if (index === 2) {
    return `${baseClass} bg-orange-500/20 text-orange-400 border-2 border-orange-500/50`
  }

  return `${baseClass} bg-[var(--brand-primary)]/10 text-[var(--brand-primary)] border border-[var(--brand-primary)]/30`
}

const topClientes = computed((): TopClienteItem[] => {
  // Agrupar ingresos por cliente
  const clienteMap = new Map<number, IngresoRecord[]>()

  props.ingresos.forEach(ingreso => {
    const clienteId = ingreso.cliente_id
    if (!clienteMap.has(clienteId)) {
      clienteMap.set(clienteId, [])
    }
    clienteMap.get(clienteId)!.push(ingreso)
  })

  // Calcular métrica para cada cliente
  const results: TopClienteItem[] = []

  clienteMap.forEach((ingresos, clienteId) => {
    const cliente = props.clientes.find(c => c.id === clienteId)
    if (!cliente) return

    // Calcular el valor usando la función de la categoría actual
    const value = categoriaActual.value.calculate(ingresos)

    results.push({ cliente, value })
  })

  // Ordenar descendente (mayor a menor) siempre
  const sorted = results.sort((a, b) => b.value - a.value)

  let finalResults: TopClienteItem[] = []

  // Seleccionar registros según el modo
  switch (viewMode.value) {
    case 'top':
      finalResults = sorted.slice(0, cantidadClientes.value)
      break

    case 'bottom':
      // Tomar los últimos N (inverso)
      finalResults = sorted.slice(-cantidadClientes.value).reverse()
      break

    case 'average':
      // Tomar N*2+1 clientes centrados (posición central es el oro)
      const totalClientes = sorted.length
      const totalAverage = cantidadClientes.value * 2 + 1
      if (totalClientes < totalAverage) {
        // Si hay menos del total, mostrar todos
        finalResults = sorted
      } else {
        // Calcular el índice central
        const midIndex = Math.floor(totalClientes / 2)
        // Tomar N antes, el central, y N después
        const startIndex = Math.max(0, midIndex - cantidadClientes.value)
        finalResults = sorted.slice(startIndex, startIndex + totalAverage)
      }
      break

    default:
      finalResults = sorted.slice(0, cantidadClientes.value)
  }

  // Debug log
  console.log(`${viewMode.value.toUpperCase()} Clientes - Categoría:`, categoriaActual.value.label)
  console.log(`${viewMode.value.toUpperCase()} Clientes - Top 3:`, finalResults.slice(0, 3).map(s => ({
    name: s.cliente.name,
    value: s.value,
    unit: categoriaActual.value.unit
  })))

  return finalResults
})

// Acumulados para header y footer
const acumulados = computed(() => {
  // Agrupar ingresos por cliente
  const clienteMap = new Map<number, IngresoRecord[]>()

  props.ingresos.forEach(ingreso => {
    const clienteId = ingreso.cliente_id
    if (!clienteMap.has(clienteId)) {
      clienteMap.set(clienteId, [])
    }
    clienteMap.get(clienteId)!.push(ingreso)
  })

  // Calcular métrica para cada cliente
  const allResults: TopClienteItem[] = []

  clienteMap.forEach((ingresos, clienteId) => {
    const cliente = props.clientes.find(c => c.id === clienteId)
    if (!cliente) return

    const value = categoriaActual.value.calculate(ingresos)
    allResults.push({ cliente, value })
  })

  // Ordenar descendente
  const sorted = allResults.sort((a, b) => b.value - a.value)

  // Calcular acumulados según el modo
  let acumuladoMostrados = 0
  let acumuladoOcultos = 0

  if (viewMode.value === 'top') {
    // Top N: sumar los primeros N
    const topItems = sorted.slice(0, cantidadClientes.value)
    const bottomItems = sorted.slice(cantidadClientes.value)

    acumuladoMostrados = topItems.reduce((sum, item) => sum + item.value, 0)
    acumuladoOcultos = bottomItems.reduce((sum, item) => sum + item.value, 0)
  } else if (viewMode.value === 'bottom') {
    // Bottom N: sumar los últimos N
    const bottomItems = sorted.slice(-cantidadClientes.value)
    const topItems = sorted.slice(0, -cantidadClientes.value)

    acumuladoMostrados = bottomItems.reduce((sum, item) => sum + item.value, 0)
    acumuladoOcultos = topItems.reduce((sum, item) => sum + item.value, 0)
  } else if (viewMode.value === 'average') {
    // Average N*2+1: sumar los del medio
    const totalClientes = sorted.length
    const totalAverage = cantidadClientes.value * 2 + 1
    if (totalClientes < totalAverage) {
      acumuladoMostrados = sorted.reduce((sum, item) => sum + item.value, 0)
      acumuladoOcultos = 0
    } else {
      const midIndex = Math.floor(totalClientes / 2)
      const startIndex = Math.max(0, midIndex - cantidadClientes.value)
      const avgItems = sorted.slice(startIndex, startIndex + totalAverage)
      const otherItems = [...sorted.slice(0, startIndex), ...sorted.slice(startIndex + totalAverage)]

      acumuladoMostrados = avgItems.reduce((sum, item) => sum + item.value, 0)
      acumuladoOcultos = otherItems.reduce((sum, item) => sum + item.value, 0)
    }
  }

  const totalAcumulado = acumuladoMostrados + acumuladoOcultos
  const porcentajeMostrados = totalAcumulado > 0 ? (acumuladoMostrados / totalAcumulado) * 100 : 0
  const porcentajeOcultos = totalAcumulado > 0 ? (acumuladoOcultos / totalAcumulado) * 100 : 0

  return {
    mostrados: acumuladoMostrados,
    ocultos: acumuladoOcultos,
    porcentajeMostrados,
    porcentajeOcultos
  }
})

const rankingStats = computed((): RankingStats => {
  // Agrupar todos los clientes primero para obtener el total
  const clienteMap = new Map<number, IngresoRecord[]>()

  props.ingresos.forEach(ingreso => {
    const clienteId = ingreso.cliente_id
    if (!clienteMap.has(clienteId)) {
      clienteMap.set(clienteId, [])
    }
    clienteMap.get(clienteId)!.push(ingreso)
  })

  const totalClientes = clienteMap.size

  let clientesArriba = 0
  let clientesAbajo = 0

  if (viewMode.value === 'top') {
    // En Top N, todos los demás están abajo
    clientesArriba = 0
    clientesAbajo = Math.max(0, totalClientes - cantidadClientes.value)
  } else if (viewMode.value === 'bottom') {
    // En Bottom N, todos los demás están arriba
    clientesArriba = Math.max(0, totalClientes - cantidadClientes.value)
    clientesAbajo = 0
  } else if (viewMode.value === 'average') {
    // En Average N*2+1, calcular cuántos hay arriba y abajo
    const totalAverage = cantidadClientes.value * 2 + 1
    if (totalClientes <= totalAverage) {
      clientesArriba = 0
      clientesAbajo = 0
    } else {
      const midIndex = Math.floor(totalClientes / 2)
      const startIndex = Math.max(0, midIndex - cantidadClientes.value)
      const endIndex = startIndex + totalAverage

      clientesArriba = startIndex
      clientesAbajo = Math.max(0, totalClientes - endIndex)
    }
  }

  const porcentajeArriba = totalClientes > 0 ? (clientesArriba / totalClientes) * 100 : 0
  const porcentajeAbajo = totalClientes > 0 ? (clientesAbajo / totalClientes) * 100 : 0

  return {
    totalClientes,
    clientesArriba,
    clientesAbajo,
    porcentajeArriba,
    porcentajeAbajo
  }
})

function formatValue(value: number): string {
  const unit = categoriaActual.value.unit

  if (unit === 'L') {
    // Formato monetario
    return new Intl.NumberFormat('es-HN', {
      style: 'currency',
      currency: 'HNL',
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    }).format(value).replace('HNL', 'L')
  }

  if (unit === 'registros') {
    return value.toString()
  }

  // Formato numérico con decimales
  return value.toLocaleString('es-HN', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  })
}
</script>
