# Fonction pour récupérer une Array des extensions d'images et vidéos depuis un json
function Get-ImageVideoExtensions {
    param (
        [string] $sourceUrl = "https://cdn.jsdelivr.net/gh/jshttp/mime-db@v1.52.0/db.json"
    )
    $jsonData = (Invoke-RestMethod $sourceUrl).PSObject.Properties
    $extensions = @()

    foreach ($item in $jsonData) {
        if ($item.Name -like "image*" -or $item.Name -like "video*") {
            $extensions += $item.Value.extensions
        }
    }

    $extensions = $extensions | Sort-Object -Unique
    return $extensions
}

# Fonction pour décompresser les archives
function Decompress-ArchiveIfNeeded {
    param(
        [string]$ArchivePath,
        [string]$ExtractPath
    )
    
    if (Test-Path $ArchivePath -PathType Leaf) {
        $tempDir = Join-Path -Path $ExtractPath -ChildPath ([System.IO.Path]::GetRandomFileName())
        while (Test-Path $tempDir) {
            $tempDir = Join-Path -Path $ExtractPath -ChildPath ([System.IO.Path]::GetRandomFileName())
        }
        New-Item -Path $tempDir -ItemType Directory | Out-Null
        Expand-Archive -Path $ArchivePath -DestinationPath $tempDir
        return $tempDir
    }
    return $null
}

# Fonction pour obtenir la date de création d'une image/vidéo
function Get-OriginalDate {
    param (
        $file
    )
    # Tentative de lecture des données EXIF
    $exif = Try { [System.Drawing.Image]::FromFile($file.FullName) } Catch { $null }

    if ($exif) {
        $exifDate = $exif.PropertyItems | Where-Object { $_.Id -eq 0x9003 } | ForEach-Object {
            [System.Text.Encoding]::ASCII.GetString($_.Value).TrimEnd([char]0)
        }
        if ($exifDate) {
            $date = [datetime]::ParseExact($exifDate, "yyyy:MM:dd HH:mm:ss", $null)
        } else {
            $date = $file.CreationTime
        }
        $exif.Dispose()
    } else {
        $date = $file.CreationTime
    }
}

# Demande des paramètres si non fournis
if (-not $args[0] -or -not $args[1]) {
    $SourceDir = Read-Host "Entrez le chemin du dossier source"
    $DestinationDir = Read-Host "Entrez le chemin du dossier destination"
} else {
    $SourceDir = $args[0]
    $DestinationDir = $args[1]
}

# Vérifie si le dossier source est une archive
if ($SourceDir -match "\.zip$") {
    $SourceDir = Decompress-ArchiveIfNeeded -ArchivePath $SourceDir -ExtractPath $env:TEMP
    if (-not $SourceDir) {
        Write-Host "L'archive n'a pas pu être décompressée."
        return
    }
}

$validExtensions = Get-ImageVideoExtensions

# Parcourt tous les fichiers récursivement dans le dossier source
Get-ChildItem -Path $SourceDir -Recurse -File | ForEach-Object {
    $file = $_
    $extension = $file.Extension.ToLower().TrimStart('.')

    if ($extension -in $validExtensions) {
        # Tentative de lecture des données EXIF
        $exif = Try { [System.Drawing.Image]::FromFile($file.FullName) } Catch { $null }

        if ($exif) {
            $exifDate = $exif.PropertyItems | Where-Object { $_.Id -eq 0x9003 } | ForEach-Object {
                [System.Text.Encoding]::ASCII.GetString($_.Value).TrimEnd([char]0)
            }
            if ($exifDate) {
                $originalDate = [datetime]::ParseExact($exifDate, "yyyy:MM:dd HH:mm:ss", $null)
            } else {
                $originalDate = $file.CreationTime
            }
            $exif.Dispose()
        } else {
            $originalDate = $file.CreationTime
        }
        
        if (-Not $originalDate) {
            $targetFolder = Join-Path -Path $DestinationDir -ChildPath "Non daté"
        } else {
            # Créer le dossier de destination basé sur l'année et le mois
            $year = $originalDate.Year
            $monthNum = $originalDate.Month.ToString("00")
            $monthName = $originalDate.ToString("MMMM", [System.Globalization.CultureInfo]::GetCultureInfo("fr-FR"))
            $targetFolder = Join-Path -Path $DestinationDir -ChildPath "$year\$monthNum - $monthName"
        }

        if (-Not (Test-Path $targetFolder)) {
            New-Item -Path $targetFolder -ItemType Directory | Out-Null
        }

        # Copier le fichier dans le dossier de destination
        Copy-Item -Path $file.FullName -Destination $targetFolder
    } else {
        Write-Host "Fichier ignoré: $($file.FullName)"
    }
}

# Suppression du dossier temporaire si nécessaire
if ($SourceDir -like "$env:TEMP\*") {
    Remove-Item -Path $SourceDir -Recurse -Force
}