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<T extends { numero: string }>(camas: T[]): T[] {
  const parseBedNumber = (numero: string) => {
    const match = (numero || '').match(/^(\d{3})-(\d+)$/);
    if (!match) return { sala: 0, cama: 0 };
    return {
      sala: parseInt(match[1], 10),
      cama: parseInt(match[2], 10)
    };
  };

  return [...camas].sort((a, b) => {
    const pa = parseBedNumber(a.numero);
    const pb = parseBedNumber(b.numero);

    const getOrden = (sala: number) => {
      const grupo = Math.floor(sala / 100);
      const esPar = sala % 2 === 0;

      if (grupo === 2) {
        if (!esPar) return { weight: 1, order: 'desc', sala }; // 2XX impares, mayor a menor
        return { weight: 2, order: 'asc', sala }; // 2XX pares, menor a mayor
      }
      if (grupo === 3) {
        if (esPar) return { weight: 3, order: 'asc', sala }; // 3XX pares, menor a mayor
        return { weight: 4, order: 'desc', sala }; // 3XX impares, mayor a menor
      }
      if (grupo === 4) {
        if (!esPar) return { weight: 5, order: 'desc', sala }; // 4XX impares, mayor a menor
        return { weight: 6, order: 'asc', sala }; // 4XX pares, menor a mayor
      }
      return { weight: 10, order: 'asc', sala };
    };

    const oa = getOrden(pa.sala);
    const ob = getOrden(pb.sala);

    if (oa.weight !== ob.weight) {
      return oa.weight - ob.weight;
    }

    if (oa.sala !== ob.sala) {
      if (oa.order === 'desc') {
        return ob.sala - oa.sala;
      } else {
        return oa.sala - ob.sala;
      }
    }

    return pa.cama - pb.cama;
  });
}

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';
}
