import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { requireAuth } from '@/lib/requireAuth'

const DAY_IN_MS = 24 * 60 * 60 * 1000
const PERIOD_DAYS = 30

function getTodayInParis() {
  const parts = new Intl.DateTimeFormat('en-CA', {
    timeZone: 'Europe/Paris',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).formatToParts(new Date())

  const values = Object.fromEntries(
    parts.map((part) => [part.type, part.value]),
  )

  return {
    year: Number(values.year),
    month: Number(values.month),
    day: Number(values.day),
  }
}

function createBirthdayTimestamp(year: number, month: number, day: number) {
  const lastDayOfMonth = new Date(Date.UTC(year, month, 0)).getUTCDate()
  return Date.UTC(year, month - 1, Math.min(day, lastDayOfMonth))
}

export async function GET(request: Request) {
  const authError = requireAuth(request)

  if (authError) {
    return authError
  }

  try {
    const employes = await prisma.employes.findMany({
      where: {
        Actif: true,
        COS: { not: null },
        DAN: { not: null },
      },
      select: {
        COS: true,
        NSA: true,
        PRE: true,
        DAN: true,
      },
    })

    const today = getTodayInParis()
    const todayTimestamp = Date.UTC(today.year, today.month - 1, today.day)

    const items = employes.flatMap((employe) => {
      if (employe.COS === null || employe.DAN === null) {
        return []
      }

      const birthYear = employe.DAN.getUTCFullYear()
      const birthMonth = employe.DAN.getUTCMonth() + 1
      const birthDay = employe.DAN.getUTCDate()

      let birthdayYear = today.year
      let birthdayTimestamp = createBirthdayTimestamp(
        birthdayYear,
        birthMonth,
        birthDay,
      )

      if (birthdayTimestamp < todayTimestamp) {
        birthdayYear += 1
        birthdayTimestamp = createBirthdayTimestamp(
          birthdayYear,
          birthMonth,
          birthDay,
        )
      }

      const joursRestants = Math.round(
        (birthdayTimestamp - todayTimestamp) / DAY_IN_MS,
      )

      if (joursRestants > PERIOD_DAYS) {
        return []
      }

      return [{
        cos: employe.COS,
        nom: employe.NSA,
        prenom: employe.PRE,
        age: birthdayYear - birthYear,
        date_anniversaire: new Date(birthdayTimestamp)
          .toISOString()
          .slice(0, 10),
        jours_restants: joursRestants,
      }]
    })

    items.sort((first, second) => {
      if (first.jours_restants !== second.jours_restants) {
        return first.jours_restants - second.jours_restants
      }

      return (first.nom ?? '').localeCompare(second.nom ?? '', 'fr')
    })

    return NextResponse.json(
      {
        message: 'Dashboard anniversaires retrieved successfully',
        items,
        count: items.length,
        periode_jours: PERIOD_DAYS,
      },
      { status: 200 },
    )
  } catch (error) {
    console.error('Erreur lors de la récupération des anniversaires :', error)

    return NextResponse.json(
      { message: 'Erreur lors de la récupération des anniversaires' },
      { status: 500 },
    )
  }
}
