import { readdir, readFile } from 'node:fs/promises'
import { join, extname, basename } from 'node:path'
import { createHash } from 'node:crypto'
import { slugify } from './slugify'
import { getCardFromDate } from './getCardFromDate'
import type { Card } from '@/types/types'

const listAudioExts = ['.mp3', '.opus', 'flac']
const listImageExts = ['.jpg', '.jpeg', '.webp']

export async function scanMusicFolder(folderPath: string): Promise<Card[]> {
  const runtimeConfig = useRuntimeConfig()
  const urlPrefix = runtimeConfig.NUXT_URL_PREFIX

  try {
    const files = await readdir(folderPath)
    const cardMap = new Map<string, Card>()

    // D'abord, on traite tous les fichiers audio
    for (const file of files) {
      const ext = extname(file).toLowerCase()

      // On ne traite que les fichiers audio
      if (!listAudioExts.includes(ext)) continue

      const parsed = await parseFilename(join(folderPath, file))
      if (parsed) {
        // On vérifie s'il existe une image avec le même nom de base
        const baseName = basename(file, ext)
        let imageUrl = ''

        // On cherche une image correspondante
        for (const imgExt of listImageExts) {
          const potentialImage = baseName + imgExt
          if (files.includes(potentialImage)) {
            imageUrl = urlPrefix + baseName + imgExt
            break
          }
        }

        cardMap.set(parsed.esid, {
          ...parsed,
          url_audio: urlPrefix + baseName + ext,
          url_image: imageUrl,
          suit: parsed.suit,
          rank: parsed.rank
        })
      }
    }

    return Array.from(cardMap.values())
  } catch (error) {
    console.error('Erreur lors du scan du dossier:', error)
    throw error
  }
}

async function parseFilename(
  filename: string
): Promise<Omit<Card, 'url_audio' | 'url_image'> | null> {
  // Format: yyyymmddhh__artist__title.ext
  const nameWithoutExt = basename(filename, extname(filename))
  const parts = nameWithoutExt.split('__')

  if (parts.length !== 3) {
    console.warn(`Nom de fichier invalide: ${filename}`)
    return null
  }

  const [datetime, artist, title] = parts

  if (!datetime || !artist || !title) {
    console.warn(`Format de fichier invalide: ${filename} - manque des parties`)
    return null
  }

  if (datetime.length !== 10) {
    console.warn(`Format de date invalide: ${filename}`)
    return null
  }

  // Utilisation d'un hash basé sur le contenu du fichier pour un ESID stable
  let fileHash = ''
  try {
    const fileContent = await readFile(filename)
    fileHash = createHash('md5').update(fileContent).digest('hex').substring(0, 8)
  } catch (error) {
    console.warn(`Impossible de lire le fichier pour générer le hash: ${filename}`)
    fileHash = createHash('md5').update(filename).digest('hex').substring(0, 8)
  }

  const year = datetime.substring(0, 4)
  const month = datetime.substring(4, 6)
  const day = datetime.substring(6, 8)
  const hour = datetime.substring(8, 10)
  // Créer l'ID unique pour la card
  const esid = createHash('md5')
    .update(`${year}${month}${day}${hour}${artist}${title}`)
    .digest('hex')

  const date = new Date(
    parseInt(year, 10),
    parseInt(month, 10) - 1,
    parseInt(day, 10),
    parseInt(hour, 10)
  )
  const card = getCardFromDate(date)

  return {
    year,
    month,
    day,
    hour,
    artist: artist.replace(/_/g, ' '), // Remplacer les _ par des espaces
    title: title.replace(/_/g, ' '),
    esid,
    slug: slugify(`${artist} ${title}`),
    createdAt: date,
    suit: card.suit,
    rank: card.rank
  }
}
