@echo off
setlocal EnableDelayedExpansion
echo ========================================
echo   FFmpeg Automatic Installer
echo ========================================
echo.

REM Check for administrator privileges
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo [INFO] No administrator privileges.
    echo If you cannot write to C:\ffmpeg, please run as administrator.
    echo.
    timeout /t 3 >nul
)

echo [*] Checking FFmpeg status in detail...
echo.

REM ===============================================
REM Step 1: Check if FFmpeg is recognized in PATH
REM ===============================================
where ffmpeg.exe >nul 2>&1
set "PATH_WORKING=%errorlevel%"

REM ===============================================
REM Step 2: Search for FFmpeg files in common locations
REM ===============================================
set "FOUND_LOCATIONS="
set "FOUND_COUNT=0"

REM List of locations to search
set SEARCH_PATHS=C:\ffmpeg\bin;C:\Program Files\ffmpeg\bin;C:\Program Files (x86)\ffmpeg\bin;%USERPROFILE%\ffmpeg\bin;C:\tools\ffmpeg\bin;C:\Software\ffmpeg\bin

for %%p in ("%SEARCH_PATHS:;=" "%") do (
    set "CHECK_PATH=%%~p"
    if exist "!CHECK_PATH!\ffmpeg.exe" (
        set /a FOUND_COUNT+=1
        if defined FOUND_LOCATIONS (
            set "FOUND_LOCATIONS=!FOUND_LOCATIONS!;!CHECK_PATH!"
        ) else (
            set "FOUND_LOCATIONS=!CHECK_PATH!"
        )
    )
)

REM ===============================================
REM Step 3: Situation assessment and response
REM ===============================================

if %PATH_WORKING% equ 0 (
    REM Case 1: FFmpeg is recognized in PATH
    echo [OK] FFmpeg is recognized in PATH
    echo.
    echo [*] FFmpeg location:
    where ffmpeg.exe
    echo.
    echo [*] Current version:
    ffmpeg -version 2>nul | find "ffmpeg version"
    echo.
    
    goto :case_path_working
    
) else (
    if %FOUND_COUNT% gtr 0 (
        REM Case 2: Files exist but PATH is not configured
        echo [X] FFmpeg is not recognized in PATH
        echo [OK] However, FFmpeg files were found
        echo.
        echo [*] Found FFmpeg locations:
        for %%l in ("%FOUND_LOCATIONS:;=" "%") do (
            set "LOC=%%~l"
            echo   - !LOC!\ffmpeg.exe
            
            REM Display version information
            for /f "delims=" %%v in ('"!LOC!\ffmpeg.exe" -version 2^>nul ^| find "ffmpeg version"') do (
                echo     %%v
            )
        )
        echo.
        
        goto :case_no_path
        
    ) else (
        REM Case 3: FFmpeg not found
        echo [X] FFmpeg not found
        echo.
        
        goto :case_not_found
    )
)

:case_path_working
REM ===============================================
REM Case 1: PATH is already configured
REM ===============================================
echo =====================================
echo   Case 1: FFmpeg Update Check
echo =====================================
echo.
echo FFmpeg is already working properly.
echo Do you want to update to the latest version?
echo.
echo [*] Benefits of updating:
echo   - Latest features and bug fixes
echo   - New codec support
echo   - Performance improvements
echo.

set /p "UPDATE_CHOICE=Update to latest version? (Y/N): "

if /i "!UPDATE_CHOICE!"=="Y" (
    echo Updating existing FFmpeg to latest version...
    echo.
    
    REM Identify the location of the currently used FFmpeg
    for /f "delims=" %%i in ('where ffmpeg.exe') do (
        set "CURRENT_FFMPEG=%%i"
        goto :found_current
    )
    
    :found_current
    for %%f in ("!CURRENT_FFMPEG!") do set "CURRENT_DIR=%%~dpf"
    echo [*] Update target: !CURRENT_DIR!
    
    REM Set installation destination according to that location
    set "INSTALL_DIR=!CURRENT_DIR:~0,-5!"
    set "TARGET_PATH=!CURRENT_DIR:~0,-1!"
    
    goto :install
) else (
    echo Update cancelled.
    echo Please continue using your current FFmpeg.
    goto :end
)

:case_no_path
REM ===============================================
REM Case 2: Files exist but PATH is not configured
REM ===============================================
echo =====================================
echo   Case 2: PATH Setup + Update Check
echo =====================================
echo.
echo FFmpeg is installed but PATH is not configured.
echo First, configure PATH to make FFmpeg available.
echo.

REM Use the first found FFmpeg
for %%l in ("%FOUND_LOCATIONS:;=" "%") do (
    set "FIRST_LOCATION=%%~l"
    goto :found_first
)

:found_first
echo [*] PATH configuration target: !FIRST_LOCATION!
echo.

REM Execute PATH configuration
echo [*] Configuring PATH...

REM Get current user PATH
for /f "tokens=2*" %%i in ('reg query "HKCU\Environment" /v PATH 2^>nul ^| find "PATH"') do set USER_PATH=%%j
if not defined USER_PATH set USER_PATH=

REM Check if already included in PATH
echo !USER_PATH! | find /i "!FIRST_LOCATION!" >nul
if !errorlevel! equ 0 (
    echo [OK] Already configured in PATH
) else (
    if "!USER_PATH!"=="" (
        set "NEW_PATH=!FIRST_LOCATION!"
    ) else (
        set "NEW_PATH=!USER_PATH!;!FIRST_LOCATION!"
    )
    
    reg add "HKCU\Environment" /v PATH /t REG_EXPAND_SZ /d "!NEW_PATH!" /f >nul 2>&1
    if !errorlevel! equ 0 (
        echo [OK] PATH configuration complete!
    ) else (
        echo [X] PATH configuration failed
    )
)

REM System notification
echo [*] Notifying system of environment variable changes...
powershell.exe -Command "& {Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition '[DllImport(\"user32.dll\", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);'; $HWND_BROADCAST = [IntPtr]0xffff; $WM_SETTINGCHANGE = 0x1a; $result = [UIntPtr]::Zero; [Win32.NativeMethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, 'Environment', 2, 5000, [ref]$result) | Out-Null; Write-Host '[OK] Environment variable change notification sent' -ForegroundColor Green}"

echo.
echo [OK] PATH configuration complete!
echo.

REM Version check and update selection
echo [*] Current FFmpeg version:
"!FIRST_LOCATION!\ffmpeg.exe" -version 2>nul | find "ffmpeg version"
echo.

set /p "UPDATE_CHOICE2=Update to latest version? (Y/N): "

if /i "!UPDATE_CHOICE2!"=="Y" (
    echo Updating to latest version...
    echo.
    
    REM Set update target
    for %%f in ("!FIRST_LOCATION!") do set "PARENT_DIR=%%~dpf"
    set "INSTALL_DIR=!PARENT_DIR:~0,-5!"
    set "TARGET_PATH=!FIRST_LOCATION!"
    
    goto :install
) else (
    echo Update skipped.
    echo FFmpeg is now available via PATH configuration.
    goto :end
)

:case_not_found
REM ===============================================
REM Case 3: FFmpeg not found (New installation)
REM ===============================================
echo =====================================
echo   Case 3: New Installation
echo =====================================
echo.
echo FFmpeg was not found in common folders.
echo Will install FFmpeg to C:\ffmpeg.
echo.
echo [*] Installation contents:
echo   - Download latest FFmpeg
echo   - Extract to C:\ffmpeg
echo   - Configure PATH environment variable
echo   - Notify system
echo.

set /p "INSTALL_CHOICE=Start installation? (Y/N): "

if /i "!INSTALL_CHOICE!"=="Y" (
    echo Starting new installation...
    echo.
    
    set "INSTALL_DIR=C:\ffmpeg"
    set "TARGET_PATH=C:\ffmpeg\bin"
    
    goto :install
) else (
    echo Installation cancelled.
    goto :end
)

:install
REM ===============================================
REM Installation process
REM ===============================================
echo ========================================
echo   Installation Started
echo ========================================
echo.
echo [*] Installation destination: !INSTALL_DIR!
echo.

REM Create temporary directory
set "TEMP_DIR=%TEMP%\ffmpeg_installer"
if exist "!TEMP_DIR!" (
    echo Removing existing temporary files...
    rmdir /s /q "!TEMP_DIR!" >nul 2>&1
)
mkdir "!TEMP_DIR!"

REM Download
echo [*] Downloading FFmpeg... (may take several minutes)
powershell.exe -Command "& {$ProgressPreference='SilentlyContinue'; try {Invoke-WebRequest -Uri 'https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip' -OutFile '%TEMP_DIR%\ffmpeg.zip' -UseBasicParsing; Write-Host '[OK] Download complete' -ForegroundColor Green} catch {Write-Host '[X] Download error: ' $_  -ForegroundColor Red; exit 1}}"

if not exist "!TEMP_DIR!\ffmpeg.zip" (
    echo [X] Download failed.
    echo Please check your internet connection.
    echo.
    echo Press any key to exit...
    pause >nul
    goto :cleanup
)

REM Extract ZIP
echo [*] Extracting ZIP file...
powershell.exe -Command "& {Add-Type -AssemblyName System.IO.Compression.FileSystem; try {[System.IO.Compression.ZipFile]::ExtractToDirectory('%TEMP_DIR%\ffmpeg.zip', '%TEMP_DIR%'); Write-Host '[OK] Extraction complete' -ForegroundColor Green} catch {Write-Host '[X] Extraction error: ' $_  -ForegroundColor Red; exit 1}}"

REM Search for extracted folder
set "EXTRACTED_DIR="
for /d %%d in ("!TEMP_DIR!\ffmpeg-*") do (
    set "EXTRACTED_DIR=%%d"
    goto :found_extracted
)

echo [X] Extracted folder not found.
echo Press any key to exit...
pause >nul
goto :cleanup

:found_extracted

REM Create installation destination directory
echo [*] Creating installation destination directory...
if not exist "!INSTALL_DIR!" (
    mkdir "!INSTALL_DIR!" 2>nul
    if !errorlevel! neq 0 (
        echo [X] Failed to create !INSTALL_DIR!.
        echo Please run as administrator.
        echo.
        echo Press any key to exit...
        pause >nul
        goto :cleanup
    )
)

REM Copy files
echo [*] Copying FFmpeg files...
robocopy "!EXTRACTED_DIR!" "!INSTALL_DIR!" /E /NP /NFL /NDL >nul 2>&1
if !errorlevel! gtr 7 (
    echo [X] File copy failed.
    echo Press any key to exit...
    pause >nul
    goto :cleanup
)

echo [OK] File copy complete

REM PATH configuration (only for Case 3)
if "!TARGET_PATH!"=="C:\ffmpeg\bin" (
    echo [*] Configuring PATH environment variable...
    
    REM Get current user PATH
    for /f "tokens=2*" %%i in ('reg query "HKCU\Environment" /v PATH 2^>nul ^| find "PATH"') do set USER_PATH=%%j
    if not defined USER_PATH set USER_PATH=
    
    REM Check if C:\ffmpeg\bin is already included
    echo !USER_PATH! | find /i "C:\ffmpeg\bin" >nul
    if !errorlevel! equ 0 (
        echo [OK] C:\ffmpeg\bin is already configured in PATH.
    ) else (
        if "!USER_PATH!"=="" (
            set "NEW_PATH=!TARGET_PATH!"
        ) else (
            set "NEW_PATH=!USER_PATH!;!TARGET_PATH!"
        )
        
        reg add "HKCU\Environment" /v PATH /t REG_EXPAND_SZ /d "!NEW_PATH!" /f >nul 2>&1
        if !errorlevel! equ 0 (
            echo [OK] PATH configuration complete!
        ) else (
            echo [X] PATH configuration failed.
        )
    )
    
    REM System notification
    echo [*] Notifying system of environment variable changes...
    powershell.exe -Command "& {Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition '[DllImport(\"user32.dll\", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);'; $HWND_BROADCAST = [IntPtr]0xffff; $WM_SETTINGCHANGE = 0x1a; $result = [UIntPtr]::Zero; [Win32.NativeMethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, 'Environment', 2, 5000, [ref]$result) | Out-Null; Write-Host '[OK] Environment variable change notification sent' -ForegroundColor Green}"
)

REM Operation check
echo.
echo [*] Running operation check...
powershell.exe -Command "& {$env:PATH = [System.Environment]::GetEnvironmentVariable('PATH','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('PATH','User'); Write-Host 'Checking FFmpeg operation...' -ForegroundColor Yellow; try {$result = ffmpeg -version 2>&1; if ($result -like '*ffmpeg version*') {Write-Host '[OK] FFmpeg operation check successful!' -ForegroundColor Green; $result | Select-String 'ffmpeg version' | ForEach-Object {Write-Host $_.ToString() -ForegroundColor Cyan}} else {Write-Host '[X] FFmpeg is not operating normally' -ForegroundColor Red}} catch {Write-Host '[X] Problem occurred while running FFmpeg' -ForegroundColor Red; Write-Host 'Please open a new Command Prompt and try again' -ForegroundColor Yellow}}"

:cleanup
echo.
echo [*] Cleaning up temporary files...
if exist "!TEMP_DIR!" rmdir /s /q "!TEMP_DIR!" >nul 2>&1

:end
echo.
echo ========================================
echo   Complete
echo ========================================
echo.
echo [OK] Process complete!
echo.
echo [*] FFmpeg executable: !INSTALL_DIR!\bin\ffmpeg.exe
echo [*] PATH configuration: Complete
echo [*] System notification: Sent
echo.
echo [*] Usage:
echo   Open a new Command Prompt or PowerShell
echo   and run "ffmpeg -version"
echo.
echo Press any key to exit...
pause >nul
