<?php

require_once __DIR__ . '/admin_tool_helper.php';

ini_set('display_errors', 0);
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);

if (!function_exists('e')) {
    function e($value) { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
}

$marketDataPath = __DIR__ . '/../services/MarketDataService.php';
$candleServicePath = __DIR__ . '/../services/CandleService.php';
$configServicePath = __DIR__ . '/../services/SystemConfigService.php';
if (file_exists($marketDataPath)) require_once $marketDataPath;
if (file_exists($candleServicePath)) require_once $candleServicePath;
if (file_exists($configServicePath)) require_once $configServicePath;

function candle_admin_ensure_tables() {
    db()->exec("CREATE TABLE IF NOT EXISTS candles (
        id INT AUTO_INCREMENT PRIMARY KEY,
        symbol VARCHAR(30) NOT NULL,
        timeframe VARCHAR(20) NOT NULL,
        open_time DATETIME NOT NULL,
        open_price DECIMAL(20,8) NOT NULL,
        high_price DECIMAL(20,8) NOT NULL,
        low_price DECIMAL(20,8) NOT NULL,
        close_price DECIMAL(20,8) NOT NULL,
        volume DECIMAL(20,8) DEFAULT 0,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uniq_symbol_tf_time (symbol, timeframe, open_time),
        INDEX idx_symbol_tf (symbol, timeframe),
        INDEX idx_open_time (open_time)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
}

function candle_admin_symbols() {
    try {
        if (class_exists('SystemConfigService') && method_exists('SystemConfigService', 'getActiveSymbols')) {
            $rows = SystemConfigService::getActiveSymbols(false);
            if ($rows) return $rows;
        }
        $stmt = db()->query("SELECT DISTINCT symbol FROM candles ORDER BY symbol ASC");
        return array_map(fn($s) => ['symbol' => $s], $stmt->fetchAll(PDO::FETCH_COLUMN) ?: []);
    } catch (Throwable $e) { return []; }
}

function candle_admin_timeframes() {
    try {
        if (class_exists('SystemConfigService') && method_exists('SystemConfigService', 'getTimeframes')) {
            $rows = SystemConfigService::getTimeframes();
            if ($rows) return $rows;
        }
        $stmt = db()->query("SELECT DISTINCT timeframe AS code FROM candles ORDER BY timeframe ASC");
        return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
    } catch (Throwable $e) { return []; }
}

function candle_admin_interval_minutes($tf) {
    $tf = strtolower(trim((string)$tf));
    $map = ['1m'=>1,'3m'=>3,'5m'=>5,'15m'=>15,'30m'=>30,'1h'=>60,'2h'=>120,'4h'=>240,'1d'=>1440,'1w'=>10080];
    return $map[$tf] ?? null;
}

function candle_admin_normalize_time($value) {
    $value = trim((string)$value);
    if ($value === '') return null;
    if (is_numeric($value)) {
        $num = (int)$value;
        if ($num > 20000000000) $num = (int)floor($num / 1000);
        return date('Y-m-d H:i:s', $num);
    }
    $ts = strtotime($value);
    return $ts ? date('Y-m-d H:i:s', $ts) : null;
}

function candle_admin_num($value) {
    $value = trim((string)$value);
    $value = str_replace(',', '', $value);
    return is_numeric($value) ? (float)$value : null;
}

function candle_admin_insert($symbol, $timeframe, $openTime, $open, $high, $low, $close, $volume = 0) {
    $symbol = strtoupper(trim((string)$symbol));
    $timeframe = trim((string)$timeframe);
    $openTime = candle_admin_normalize_time($openTime);
    $open = candle_admin_num($open);
    $high = candle_admin_num($high);
    $low = candle_admin_num($low);
    $close = candle_admin_num($close);
    $volume = candle_admin_num($volume) ?? 0;
    if (!$symbol || !$timeframe || !$openTime || $open === null || $high === null || $low === null || $close === null) {
        return ['ok'=>false,'message'=>'Missing or invalid candle data.'];
    }
    if ($high < max($open, $close) || $low > min($open, $close) || $high < $low) {
        return ['ok'=>false,'message'=>'Invalid OHLC values. High/Low does not match candle body.'];
    }
    $stmt = db()->prepare("INSERT INTO candles (symbol,timeframe,open_time,open_price,high_price,low_price,close_price,volume)
        VALUES (?,?,?,?,?,?,?,?)
        ON DUPLICATE KEY UPDATE open_price=VALUES(open_price), high_price=VALUES(high_price), low_price=VALUES(low_price), close_price=VALUES(close_price), volume=VALUES(volume), updated_at=NOW()");
    $stmt->execute([$symbol,$timeframe,$openTime,$open,$high,$low,$close,$volume]);
    return ['ok'=>true,'message'=>'Candle saved successfully.'];
}

function candle_admin_fetch_recent($symbol, $timeframe, $limit = 100) {
    $stmt = db()->prepare("SELECT * FROM candles WHERE symbol=? AND timeframe=? ORDER BY open_time DESC LIMIT ?");
    $stmt->bindValue(1, strtoupper((string)$symbol));
    $stmt->bindValue(2, (string)$timeframe);
    $stmt->bindValue(3, (int)$limit, PDO::PARAM_INT);
    $stmt->execute();
    return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}

function candle_admin_stats($symbol, $timeframe) {
    $stmt = db()->prepare("SELECT COUNT(*) total, MIN(open_time) first_candle, MAX(open_time) last_candle FROM candles WHERE symbol=? AND timeframe=?");
    $stmt->execute([strtoupper((string)$symbol), (string)$timeframe]);
    return $stmt->fetch(PDO::FETCH_ASSOC) ?: ['total'=>0,'first_candle'=>null,'last_candle'=>null];
}

function candle_admin_integrity_scan($symbol, $timeframe, $limit = 500) {
    $minutes = candle_admin_interval_minutes($timeframe);
    $rows = array_reverse(candle_admin_fetch_recent($symbol, $timeframe, $limit));
    $issues = ['missing_gaps'=>[], 'invalid_ohlc'=>[], 'duplicate_count'=>0, 'total_scanned'=>count($rows)];
    foreach ($rows as $r) {
        $open=(float)$r['open_price']; $high=(float)$r['high_price']; $low=(float)$r['low_price']; $close=(float)$r['close_price'];
        if ($high < max($open,$close) || $low > min($open,$close) || $high < $low) $issues['invalid_ohlc'][]=$r;
    }
    if ($minutes && count($rows)>1) {
        for ($i=1;$i<count($rows);$i++) {
            $prev=strtotime($rows[$i-1]['open_time']); $cur=strtotime($rows[$i]['open_time']);
            $diff=(int)round(($cur-$prev)/60);
            if ($diff>$minutes) $issues['missing_gaps'][]=['from'=>$rows[$i-1]['open_time'],'to'=>$rows[$i]['open_time'],'expected_minutes'=>$minutes,'actual_minutes'=>$diff,'missing_estimate'=>max(0,(int)floor($diff/$minutes)-1)];
        }
    }
    try {
        $stmt=db()->prepare("SELECT SUM(cnt - 1) FROM (SELECT COUNT(*) cnt FROM candles WHERE symbol=? AND timeframe=? GROUP BY symbol,timeframe,open_time HAVING COUNT(*)>1) x");
        $stmt->execute([strtoupper((string)$symbol),(string)$timeframe]);
        $issues['duplicate_count']=(int)($stmt->fetchColumn() ?: 0);
    } catch (Throwable $e) { $issues['duplicate_count']=0; }
    return $issues;
}

function candle_admin_cleanup_duplicates($symbol, $timeframe) {
    $stmt = db()->prepare("DELETE c1 FROM candles c1 INNER JOIN candles c2 ON c1.symbol=c2.symbol AND c1.timeframe=c2.timeframe AND c1.open_time=c2.open_time AND c1.id<c2.id WHERE c1.symbol=? AND c1.timeframe=?");
    $stmt->execute([strtoupper((string)$symbol), (string)$timeframe]);
    return $stmt->rowCount();
}

function candle_admin_import_csv($filePath, $symbol, $timeframe) {
    if (!is_uploaded_file($filePath) && !file_exists($filePath)) return ['ok'=>false,'message'=>'CSV file not found.'];
    $handle=fopen($filePath,'r');
    if (!$handle) return ['ok'=>false,'message'=>'Could not open CSV file.'];
    $header=fgetcsv($handle);
    if (!$header) { fclose($handle); return ['ok'=>false,'message'=>'CSV file is empty.']; }
    $headerLower=array_map(fn($h)=>strtolower(trim((string)$h)),$header);
    $find=function($names) use ($headerLower){ foreach($names as $name){ $idx=array_search($name,$headerLower,true); if($idx!==false) return $idx; } return null; };
    $timeIdx=$find(['time','open_time','date','datetime','timestamp']); $openIdx=$find(['open','open_price']); $highIdx=$find(['high','high_price']); $lowIdx=$find(['low','low_price']); $closeIdx=$find(['close','close_price']); $volumeIdx=$find(['volume','vol']);
    if ($timeIdx===null || $openIdx===null || $highIdx===null || $lowIdx===null || $closeIdx===null) { fclose($handle); return ['ok'=>false,'message'=>'CSV must contain time/open/high/low/close columns.']; }
    $inserted=0; $skipped=0; $errors=[]; $rowNo=1;
    while(($row=fgetcsv($handle))!==false){
        $rowNo++;
        $result=candle_admin_insert($symbol,$timeframe,$row[$timeIdx]??'',$row[$openIdx]??'',$row[$highIdx]??'',$row[$lowIdx]??'',$row[$closeIdx]??'', $volumeIdx!==null ? ($row[$volumeIdx]??0) : 0);
        if(!empty($result['ok'])) $inserted++; else { $skipped++; if(count($errors)<5) $errors[]='Row '.$rowNo.': '.$result['message']; }
    }
    fclose($handle);
    return ['ok'=>true,'message'=>"CSV import completed. Saved: {$inserted}. Skipped: {$skipped}.",'errors'=>$errors];
}

function candle_admin_api_sync($symbol, $timeframe, $limit = 300, $provider = 'twelvedata') {
    $symbol = strtoupper(trim((string)$symbol));
    $timeframe = trim((string)$timeframe);
    $limit = max(10, min(5000, (int)$limit));
    $provider = strtolower(trim((string)$provider));
    $provider = $provider ?: 'twelvedata';

    try {
        if (class_exists('CandleService') && method_exists('CandleService', 'syncFromApi')) {
            $result = CandleService::syncFromApi($symbol, $timeframe, $limit, $provider);
            return $result;
        }

        if (!class_exists('SystemConfigService') || !class_exists('MarketDataService')) {
            return ['ok'=>false,'message'=>'SystemConfigService or MarketDataService is not available.'];
        }

        $apiInterval = method_exists('SystemConfigService','getApiInterval')
            ? SystemConfigService::getApiInterval($timeframe)
            : $timeframe;

        if (!$apiInterval) {
            $apiInterval = $timeframe;
        }

        if (!method_exists('MarketDataService','fetchCandles')) {
            return ['ok'=>false,'message'=>'No compatible MarketDataService::fetchCandles() method found.'];
        }

        ob_start();
        $candles = MarketDataService::fetchCandles($symbol, $apiInterval, $limit, $provider);
        $debug = trim(ob_get_clean());

        if (!is_array($candles) || empty($candles)) {
            return [
                'ok'=>false,
                'message'=>'API returned no candles. Check provider_symbol/API interval/API key.',
                'provider'=>$provider,
                'debug'=>$debug
            ];
        }

        $saved = 0;
        $skipped = 0;
        $errors = [];

        foreach ($candles as $row) {
            $openTime = $row['open_time'] ?? $row['datetime'] ?? $row['time'] ?? $row['date'] ?? '';
            $result = candle_admin_insert(
                $symbol,
                $timeframe,
                $openTime,
                $row['open'] ?? $row['open_price'] ?? '',
                $row['high'] ?? $row['high_price'] ?? '',
                $row['low'] ?? $row['low_price'] ?? '',
                $row['close'] ?? $row['close_price'] ?? '',
                $row['volume'] ?? 0
            );

            if (!empty($result['ok'])) {
                $saved++;
            } else {
                $skipped++;
                if (count($errors) < 10) {
                    $errors[] = $result['message'] ?? 'Invalid row';
                }
            }
        }

        return [
            'ok'=>true,
            'message'=>"API sync completed. Saved/updated: {$saved}. Skipped: {$skipped}.",
            'saved'=>$saved,
            'skipped'=>$skipped,
            'errors'=>$errors,
            'debug'=>$debug,
            'market_service_returned'=>count($candles),
            'warning'=>count($candles) <= 2 ? 'Only '.count($candles).' candle(s) were returned by MarketDataService/API.' : ''
        ];
    } catch (Throwable $e) {
        return ['ok'=>false,'message'=>'API sync failed: '.$e->getMessage()];
    }
}


candle_admin_ensure_tables();
$message=''; $error=''; $details=[]; $activeTab=$_GET['tab'] ?? 'sync';
$symbols=candle_admin_symbols(); $timeframes=candle_admin_timeframes();
$selectedSymbol=strtoupper(trim((string)($_GET['symbol'] ?? $_POST['symbol'] ?? ($symbols[0]['symbol'] ?? 'EURUSD'))));
$selectedTimeframe=trim((string)($_GET['timeframe'] ?? $_POST['timeframe'] ?? ($timeframes[0]['code'] ?? '1H')));
$selectedProvider=strtolower(trim((string)($_GET['provider'] ?? $_POST['provider'] ?? 'twelvedata')));
if (!in_array($selectedProvider, ['twelvedata','fmp','binance','auto'], true)) { $selectedProvider = 'twelvedata'; }

if ($_SERVER['REQUEST_METHOD']==='POST') {
    $action=$_POST['action'] ?? ''; $selectedSymbol=strtoupper(trim((string)($_POST['symbol'] ?? $selectedSymbol))); $selectedTimeframe=trim((string)($_POST['timeframe'] ?? $selectedTimeframe)); $selectedProvider=strtolower(trim((string)($_POST['provider'] ?? $selectedProvider))); if (!in_array($selectedProvider, ['twelvedata','fmp','binance','auto'], true)) { $selectedProvider='twelvedata'; }
    try {
        if ($action==='manual_add') { $activeTab='manual'; $result=candle_admin_insert($selectedSymbol,$selectedTimeframe,$_POST['open_time']??'',$_POST['open_price']??'',$_POST['high_price']??'',$_POST['low_price']??'',$_POST['close_price']??'',$_POST['volume']??0); if(!empty($result['ok'])) $message=$result['message']; else $error=$result['message']; }
        if ($action==='csv_import') { $activeTab='import'; if(empty($_FILES['csv_file']['tmp_name'])) $error='Please choose a CSV file.'; else { $result=candle_admin_import_csv($_FILES['csv_file']['tmp_name'],$selectedSymbol,$selectedTimeframe); if(!empty($result['ok'])) { $message=$result['message']; $details=$result['errors']??[]; } else $error=$result['message']; } }
        if ($action==='api_sync') { $activeTab='sync'; $result=candle_admin_api_sync($selectedSymbol,$selectedTimeframe,$_POST['limit']??300,$selectedProvider); if(!empty($result['ok'])) { $message=$result['message']; $details=$result; } else { $error=$result['message'] ?? 'API sync failed.'; $details=$result; } }
        if ($action==='cleanup_duplicates') { $activeTab='integrity'; $deleted=candle_admin_cleanup_duplicates($selectedSymbol,$selectedTimeframe); $message="Duplicate cleanup completed. Deleted {$deleted} duplicate candle(s)."; }
    } catch(Throwable $e) { $error=$e->getMessage(); }
}

$stats=candle_admin_stats($selectedSymbol,$selectedTimeframe);
$integrity=candle_admin_integrity_scan($selectedSymbol,$selectedTimeframe,500);
$recentCandles=candle_admin_fetch_recent($selectedSymbol,$selectedTimeframe,100);

admin_layout_header('Candle Management');
?>
<style>
.candle-wrap{max-width:1500px;margin:0 auto}.candle-title{font-size:36px;font-weight:900;letter-spacing:-.04em;color:#020617}.candle-sub{margin-top:6px;color:#64748b;font-size:14px}.candle-grid{display:grid;grid-template-columns:360px 1fr;gap:22px;margin-top:24px;align-items:start}.candle-card{background:#fff;border:1px solid #e2e8f0;border-radius:24px;box-shadow:0 10px 24px rgba(15,23,42,.045);overflow:hidden}.candle-head{padding:20px 22px;border-bottom:1px solid #e2e8f0;background:linear-gradient(135deg,rgba(37,99,235,.06),rgba(15,23,42,.02)),#fff}.candle-card-title{font-size:19px;font-weight:900;color:#020617}.candle-card-sub{margin-top:4px;font-size:12px;color:#64748b}.candle-body{padding:22px}.candle-label{display:block;font-size:11px;font-weight:900;letter-spacing:.06em;text-transform:uppercase;color:#64748b;margin-bottom:7px}.candle-input,.candle-select,.candle-file{width:100%;height:44px;border:1px solid #cbd5e1;border-radius:14px;padding:0 13px;font-weight:800;color:#0f172a;background:#fff}.candle-input:focus,.candle-select:focus{outline:none;border-color:#2563eb;box-shadow:0 0 0 4px rgba(37,99,235,.12)}.candle-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.candle-field{margin-bottom:15px}.candle-btn{height:44px;border:0;border-radius:14px;padding:0 18px;background:#2563eb;color:#fff;font-weight:900;cursor:pointer}.candle-btn-red{background:#dc2626}.candle-tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px}.candle-tab{display:inline-flex;align-items:center;height:40px;padding:0 14px;border-radius:999px;text-decoration:none;font-size:13px;font-weight:900;border:1px solid #e2e8f0;background:#f8fafc;color:#334155}.candle-tab.active{background:#2563eb;color:#fff;border-color:#2563eb}.candle-msg{margin-top:18px;padding:14px 16px;border-radius:16px;font-weight:800;font-size:14px}.candle-success{background:#ecfdf5;border:1px solid #a7f3d0;color:#047857}.candle-error{background:#fef2f2;border:1px solid #fecaca;color:#b91c1c}.stat-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.stat{background:#f8fafc;border:1px solid #e2e8f0;border-radius:18px;padding:14px}.stat-label{font-size:11px;font-weight:900;color:#64748b;text-transform:uppercase;letter-spacing:.06em}.stat-value{margin-top:6px;font-size:18px;font-weight:900;color:#020617}.integrity-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:16px}.integrity-box{border-radius:18px;padding:14px;border:1px solid #e2e8f0;background:#f8fafc}.integrity-box.bad{background:#fef2f2;border-color:#fecaca;color:#991b1b}.integrity-box.good{background:#ecfdf5;border-color:#a7f3d0;color:#065f46}.candle-table-wrap{overflow:auto;border:1px solid #e2e8f0;border-radius:18px}.candle-table{width:100%;border-collapse:collapse;font-size:13px}.candle-table th{background:#f8fafc;color:#475569;text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.06em;padding:12px}.candle-table td{border-top:1px solid #e2e8f0;padding:11px;color:#0f172a;font-weight:700}.help{font-size:13px;line-height:1.6;color:#475569;background:#f8fafc;border:1px solid #e2e8f0;border-radius:18px;padding:15px}@media(max-width:1100px){.candle-grid{grid-template-columns:1fr}.candle-row,.stat-grid,.integrity-grid{grid-template-columns:1fr}}
</style>
<div class="candle-wrap">
<div><div class="candle-title">Candle Management</div><div class="candle-sub">Sync, import, manually add, inspect and repair OHLC candle data used by the analysis engine.</div></div>
<?php if($message):?><div class="candle-msg candle-success"><?=e($message)?></div><?php endif;?>
<?php if($error):?><div class="candle-msg candle-error"><?=e($error)?></div><?php endif;?>
<?php if(!empty($details)):?><div class="candle-msg candle-success"><pre style="white-space:pre-wrap;margin:0;font-size:12px;"><?=e(json_encode($details, JSON_PRETTY_PRINT))?></pre></div><?php endif;?>
<div class="candle-grid"><aside class="candle-card"><div class="candle-head"><div class="candle-card-title">Market Selection</div><div class="candle-card-sub">Choose the currency/symbol and timeframe to manage.</div></div><div class="candle-body">
<form method="get"><input type="hidden" name="tab" value="<?=e($activeTab)?>"><div class="candle-field"><label class="candle-label">Symbol</label><select class="candle-select" name="symbol"><?php foreach($symbols as $s): $sym=strtoupper((string)($s['symbol']??'')); ?><option value="<?=e($sym)?>" <?=$sym===$selectedSymbol?'selected':''?>><?=e($sym.(!empty($s['name'])?' - '.$s['name']:''))?></option><?php endforeach;?></select></div><div class="candle-field"><label class="candle-label">Timeframe</label><select class="candle-select" name="timeframe"><?php foreach($timeframes as $tf): $code=(string)($tf['code']??$tf['timeframe']??''); ?><option value="<?=e($code)?>" <?=$code===$selectedTimeframe?'selected':''?>><?=e($code)?></option><?php endforeach;?></select></div><div class="candle-field"><label class="candle-label">API Provider</label><select class="candle-select" name="provider"><option value="twelvedata" <?=$selectedProvider==='twelvedata'?'selected':''?>>TwelveData</option><option value="fmp" <?=$selectedProvider==='fmp'?'selected':''?>>FMP</option><option value="binance" <?=$selectedProvider==='binance'?'selected':''?>>Binance</option><option value="auto" <?=$selectedProvider==='auto'?'selected':''?>>Auto fallback</option></select></div><button class="candle-btn" type="submit" style="width:100%;">Load Candles</button></form>
<div class="stat-grid" style="margin-top:18px;"><div class="stat"><div class="stat-label">Total</div><div class="stat-value"><?=number_format((int)($stats['total']??0))?></div></div><div class="stat"><div class="stat-label">First</div><div class="stat-value" style="font-size:12px;"><?=e($stats['first_candle']?:'N/A')?></div></div><div class="stat"><div class="stat-label">Last</div><div class="stat-value" style="font-size:12px;"><?=e($stats['last_candle']?:'N/A')?></div></div></div>
<div class="help" style="margin-top:18px;"><strong>Recommended workflow</strong><br><br>1. API Sync for production data.<br>2. CSV Import for history/backtesting.<br>3. Manual Add for BOS/CHoCH/liquidity tests.<br>4. Integrity Scan after import/sync.</div>
</div></aside><main>
<div class="candle-tabs"><?php $tabs=['sync'=>'API Sync','import'=>'CSV Import','manual'=>'Manual Add','integrity'=>'Integrity Scan','recent'=>'Recent Candles']; foreach($tabs as $key=>$label):?><a class="candle-tab <?=$activeTab===$key?'active':''?>" href="?tab=<?=e($key)?>&symbol=<?=urlencode($selectedSymbol)?>&timeframe=<?=urlencode($selectedTimeframe)?>&provider=<?=urlencode($selectedProvider)?>"><?=e($label)?></a><?php endforeach;?></div>
<?php if($activeTab==='sync'):?><section class="candle-card"><div class="candle-head"><div class="candle-card-title">API Candle Sync</div><div class="candle-card-sub">Choose TwelveData, FMP, Binance, or Auto fallback. Debug output shows provider, provider symbol, interval, returned candles and saved candles. Binance is best for crypto symbols like BTCUSD/BTCUSDT and ETHUSD/ETHUSDT.</div></div><div class="candle-body"><form method="post"><input type="hidden" name="action" value="api_sync"><input type="hidden" name="symbol" value="<?=e($selectedSymbol)?>"><input type="hidden" name="timeframe" value="<?=e($selectedTimeframe)?>"><input type="hidden" name="provider" value="<?=e($selectedProvider)?>"><div class="candle-row"><label class="candle-field"><span class="candle-label">Symbol</span><input class="candle-input" value="<?=e($selectedSymbol)?>" readonly></label><label class="candle-field"><span class="candle-label">Timeframe</span><input class="candle-input" value="<?=e($selectedTimeframe)?>" readonly></label><label class="candle-field"><span class="candle-label">API Provider</span><input class="candle-input" value="<?=e(strtoupper($selectedProvider))?>" readonly></label><label class="candle-field"><span class="candle-label">Candle Limit</span><input class="candle-input" name="limit" value="300" type="number" min="50" max="5000"></label></div><button class="candle-btn">Fetch / Sync Candles</button></form></div></section><?php endif;?>
<?php if($activeTab==='import'):?><section class="candle-card"><div class="candle-head"><div class="candle-card-title">CSV Import</div><div class="candle-card-sub">CSV headers accepted: time/open/high/low/close/volume.</div></div><div class="candle-body"><form method="post" enctype="multipart/form-data"><input type="hidden" name="action" value="csv_import"><input type="hidden" name="symbol" value="<?=e($selectedSymbol)?>"><input type="hidden" name="timeframe" value="<?=e($selectedTimeframe)?>"><input type="hidden" name="provider" value="<?=e($selectedProvider)?>"><div class="candle-field"><label class="candle-label">CSV File</label><input class="candle-file" type="file" name="csv_file" accept=".csv,text/csv" required></div><button class="candle-btn">Import CSV</button></form><div class="help" style="margin-top:18px;">Example headers:<br><code>time,open,high,low,close,volume</code></div></div></section><?php endif;?>
<?php if($activeTab==='manual'):?><section class="candle-card"><div class="candle-head"><div class="candle-card-title">Manual Candle Add</div><div class="candle-card-sub">Best for debugging a specific BOS, CHoCH or liquidity sweep condition.</div></div><div class="candle-body"><form method="post"><input type="hidden" name="action" value="manual_add"><input type="hidden" name="symbol" value="<?=e($selectedSymbol)?>"><input type="hidden" name="timeframe" value="<?=e($selectedTimeframe)?>"><input type="hidden" name="provider" value="<?=e($selectedProvider)?>"><div class="candle-row"><label class="candle-field"><span class="candle-label">Open Time</span><input class="candle-input" name="open_time" placeholder="2026-05-21 10:00:00" required></label><label class="candle-field"><span class="candle-label">Open</span><input class="candle-input" name="open_price" required></label><label class="candle-field"><span class="candle-label">High</span><input class="candle-input" name="high_price" required></label><label class="candle-field"><span class="candle-label">Low</span><input class="candle-input" name="low_price" required></label><label class="candle-field"><span class="candle-label">Close</span><input class="candle-input" name="close_price" required></label><label class="candle-field"><span class="candle-label">Volume</span><input class="candle-input" name="volume" value="0"></label></div><button class="candle-btn">Save Candle</button></form></div></section><?php endif;?>
<?php if($activeTab==='integrity'):?><section class="candle-card"><div class="candle-head"><div class="candle-card-title">Integrity Scan</div><div class="candle-card-sub">Checks recent candles for gaps, invalid OHLC and duplicates.</div></div><div class="candle-body"><div class="integrity-grid"><div class="integrity-box <?=empty($integrity['missing_gaps'])?'good':'bad'?>"><div class="stat-label">Missing Gaps</div><div class="stat-value"><?=count($integrity['missing_gaps']??[])?></div></div><div class="integrity-box <?=empty($integrity['invalid_ohlc'])?'good':'bad'?>"><div class="stat-label">Invalid OHLC</div><div class="stat-value"><?=count($integrity['invalid_ohlc']??[])?></div></div><div class="integrity-box <?=empty($integrity['duplicate_count'])?'good':'bad'?>"><div class="stat-label">Duplicates</div><div class="stat-value"><?=(int)($integrity['duplicate_count']??0)?></div></div></div><form method="post" style="margin-top:18px;"><input type="hidden" name="action" value="cleanup_duplicates"><input type="hidden" name="symbol" value="<?=e($selectedSymbol)?>"><input type="hidden" name="timeframe" value="<?=e($selectedTimeframe)?>"><input type="hidden" name="provider" value="<?=e($selectedProvider)?>"><button class="candle-btn candle-btn-red" onclick="return confirm('Delete duplicate candles for this symbol/timeframe?')">Delete Duplicates</button></form><?php if(!empty($integrity['missing_gaps'])):?><div style="margin-top:18px;" class="candle-table-wrap"><table class="candle-table"><thead><tr><th>From</th><th>To</th><th>Expected</th><th>Actual</th><th>Missing Estimate</th></tr></thead><tbody><?php foreach(array_slice($integrity['missing_gaps'],0,20) as $gap):?><tr><td><?=e($gap['from'])?></td><td><?=e($gap['to'])?></td><td><?=e($gap['expected_minutes'])?> min</td><td><?=e($gap['actual_minutes'])?> min</td><td><?=e($gap['missing_estimate'])?></td></tr><?php endforeach;?></tbody></table></div><?php endif;?></div></section><?php endif;?>
<?php if($activeTab==='recent'):?><section class="candle-card"><div class="candle-head"><div class="candle-card-title">Recent Candles</div><div class="candle-card-sub">Latest 100 candles for <?=e($selectedSymbol)?> / <?=e($selectedTimeframe)?>.</div></div><div class="candle-body"><div class="candle-table-wrap"><table class="candle-table"><thead><tr><th>Open Time</th><th>Open</th><th>High</th><th>Low</th><th>Close</th><th>Volume</th></tr></thead><tbody><?php if(!$recentCandles):?><tr><td colspan="6">No candles found for this symbol/timeframe.</td></tr><?php endif;?><?php foreach($recentCandles as $c):?><tr><td><?=e($c['open_time'])?></td><td><?=e($c['open_price'])?></td><td><?=e($c['high_price'])?></td><td><?=e($c['low_price'])?></td><td><?=e($c['close_price'])?></td><td><?=e($c['volume'])?></td></tr><?php endforeach;?></tbody></table></div></div></section><?php endif;?>
</main></div></div>
<?php admin_layout_footer(); ?>
