import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" import type { Usuario } from '@/types' export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } export function formatDateDDMMYYYY(dateString: string): string { if (!dateString) return ''; const parts = dateString.split('-'); if (parts.length !== 3) return dateString; const [year, month, day] = parts; return `${day}-${month}-${year}`; } export function getLocalToday(): string { const d = new Date(); const year = d.getFullYear(); const month = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } export function getNombreProfesional(user?: Usuario | null): string { if (!user) return 'Admin'; const apellido = user.apellido?.trim() || ''; const nombre = user.nombre?.trim() || ''; if (apellido && nombre) return `${apellido}, ${nombre}`; if (apellido) return apellido; if (nombre) return nombre; return 'Admin'; } export function calcularEdad(fechaNacimiento?: string): string | number { if (!fechaNacimiento) return '-'; const hoy = new Date(); const cumple = new Date(fechaNacimiento); if (isNaN(cumple.getTime())) return '-'; let edad = hoy.getFullYear() - cumple.getFullYear(); const m = hoy.getMonth() - cumple.getMonth(); if (m < 0 || (m === 0 && hoy.getDate() < cumple.getDate())) { edad--; } return edad; } export function isCamaFueraDeGrupo( cama: { numero: string; grupoId?: string; areaId?: string; sector?: string } ): boolean { return computeSector(cama?.numero || '') === 'Fuera de Área'; } export function sortCamas(camas: T[]): T[] { if (!camas || camas.length <= 1) return camas || []; const parseBedKey = (numero: string) => { const clean = (numero || '').trim(); const match = clean.match(/^(\d{3})-(\d+)$/); if (!match) return { weight: 10, salaDir: 0, cama: 0 }; const sala = parseInt(match[1], 10); const cama = parseInt(match[2], 10); const grupo = Math.floor(sala / 100); const esPar = sala % 2 === 0; let weight = 10; let isDesc = false; if (grupo === 2) { if (!esPar) { weight = 1; isDesc = true; } else { weight = 2; isDesc = false; } } else if (grupo === 3) { if (esPar) { weight = 3; isDesc = false; } else { weight = 4; isDesc = true; } } else if (grupo === 4) { if (!esPar) { weight = 5; isDesc = true; } else { weight = 6; isDesc = false; } } const salaDir = isDesc ? -sala : sala; return { weight, salaDir, cama }; }; const mapped = camas.map(item => ({ item, key: parseBedKey(item.numero) })); mapped.sort((a, b) => { if (a.key.weight !== b.key.weight) return a.key.weight - b.key.weight; if (a.key.salaDir !== b.key.salaDir) return a.key.salaDir - b.key.salaDir; return a.key.cama - b.key.cama; }); return mapped.map(m => m.item); } export function computeSector(numero: string): "En Área" | "Fuera de Área" { if (!numero) return 'En Área'; const cleanNumero = String(numero).trim(); // Format is XXX-YY (where XXX is room number, YY is bed number in room) // Extract room number XXX (first part before hyphen if hyphen exists, or first 3 digits) const parts = cleanNumero.split('-'); const salaStr = parts[0].trim(); // Fuera de área rule 1: 3XX where XX is an odd number (e.g., 301, 303, 315, 399) // salaStr length can be 3, starting with '3' if (salaStr.length === 3 && salaStr.startsWith('3')) { const xxNum = parseInt(salaStr.slice(1), 10); if (!isNaN(xxNum) && xxNum % 2 !== 0) { return 'Fuera de Área'; } } // Fuera de área rule 2: 4XX (starts with '4', regardless of digits XX) if (salaStr.startsWith('4')) { return 'Fuera de Área'; } return 'En Área'; }