functions/DataMigration.ps1

function Get-EmojiToolsDataPath {
    <#
    .SYNOPSIS
        Gets the version-independent data directory path for EmojiTools.

    .DESCRIPTION
        Returns the path where EmojiTools stores user data (history, collections, aliases, stats).
        This path is version-independent and persists across module upgrades.

        Priority:
        1. Environment variable: $env:EMOJITOOLS_DATA_PATH
        2. Windows: $env:LOCALAPPDATA\EmojiTools
        3. Cross-platform fallback: $HOME\.emojitools

    .EXAMPLE
        Get-EmojiToolsDataPath
        Returns the data directory path (e.g., C:\Users\username\AppData\Local\EmojiTools)

    .OUTPUTS
        String - The full path to the data directory
    #>

    [CmdletBinding()]
    param()

    # Allow override via environment variable
    if ($env:EMOJITOOLS_DATA_PATH) {
        return $env:EMOJITOOLS_DATA_PATH
    }

    # Windows: Use LocalAppData
    if ($IsWindows -or $env:OS -match 'Windows') {
        if ($env:LOCALAPPDATA) {
            return Join-Path $env:LOCALAPPDATA "EmojiTools"
        }
    }

    # Cross-platform fallback: Use home directory
    return Join-Path $HOME ".emojitools"
}

function Initialize-EmojiToolsDataDirectory {
    <#
    .SYNOPSIS
        Initializes the EmojiTools data directory structure.

    .DESCRIPTION
        Creates the version-independent data directory and required subdirectories.
        Automatically migrates data from module-embedded location if this is a first run.

    .PARAMETER Force
        Force re-initialization even if directory already exists

    .EXAMPLE
        Initialize-EmojiToolsDataDirectory
        Creates the data directory structure

    .OUTPUTS
        String - The path to the initialized data directory
    #>

    [CmdletBinding()]
    param(
        [Parameter()]
        [switch]$Force
    )

    $dataPath = Get-EmojiToolsDataPath

    # Create directory if it doesn't exist
    if (-not (Test-Path $dataPath)) {
        Write-Verbose "Creating EmojiTools data directory: $dataPath"
        New-Item -ItemType Directory -Path $dataPath -Force | Out-Null
    }

    # Create subdirectories
    $subdirs = @('languages')
    foreach ($subdir in $subdirs) {
        $subdirPath = Join-Path $dataPath $subdir
        if (-not (Test-Path $subdirPath)) {
            Write-Verbose "Creating subdirectory: $subdirPath"
            New-Item -ItemType Directory -Path $subdirPath -Force | Out-Null
        }
    }

    # Check if migration is needed (first run after upgrade)
    $migrationMarker = Join-Path $dataPath ".migrated"
    $moduleDataPath = Join-Path $PSScriptRoot "..\data"

    if (-not (Test-Path $migrationMarker) -or $Force) {
        Write-Verbose "Checking for data migration from module directory..."
        Invoke-EmojiDataMigration -SourcePath $moduleDataPath -DestinationPath $dataPath -Force:$Force

        # Create migration marker with millisecond precision for Force re-migration detection
        "Migrated from module directory on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff')" |
            Set-Content $migrationMarker -Encoding UTF8
    }

    return $dataPath
}

function Invoke-EmojiDataMigration {
    <#
    .SYNOPSIS
        Migrates user data from module directory to version-independent location.

    .DESCRIPTION
        Copies user-specific data files (history, collections, aliases, stats) from the
        module's data directory to the version-independent data directory. This preserves
        user data during module upgrades.

        Files migrated:
        - history.json (usage history)
        - collections.json (custom collections)
        - aliases.json (custom aliases)
        - stats.json (usage statistics)
        - emoji.csv (cached dataset)
        - metadata.json (dataset metadata)
        - languages/* (installed language packs)

    .PARAMETER SourcePath
        Source directory (typically module's data directory)

    .PARAMETER DestinationPath
        Destination directory (version-independent data path)

    .PARAMETER Force
        Overwrite existing files in destination

    .EXAMPLE
        Invoke-EmojiDataMigration -SourcePath "C:\...\Modules\EmojiTools\1.15.0\data" -DestinationPath "C:\Users\...\AppData\Local\EmojiTools"
        Migrates data from old location to new location
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$SourcePath,

        [Parameter(Mandatory)]
        [string]$DestinationPath,

        [Parameter()]
        [switch]$Force
    )

    if (-not (Test-Path $SourcePath)) {
        Write-Verbose "Source path does not exist: $SourcePath"
        return
    }

    # Files to migrate (only if they exist in source)
    $filesToMigrate = @(
        'history.json',
        'collections.json',
        'aliases.json',
        'stats.json',
        'emoji.csv',
        'metadata.json',
        '.setup-complete'
    )

    $migratedFiles = @()
    $skippedFiles = @()

    foreach ($file in $filesToMigrate) {
        $sourceFilePath = Join-Path $SourcePath $file
        $destFilePath = Join-Path $DestinationPath $file

        if (Test-Path $sourceFilePath) {
            # Skip if destination exists and Force not specified
            if ((Test-Path $destFilePath) -and -not $Force) {
                Write-Verbose "Skipping $file (already exists in destination)"
                $skippedFiles += $file
                continue
            }

            try {
                Copy-Item -Path $sourceFilePath -Destination $destFilePath -Force
                $migratedFiles += $file
                Write-Verbose "Migrated: $file"
            }
            catch {
                Write-Warning "Failed to migrate ${file}: $_"
            }
        }
    }

    # Migrate language packs
    $sourceLangPath = Join-Path $SourcePath "languages"
    $destLangPath = Join-Path $DestinationPath "languages"

    if (Test-Path $sourceLangPath) {
        if (-not (Test-Path $destLangPath)) {
            New-Item -ItemType Directory -Path $destLangPath -Force | Out-Null
        }

        $langDirs = Get-ChildItem -Path $sourceLangPath -Directory
        foreach ($langDir in $langDirs) {
            $destLangDir = Join-Path $destLangPath $langDir.Name

            if ((Test-Path $destLangDir) -and -not $Force) {
                Write-Verbose "Skipping language pack: $($langDir.Name) (already exists)"
                continue
            }

            try {
                # Remove existing directory if Force is specified
                if ((Test-Path $destLangDir) -and $Force) {
                    Remove-Item -Path $destLangDir -Recurse -Force
                }

                Copy-Item -Path $langDir.FullName -Destination $destLangDir -Recurse -Force
                $migratedFiles += "languages/$($langDir.Name)"
                Write-Verbose "Migrated language pack: $($langDir.Name)"
            }
            catch {
                Write-Warning "Failed to migrate language pack ${langDir.Name}: $_"
            }
        }
    }

    # Report results
    if ($migratedFiles.Count -gt 0) {
        Write-Information "📦 Migrated $($migratedFiles.Count) file(s) to version-independent data directory:"
        Write-Information " $DestinationPath"
        if ($VerbosePreference -eq 'Continue') {
            $migratedFiles | ForEach-Object { Write-Verbose " ✓ $_" }
        }
    }

    if ($skippedFiles.Count -gt 0) {
        Write-Verbose "Skipped $($skippedFiles.Count) existing file(s)"
    }
}