<!-- nuxt4-app/app/components/ingresos/VistaTablaIngresosConClientes.vue -->
<script setup lang="ts">
import { h, resolveComponent } from 'vue'
import type { TableColumn } from '@nuxt/ui'
import type { IngresoRecord } from '~/composables/useIngresosMetrics'

const UButton = resolveComponent('UButton')

interface ClienteRecord {
  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
}

interface IngresoWithChildren extends IngresoRecord {
  children?: ClienteRecord[]
}

interface ClienteWithChildren extends ClienteRecord {
  children?: IngresoRecord[]
}

interface Props {
  ingresos: IngresoRecord[]
  clientes: ClienteRecord[]
  primaryView: 'ingresos' | 'clientes'
  includeClientesWithoutIngresos?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  includeClientesWithoutIngresos: false
})

// Map data based on primary view
const data = computed<(IngresoWithChildren | ClienteWithChildren)[]>(() => {
  if (props.primaryView === 'ingresos') {
    // Ingresos as parent, cliente as child
    return props.ingresos.map(ingreso => {
      const cliente = props.clientes.find(c => c.id === ingreso.cliente_id)
      return {
        ...ingreso,
        children: cliente ? [cliente] : []
      }
    })
  } else {
    // Clientes as parent, ingresos as children
    const clientesData = props.clientes.map(cliente => {
      const clienteIngresos = props.ingresos.filter(i => i.cliente_id === cliente.id)

      // Agregar campos agregados al cliente
      const peso_seco = clienteIngresos.reduce((sum, i) => sum + (i.peso_seco || 0), 0)
      const peso_neto = clienteIngresos.reduce((sum, i) => sum + (i.peso_neto || 0), 0)

      // Precio promedio ponderado (por peso_neto)
      const totalPrecioXPeso = clienteIngresos.reduce((sum, i) => sum + (i.precio * i.peso_neto), 0)
      const precio = peso_neto > 0 ? totalPrecioXPeso / peso_neto : 0

      // Estados únicos
      const estados = [...new Set(clienteIngresos.map(i => i.estado))]

      return {
        ...cliente,
        peso_seco,
        peso_neto,
        precio,
        estado: estados.length > 0 ? estados.join(', ') : '',
        children: clienteIngresos
      }
    })

    // Filter out clientes without ingresos if toggle is OFF
    if (!props.includeClientesWithoutIngresos) {
      return clientesData.filter(cliente => cliente.children && cliente.children.length > 0)
    }

    return clientesData
  }
})

// Compute table UI for thead background
const tableUi = computed(() => {
  const bgClass = props.primaryView === 'ingresos'
    ? 'bg-cyan-400/20'
    : 'bg-yellow-500/20'

  return {
    thead: `${bgClass} [&>tr>th]:text-white [&>tr>th]:font-semibold`
  }
})

const columns = computed((): TableColumn<IngresoWithChildren | ClienteWithChildren>[] => [
  {
    accessorKey: 'id',
    header: () => h('span', { class: 'text-white font-semibold' }, '#'),
    cell: ({ row }) => {
      const original = row.original as any
      const isIngreso = 'tipo' in original
      const isCliente = 'name' in original && !('tipo' in original)

      // Parent row always has button
      const isParent = row.depth === 0

      return h(
        'div',
        {
          style: {
            paddingLeft: `${row.depth * 2}rem`
          },
          class: 'flex items-center gap-2'
        },
        [
          isParent && h(UButton, {
            color: 'neutral',
            variant: 'outline',
            size: 'xs',
            icon: row.getIsExpanded() ? 'i-lucide-minus' : 'i-lucide-plus',
            class: !row.getCanExpand() && 'invisible',
            ui: {
              base: 'p-0 rounded-sm',
              leadingIcon: 'size-4'
            },
            onClick: row.getToggleExpandedHandler()
          }),
          h('span', {
            class: isCliente ? 'text-yellow-500 font-semibold' : isIngreso ? 'text-cyan-400 font-semibold' : ''
          }, String(row.getValue('id')))
        ]
      )
    }
  },
  {
    accessorKey: 'created_at',
    header: () => h('span', { class: 'text-white font-semibold' }, 'Fecha'),
    cell: ({ row }) => {
      const created = row.getValue('created_at') as string | undefined
      if (!created) return '—'
      return new Date(created).toLocaleString('es-ES', {
        day: 'numeric',
        month: 'short',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
        hour12: false
      })
    }
  },
  {
    accessorKey: 'name',
    header: () => h('span', { class: 'text-white font-semibold' }, 'Info'),
    cell: ({ row }) => {
      const original = row.original as any
      const isCliente = 'name' in original && !('tipo' in original)
      const isIngreso = 'tipo' in original

      // If it's a cliente
      if (isCliente) {
        return h('div', { class: 'flex flex-col gap-1' }, [
          h('span', { class: 'font-semibold text-yellow-500' }, original.name),
          original.ubicacion && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `📍 ${original.ubicacion}`),
          original.telefono && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `📞 ${original.telefono}`),
          original.cedula && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `🆔 ${original.cedula}`)
        ])
      }

      // If it's an ingreso
      if (isIngreso) {
        return h('div', { class: 'flex items-center gap-2' }, [
          h('span', {
            class: original.tipo === 'uva' ? 'text-purple-400' :
                  original.tipo === 'oreado' ? 'text-orange-400' :
                  original.tipo === 'mojado' ? 'text-blue-400' : 'text-green-400'
          }, original.tipo?.toUpperCase()),
          h('span', { class: 'text-xs text-gray-500' }, `Cliente ID: ${original.cliente_id}`)
        ])
      }

      return h('span', { class: 'text-gray-500' }, '—')
    }
  },
  {
    accessorKey: 'peso_seco',
    header: () => h('div', { class: 'text-right text-white font-semibold' }, 'Peso Seco (qq)'),
    cell: ({ row }) => {
      const original = row.original as any
      const isIngreso = 'tipo' in original
      const isCliente = 'name' in original && !('tipo' in original)

      // Si es cliente parent con peso_seco agregado, mostrarlo
      if (isCliente && row.depth === 0 && original.peso_seco !== undefined) {
        const peso = Number.parseFloat(original.peso_seco || 0)
        return h('div', { class: 'text-right font-medium text-yellow-500' }, peso.toFixed(2))
      }

      if (!isIngreso) return h('div', { class: 'text-right text-gray-500' }, '—')

      const peso = Number.parseFloat(row.getValue('peso_seco') || 0)
      return h('div', { class: 'text-right font-medium text-cyan-400' }, peso.toFixed(2))
    }
  },
  {
    accessorKey: 'peso_neto',
    header: () => h('div', { class: 'text-right text-white font-semibold' }, 'Peso Neto (lb)'),
    cell: ({ row }) => {
      const original = row.original as any
      const isIngreso = 'tipo' in original
      const isCliente = 'name' in original && !('tipo' in original)

      // Si es cliente parent con peso_neto agregado, mostrarlo
      if (isCliente && row.depth === 0 && original.peso_neto !== undefined) {
        const peso = Number.parseFloat(original.peso_neto || 0)
        return h('div', { class: 'text-right font-medium text-yellow-500' }, peso.toFixed(2))
      }

      if (!isIngreso) return h('div', { class: 'text-right text-gray-500' }, '—')

      const peso = Number.parseFloat(row.getValue('peso_neto') || 0)
      return h('div', { class: 'text-right font-medium text-cyan-400' }, peso.toFixed(2))
    }
  },
  {
    accessorKey: 'precio',
    header: () => h('div', { class: 'text-right text-white font-semibold' }, 'Precio'),
    cell: ({ row }) => {
      const original = row.original as any
      const isIngreso = 'tipo' in original
      const isCliente = 'name' in original && !('tipo' in original)

      // Si es cliente parent con precio agregado, mostrarlo
      if (isCliente && row.depth === 0 && original.precio !== undefined) {
        const precio = Number.parseFloat(original.precio || 0)
        const formatted = new Intl.NumberFormat('es-HN', {
          style: 'currency',
          currency: 'HNL',
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        }).format(precio).replace('HNL', 'L')

        return h('div', { class: 'text-right font-medium text-yellow-500' }, formatted)
      }

      if (!isIngreso) return h('div', { class: 'text-right text-gray-500' }, '—')

      const precio = Number.parseFloat(row.getValue('precio') || 0)
      const formatted = new Intl.NumberFormat('es-HN', {
        style: 'currency',
        currency: 'HNL',
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
      }).format(precio).replace('HNL', 'L')

      return h('div', { class: 'text-right font-medium text-cyan-400' }, formatted)
    }
  },
  {
    accessorKey: 'estado',
    header: () => h('span', { class: 'text-white font-semibold' }, 'Estado'),
    cell: ({ row }) => {
      const original = row.original as any
      const isCliente = 'name' in original && !('tipo' in original)
      const isIngreso = 'tipo' in original

      if (isCliente) {
        // Cliente row (parent) - show aggregated estados
        const isParent = row.depth === 0

        if (isParent && original.estado) {
          // Si tiene campo estado agregado, mostrarlo como badges múltiples
          const estados = original.estado.split(', ')
          return h('div', { class: 'flex flex-wrap gap-1' }, estados.map((estado: string) =>
            h('span', {
              class: estado === 'pagado'
                ? 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-green-500/20 text-green-300 border border-green-400/30 text-xs'
                : 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-yellow-500/20 text-yellow-300 border border-yellow-400/30 text-xs'
            }, estado === 'pagado' ? '✓ Pagado' : '⏳ Pendiente')
          ))
        }

        // Cliente row (child) - show if empleado
        return original.empleado
          ? h('span', { class: 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-blue-500/20 text-blue-300 border border-blue-400/30 text-xs' }, [
              h('span', '💼'),
              'Empleado'
            ])
          : h('span', { class: 'text-gray-500 text-xs' }, '—')
      }

      if (isIngreso) {
        const estado = row.getValue('estado') as string
        return h('span', {
          class: estado === 'pagado'
            ? 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-green-500/20 text-green-300 border border-green-400/30 text-xs'
            : 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-yellow-500/20 text-yellow-300 border border-yellow-400/30 text-xs'
        }, estado === 'pagado' ? '✓ Pagado' : '⏳ Pendiente')
      }

      return h('span', { class: 'text-gray-500 text-xs' }, '—')
    }
  }
])

const expanded = ref<Record<string, boolean>>({})

// Pagination
const currentPage = ref(1)
const recordsPerPage = 50

const totalRecords = computed(() => data.value.length)
const totalPages = computed(() => Math.ceil(totalRecords.value / recordsPerPage))

const startRecord = computed(() => {
  if (totalRecords.value === 0) return 0
  return (currentPage.value - 1) * recordsPerPage + 1
})

const endRecord = computed(() => {
  const end = currentPage.value * recordsPerPage
  return Math.min(end, totalRecords.value)
})

const paginatedData = computed(() => {
  const start = (currentPage.value - 1) * recordsPerPage
  const end = start + recordsPerPage
  return data.value.slice(start, end)
})

function nextPage() {
  if (currentPage.value < totalPages.value) {
    currentPage.value++
  }
}

function previousPage() {
  if (currentPage.value > 1) {
    currentPage.value--
  }
}
</script>

<template>
  <div class="flex flex-col gap-3">
    <UTable
      v-model:expanded="expanded"
      :data="paginatedData"
      :columns="columns"
      :get-sub-rows="(row: any) => row.children"
      sticky
      class="flex-1"
      :ui="{
        base: 'border-separate border-spacing-0',
        thead: tableUi.thead,
        tbody: '[&>tr]:last:[&>td]:border-b-0',
        tr: 'group',
        td: 'empty:p-0 group-has-[td:not(:empty)]:border-b border-default'
      }"
    />

    <!-- Pagination Footer -->
    <div class="flex items-center justify-between px-4 py-3 border-t border-[var(--brand-border)]">
      <span class="text-sm text-[var(--brand-text-muted)]">
        Mostrando {{ startRecord }} - {{ endRecord }} de {{ totalRecords }} registros
      </span>

      <div class="flex items-center gap-2">
        <UButton
          icon="i-lucide-chevron-left"
          color="neutral"
          variant="outline"
          size="sm"
          :disabled="currentPage === 1"
          @click="previousPage"
        />
        <span class="text-sm text-[var(--brand-text-muted)] px-2">
          Página {{ currentPage }} de {{ totalPages }}
        </span>
        <UButton
          icon="i-lucide-chevron-right"
          color="neutral"
          variant="outline"
          size="sm"
          :disabled="currentPage === totalPages"
          @click="nextPage"
        />
      </div>
    </div>
  </div>
</template>
