param (
    [string]$SourcePath,
    [string]$DriveLetter,
    [string]$VolumeName = "EstudioMedico"
)

$ErrorActionPreference = 'Stop'

function Write-Log {
    param([string]$msg, [string]$level = "INFO")
    $ts = Get-Date -Format "HH:mm:ss"
    Write-Host "[$ts][$level] $msg"
}

try {
    Write-Log "=== ROBOT MEDICO - Inicio de Grabacion ==="
    Write-Log "Unidad:  $DriveLetter"
    Write-Log "Fuente:  $SourcePath"
    Write-Log "Volumen: $VolumeName"

    # ─── 1. VALIDAR FUENTE ────────────────────────────────────────────────────
    if (-not (Test-Path $SourcePath)) {
        throw "La carpeta de origen no existe: $SourcePath"
    }

    $fuenteSize = (Get-ChildItem -Path $SourcePath -Recurse -File | Measure-Object -Property Length -Sum).Sum
    $fuenteSizeMB = [Math]::Round($fuenteSize / 1MB, 2)
    Write-Log "Tamanio de fuente: ${fuenteSizeMB} MB"

    # ─── 2. LOCALIZAR LA GRABADORA ────────────────────────────────────────────
    $letra = $DriveLetter.TrimEnd(':').ToUpper()

    $discMaster = New-Object -ComObject IMAPI2.MsftDiscMaster2
    $recorder   = $null

    foreach ($id in $discMaster) {
        $r = New-Object -ComObject IMAPI2.MsftDiscRecorder2
        $r.InitializeDiscRecorder($id)
        if ($r.DriveLetter -eq "${letra}:") {
            $recorder = $r
            break
        }
    }

    if ($null -eq $recorder) {
        throw "No se encontro una grabadora en la unidad ${letra}:"
    }
    Write-Log "Grabadora encontrada: ${letra}:"

    # ─── 3. VALIDAR ESTADO DEL DISCO ─────────────────────────────────────────
    $formatData = New-Object -ComObject IMAPI2.MsftDiscFormat2Data
    $formatData.Recorder   = $recorder
    $formatData.ClientName = "RobotMedico"

    # Obtener tipo de disco fisico
    $mediaType = $formatData.CurrentPhysicalMediaType
    # Tipos RW: CD-RW(3), DVD-RW(7), DVD+RW(8), DVD-RAM(10), BD-RE(14,17)
    $isRW = $mediaType -in @(3, 7, 8, 10, 14, 17)

    # Obtener estado del medio
    # IMAPI2_MEDIA_STATUS: 1=blank, 2=writable, 4=erasable, 8=unknown
    $mediaStatus = $formatData.CurrentMediaStatus
    $isBlank    = ($mediaStatus -band 1) -eq 1
    $isWritable = ($mediaStatus -band 2) -eq 2

    # Capacidad libre en sectores (cada sector = 2048 bytes)
    $freeSectors   = $formatData.FreeSectorsOnMedia
    $totalSectors  = $formatData.TotalSectorsOnMedia
    $freeSizeMB    = [Math]::Round($freeSectors * 2048 / 1MB, 2)
    $totalSizeMB   = [Math]::Round($totalSectors * 2048 / 1MB, 2)

    Write-Log "Tipo de disco: $mediaType | RW=$isRW | Blanco=$isBlank | Escribible=$isWritable"
    Write-Log "Capacidad total: ${totalSizeMB} MB | Libre: ${freeSizeMB} MB"

    # Verificar si el disco ya tiene datos (no blanco y no RW o no tiene espacio)
    $hasData = -not $isBlank

    if ($hasData -and -not $isRW) {
        throw "DISCO_CON_DATOS: El disco NO es regrabable (RW) y ya contiene datos. Inserte un disco en blanco."
    }

    if ($hasData -and $isRW) {
        Write-Log "DISCO RW CON DATOS DETECTADO - Borrando para regrabacion..." "WARN"

        # Borrar disco RW antes de grabar
        $eraser = New-Object -ComObject IMAPI2.MsftDiscFormat2Erase
        $eraser.Recorder              = $recorder
        $eraser.ClientName            = "RobotMedico"
        $eraser.FullErase             = $false   # Quick erase

        Write-Log "Ejecutando borrado rapido del disco RW..."
        $eraser.EraseMedia()
        Write-Log "Disco RW borrado exitosamente. Continuando con grabacion."

        # Refrescar estado tras borrado
        $formatData2 = New-Object -ComObject IMAPI2.MsftDiscFormat2Data
        $formatData2.Recorder   = $recorder
        $formatData2.ClientName = "RobotMedico"
        $freeSectors2  = $formatData2.FreeSectorsOnMedia
        $freeSizeMB    = [Math]::Round($freeSectors2 * 2048 / 1MB, 2)
        Write-Log "Espacio libre tras borrado: ${freeSizeMB} MB"
        $formatData = $formatData2
    }

    # Verificar que hay suficiente espacio
    if ($fuenteSize -gt ($freeSectors * 2048)) {
        throw "ESPACIO_INSUFICIENTE: La fuente (${fuenteSizeMB} MB) excede el espacio libre en el disco (${freeSizeMB} MB)"
    }

    Write-Log "Validacion de disco OK: $freeSizeMB MB disponibles para $fuenteSizeMB MB de datos"

    # ─── 4. CREAR IMAGEN DEL SISTEMA DE ARCHIVOS ─────────────────────────────
    Write-Log "Creando imagen del sistema de archivos..."

    $fsi = New-Object -ComObject IMAPI2FS.MsftFileSystemImage
    $fsi.ChooseImageDefaults($recorder)
    $fsi.VolumeName             = $VolumeName
    $fsi.FileSystemsToCreate    = 4  # Joliet (compatible con Windows y Linux)

    # Añadir todos los archivos de la carpeta raiz
    Write-Log "Agregando archivos desde: $SourcePath"
    $fsi.Root.AddTree($SourcePath, $false)

    $resultImage = $fsi.CreateResultImage()
    $stream      = $resultImage.ImageStream

    Write-Log "Imagen creada. Iniciando escritura en disco..."

    # ─── 5. GRABAR EN EL DISCO ───────────────────────────────────────────────
    $formatData.Recorder   = $recorder
    $formatData.ClientName = "RobotMedico"

    # Suscribirse a eventos de progreso
    Register-ObjectEvent -InputObject $formatData -EventName Update -Action {
        $pct = [Math]::Round($EventArgs.elapsedTime / [Math]::Max($EventArgs.totalTime, 1) * 100)
        Write-Host "[PROGRESO] $pct%"
    } -ErrorAction SilentlyContinue | Out-Null

    $formatData.Write($stream)
    Write-Log "Escritura en disco completada."

    # ─── 6. VERIFICACION POST-GRABACION ──────────────────────────────────────
    Write-Log "Verificando grabacion (lectura de volumen)..."
    Start-Sleep -Seconds 3

    $wmiDisk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='${letra}:'" -ErrorAction SilentlyContinue
    if ($wmiDisk -and $wmiDisk.VolumeName) {
        $volGrabado = $wmiDisk.VolumeName
        Write-Log "VERIFICACION OK: Volumen en disco = '$volGrabado' (esperado: '$VolumeName')"
        if ($volGrabado -ne $VolumeName) {
            Write-Log "AVISO: El nombre del volumen grabado ('$volGrabado') difiere del esperado ('$VolumeName')" "WARN"
        }
    } else {
        Write-Log "Verificacion de volumen omitida (el SO aun no ha montado el disco)" "WARN"
    }

    Write-Log "=== GRABACION EXITOSA en ${letra}: | Volumen: $VolumeName ==="
    exit 0

} catch {
    $errMsg = $_.Exception.Message
    Write-Host "[ERROR] $errMsg"
    Write-Host "[STDERR] $_"
    exit 1
}
