<?php
declare(strict_types=1);

function acfg(): array {
    static $c;
    if (!$c) $c = require __DIR__ . '/config.php';
    return $c;
}
function ah(string $s): string { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); }

function adminPasswordHash(): string {
    $c=acfg();
    $file=$c['password_file'];
    if (is_file($file)) {
        $j=json_decode((string)@file_get_contents($file), true);
        if (is_array($j) && !empty($j['password_hash'])) return (string)$j['password_hash'];
    }
    return (string)$c['default_password_hash'];
}
function saveAdminPassword(string $password): bool {
    if (strlen($password) < 8) return false;
    $j=['password_hash'=>password_hash($password,PASSWORD_DEFAULT),'updated_at'=>date('Y-m-d H:i:s')];
    return file_put_contents(acfg()['password_file'], json_encode($j,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOCK_EX)!==false;
}
function requireAdmin(): void {
    session_start();
    if (empty($_SESSION['qq_event_admin'])) {
        header('Location: login.php');
        exit;
    }
    if (empty($_SESSION['csrf'])) $_SESSION['csrf']=bin2hex(random_bytes(24));
}
function validCsrf(string $v): bool {
    return isset($_SESSION['csrf']) && hash_equals((string)$_SESSION['csrf'],$v);
}
function validDateFilename(string $name): bool {
    if (!preg_match('/^(\d{2})(\d{2})(\d{4})\.txt$/',$name,$m)) return false;
    return checkdate((int)$m[2],(int)$m[1],(int)$m[3]);
}
function cleanTextLines(string $raw): array {
    $raw=str_replace(["\r\n","\r"],"\n",$raw);
    $lines=array_map('trim',explode("\n",$raw));
    return array_values(array_filter($lines,fn($x)=>$x!==''));
}
function validateRows(string $type, array $lines): array {
    $valid=[];$invalid=[];
    foreach($lines as $i=>$line){
        if($type==='harian'){
            $valid[]=$line;
        } else {
            if(strpos($line,'=')===false){$invalid[]=['line'=>$i+1,'value'=>$line];continue;}
            [$a,$b]=array_map('trim',explode('=',$line,2));
            if($a===''||$b===''||!preg_match('/\d/',$b)){$invalid[]=['line'=>$i+1,'value'=>$line];continue;}
            $valid[]=$a.'='.$b;
        }
    }
    return [$valid,$invalid];
}
function backupTarget(array $t): ?string {
    $f=$t['winner_file'];
    if(!is_file($f)) return null;
    $dir=dirname($f);
    $backup=$dir.'/winners_'.date('Ymd_His').'.bak.txt';
    return copy($f,$backup)?$backup:null;
}
function uploadWinnerFile(string $type, array $file): array {
    $c=acfg();
    if(!isset($c['targets'][$type])) return ['ok'=>false,'msg'=>'Jenis event tidak valid.'];
    $t=$c['targets'][$type];
    if((int)($file['error']??UPLOAD_ERR_NO_FILE)!==UPLOAD_ERR_OK) return ['ok'=>false,'msg'=>'Upload file gagal.'];
    $name=basename((string)$file['name']);
    if(!validDateFilename($name)) return ['ok'=>false,'msg'=>'Nama file wajib format ddmmyyyy.txt, contoh 11082026.txt.'];
    $tmp=(string)$file['tmp_name'];
    if(!is_uploaded_file($tmp)) return ['ok'=>false,'msg'=>'File upload tidak valid.'];
    $raw=(string)file_get_contents($tmp);
    $lines=cleanTextLines($raw);
    [$valid,$invalid]=validateRows($type,$lines);
    if(!$valid) return ['ok'=>false,'msg'=>'Tidak ada data valid di file.'];
    if($invalid) return ['ok'=>false,'msg'=>'Ada '.count($invalid).' baris dengan format salah. Perbaiki sebelum upload.','invalid'=>$invalid];

    $dest=$t['winner_file'];
    $dir=dirname($dest);
    if(!is_dir($dir) && !mkdir($dir,0775,true)) return ['ok'=>false,'msg'=>'Folder tujuan tidak dapat dibuat.'];
    if(!is_writable($dir)) return ['ok'=>false,'msg'=>'Folder tujuan tidak writable: '.$dir];

    backupTarget($t);
    $content=implode(PHP_EOL,$valid).PHP_EOL;
    $tmpOut=$dest.'.tmp';
    if(file_put_contents($tmpOut,$content,LOCK_EX)===false) return ['ok'=>false,'msg'=>'Gagal menulis file sementara.'];
    if(!rename($tmpOut,$dest)){@unlink($tmpOut);return ['ok'=>false,'msg'=>'Gagal mengganti winners.txt.'];}
    @chmod($dest,0664);

    if(!empty($t['date_file'])) {
        file_put_contents($t['date_file'],$name,LOCK_EX);
        @chmod($t['date_file'],0664);
    }

    return ['ok'=>true,'msg'=>$t['label'].' berhasil diperbarui.','rows'=>count($valid),'filename'=>$name];
}
function targetStats(string $type): array {
    $t=acfg()['targets'][$type];
    $rows=0;
    if(is_readable($t['winner_file'])) $rows=count(file($t['winner_file'],FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES)?:[]);
    $date='';
    if(!empty($t['date_file'])&&is_readable($t['date_file'])) $date=trim((string)file_get_contents($t['date_file']));
    return ['rows'=>$rows,'date'=>$date,'modified'=>is_file($t['winner_file'])?date('Y-m-d H:i:s',filemtime($t['winner_file'])):'-'];
}
