$ErrorActionPreference = 'Stop'

$Workspace = 'C:\Users\user\Documents\New project'
$TerminalRoot = 'C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\2FA8A7E69CED7DC259B1AD86A247F675'
$ProfileDir = Join-Path $TerminalRoot 'MQL5\Profiles\Tester'
$TemplateIni = Join-Path $ProfileDir 'KOUCHA_GOLD_KIWAMI_SURVIVAL_TICK.GOLD.M5.20260521_20260529.000.ini'
$OutRoot = Join-Path $Workspace 'KOUCHA_GOLD_LATE_SINGLE_FATAL_EXIT_COMPARE'

if (!(Test-Path -LiteralPath $TemplateIni)) {
    throw "Template tester profile not found: $TemplateIni"
}

New-Item -ItemType Directory -Force -Path $OutRoot | Out-Null

$segments = @(
    @{ Segment='S1'; From='2026.05.18'; To='2026.05.20' },
    @{ Segment='S2'; From='2026.05.20'; To='2026.05.22' },
    @{ Segment='S3'; From='2026.05.25'; To='2026.05.27' },
    @{ Segment='S4'; From='2026.05.27'; To='2026.05.29' }
)

$patterns = @(
    @{ Pattern='A2_BASE'; UseSingle='false'; Soft='2500.0'; Hard='3200.0'; OppScore='88.0'; OppDiff='25.0'; MinHold='600'; UseCooldown='false'; M5='false'; MaxDay='0'; MaxSeg='0'; VixStrict='true' },
    @{ Pattern='F1_LateSingleFatalExit'; UseSingle='true'; Soft='2500.0'; Hard='3200.0'; OppScore='88.0'; OppDiff='25.0'; MinHold='600'; UseCooldown='false'; M5='false'; MaxDay='0'; MaxSeg='0'; VixStrict='true' },
    @{ Pattern='F2_LateSingleFatalExit_Strict'; UseSingle='true'; Soft='2800.0'; Hard='3500.0'; OppScore='90.0'; OppDiff='28.0'; MinHold='600'; UseCooldown='false'; M5='false'; MaxDay='0'; MaxSeg='0'; VixStrict='true' },
    @{ Pattern='F3_LateSingleFatalExit_WithCooldown'; UseSingle='true'; Soft='2500.0'; Hard='3200.0'; OppScore='88.0'; OppDiff='25.0'; MinHold='600'; UseCooldown='true'; M5='true'; MaxDay='1'; MaxSeg='2'; VixStrict='true' },
    @{ Pattern='F4_LateSingleFatalExit_Strict_WithCooldown'; UseSingle='true'; Soft='2800.0'; Hard='3500.0'; OppScore='90.0'; OppDiff='28.0'; MinHold='600'; UseCooldown='true'; M5='true'; MaxDay='1'; MaxSeg='2'; VixStrict='true' }
)

$testerOverridesBase = [ordered]@{
    Expert='KOUCHA_GOLD_KIWAMI_SURVIVAL_TICK.ex5'
    Symbol='GOLD'
    Period='M5'
    Optimization='0'
    Model='0'
    Deposit='50000'
    Currency='JPY'
    Leverage='1:888'
    Visual='0'
    ReplaceReport='1'
    ShutdownTerminal='1'
}

$inputBase = [ordered]@{
    TargetSymbol='GOLD'
    AllowMartingale='false'
    MaxTotalPositions='3'
    MaxBuyPositions='2'
    MaxSellPositions='2'
    MaxNetPositions='1'
    EntryScoreThreshold='82.0'
    MinimumScoreDifference='15.0'
    EntryCooldownSeconds='180'
    HardStopCooldownMinutes='240'
    UseBacktestLightLogMode='true'
    AuditSummaryOnlyMode='true'
    AuditSummaryIntervalMinutes='60'
    UseCsvLog='false'
    LogOnlyTradeEvents='true'
    ShowChartStatus='false'
    LogRejectedEntryReasons='false'
    LogShadowEntryCandidates='false'
    ResetLogOnInit='true'
    UseEntryOpportunityAudit='true'
    UseHistoricalTimeRiskFilter='true'
    HistoricalTimeOffsetHours='0'
    HighRiskHoursSourceTime='15,16,17,18'
    CautionRiskHoursSourceTime='10,19'
    QuietBlockHoursSourceTime='0,23'
    BlockNewEntryInQuietHours='true'
    HighRiskEntryScoreAdd='8.0'
    CautionRiskEntryScoreAdd='5.0'
    UseWeekdayHourRiskBlock='true'
    WeekdayHourRiskBlocksSourceTime='3-15,3-16,3-17,4-15,4-16,4-17'
    UseStructureBeforeTickEntry='false'
    AllowPureTickEntry='true'
    RequireTickScoreAfterStructure='false'
    UseGoldStructureFilter='false'
    UseCandlePatternConfirmation='false'
    UseCandlePatternDangerFilter='false'
    UseNewsFilter='true'
    NewsMode='2'
    UseNewsCsvFallback='true'
    UseMt5EconomicCalendar='false'
    NewsCsvFileName='news_blackout.csv'
    SingleEarlyExitRequireMaSlopeReverse='true'
    SingleEarlyExitRequireTrendMainReverse='true'
    SingleEarlyExitOnlyWhenNoHedge='true'
    SingleEarlyExitOnlySinglePosition='true'
    SingleEarlyExitBlockIfNewsActive='false'
    SingleEarlyExitAllowDuringHardStopRisk='true'
    UseLargeCandleEntryCautionForSinglePosition='false'
    LargeCandleEntryScoreAddForSingle='5.0'
    BlockEntryOnLargeCandleAgainstMaTrend='false'
    SingleEarlyExitPostCooldownMinutes='120'
    BlockSameDirectionReentryAfterSingleEarlyExit='true'
    BlockAllNewEntryAfterSingleEarlyExit='false'
    SingleEarlyExitConfirmBars='2'
    SingleEarlyExitRequireHardTrendReverseToo='true'
    SingleEarlyExitVixCautionScoreAdd='3.0'
    SingleEarlyExitVixCautionLossAddYen='300.0'
}

function Set-IniValue {
    param([string[]]$Lines, [string]$Key, [string]$Value)
    $escaped = [regex]::Escape($Key)
    for ($i = 0; $i -lt $Lines.Count; $i++) {
        if ($Lines[$i] -match "^$escaped=") {
            $parts = $Lines[$i].Split('=', 2)
            $tail = ''
            if ($parts.Count -eq 2 -and $parts[1].Contains('||')) {
                $tail = '||' + ($parts[1].Substring($parts[1].IndexOf('||') + 2))
            }
            $Lines[$i] = "$Key=$Value$tail"
            return ,$Lines
        }
    }
    return ,($Lines + "$Key=$Value")
}

$template = [string[]](Get-Content -LiteralPath $TemplateIni -Encoding Unicode)
$manifest = @()

foreach ($segment in $segments) {
    foreach ($pattern in $patterns) {
        $testName = "$($pattern.Pattern)_$($segment.Segment)_$($segment.From.Replace('.',''))_$($segment.To.Replace('.',''))"
        $testDir = Join-Path $OutRoot $testName
        New-Item -ItemType Directory -Force -Path $testDir | Out-Null

        $lines = [string[]]$template
        $testerOverrides = [ordered]@{}
        foreach ($kv in $testerOverridesBase.GetEnumerator()) { $testerOverrides[$kv.Key] = $kv.Value }
        $testerOverrides['FromDate'] = $segment.From
        $testerOverrides['ToDate'] = $segment.To
        $testerOverrides['Report'] = Join-Path $testDir ($testName + '_report.htm')

        foreach ($kv in $testerOverrides.GetEnumerator()) { $lines = Set-IniValue -Lines $lines -Key $kv.Key -Value $kv.Value }
        foreach ($kv in $inputBase.GetEnumerator()) { $lines = Set-IniValue -Lines $lines -Key $kv.Key -Value $kv.Value }

        $lines = Set-IniValue -Lines $lines -Key 'UseSinglePositionContraryEarlyExit' -Value $pattern.UseSingle
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitSoftLossYen' -Value $pattern.Soft
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitHardLossYen' -Value $pattern.Hard
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitOppositeTickScore' -Value $pattern.OppScore
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitOppositeScoreDiff' -Value $pattern.OppDiff
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitMinHoldSeconds' -Value $pattern.MinHold
        $lines = Set-IniValue -Lines $lines -Key 'UseSingleEarlyExitPostCooldown' -Value $pattern.UseCooldown
        $lines = Set-IniValue -Lines $lines -Key 'MaxSingleEarlyExitPerDay' -Value $pattern.MaxDay
        $lines = Set-IniValue -Lines $lines -Key 'MaxSingleEarlyExitPerSegment' -Value $pattern.MaxSeg
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitRequireM5CloseConfirmation' -Value $pattern.M5
        $lines = Set-IniValue -Lines $lines -Key 'SingleEarlyExitStricterWhenVixCaution' -Value $pattern.VixStrict

        $iniPath = Join-Path $testDir ($testName + '.ini')
        Set-Content -LiteralPath $iniPath -Value $lines -Encoding Unicode

        $setLines = @()
        $inInputs = $false
        foreach ($line in $lines) {
            if ($line -eq '[TesterInputs]') { $inInputs = $true; continue }
            if ($line.StartsWith('[') -and $line -ne '[TesterInputs]') { $inInputs = $false }
            if ($inInputs -and $line -ne '') { $setLines += $line }
        }
        $setPath = Join-Path $testDir ($testName + '.set')
        Set-Content -LiteralPath $setPath -Value $setLines -Encoding Unicode

        $manifest += [pscustomobject]@{
            TestName=$testName
            Pattern=$pattern.Pattern
            Segment=$segment.Segment
            FromDate=$segment.From
            ToDate=$segment.To
            Ini=$iniPath
            Set=$setPath
            ExpectedDeposit='50000'
            ExpectedLeverage='1:888'
            ExpectedUseSingle=$pattern.UseSingle
            ExpectedSoft=$pattern.Soft
            ExpectedHard=$pattern.Hard
            ExpectedOppScore=$pattern.OppScore
            ExpectedOppDiff=$pattern.OppDiff
            ExpectedUseCooldown=$pattern.UseCooldown
            ExpectedM5=$pattern.M5
            ExpectedMaxDay=$pattern.MaxDay
            ExpectedMaxSeg=$pattern.MaxSeg
        }
    }
}

$manifest | Export-Csv -LiteralPath (Join-Path $OutRoot 'late_single_fatal_exit_manifest.csv') -NoTypeInformation -Encoding UTF8
Write-Host "Generated late single fatal exit configs: $OutRoot"
