<?php
/**
 * WinRacing V44.0 — Chairman Ranking Optimizer + Production Integration Engine
 * -----------------------------------------------------------------------------
 * Base Source: V43.0 Chairman Integration Engine.
 * Standalone PHP 7.4+ / MySQLi / Bootstrap-style Dark UI.
 * Does NOT modify analysis.php, main program, V43/V42/V41/V40 tables, or old engines.
 * Adds V44-only tables.
 * Purpose:
 *   Convert V43 Chairman Integration Score into production-ready race ranking.
 *   Optimizes ranking, calibrates confidence, creates race strength index,
 *   top pick / Q / Trio / Six-up style outputs, and an analysis.php-ready API table.
 */
@set_time_limit(1200);
@ini_set('memory_limit','1536M');
require_once __DIR__ . '/config/config.php';
if (!isset($conn) && isset($db)) { $conn = $db; }
if (!isset($conn) || !($conn instanceof mysqli)) { die('DB connection not found. Need config/config.php with $conn or $db.'); }
$conn->set_charset('utf8mb4');

function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
function q($db,$s){ return "'".$db->real_escape_string((string)$s)."'"; }
function n($v,$d=0){ return is_numeric($v) ? (float)$v : $d; }
function i($v,$d=0){ return is_numeric($v) ? (int)$v : $d; }
function pct($v){ return number_format((float)$v,2).'%'; }
function clampv($v,$min,$max){ return max($min,min($max,$v)); }
function table_exists($db,$t){ $r=@$db->query('SHOW TABLES LIKE '.q($db,$t)); return $r && $r->num_rows>0; }
function rows($db,$sql){ $a=array(); $r=@$db->query($sql); if($r){ while($x=$r->fetch_assoc()) $a[]=$x; } return $a; }
function scalar($db,$sql,$d=0){ $r=@$db->query($sql); if($r && ($x=$r->fetch_row())) return $x[0]; return $d; }
function run_key(){ return date('YmdHis').'_'.mt_rand(1000,9999); }
function grade_from_score($s){ $s=n($s); if($s>=92)return 'S+'; if($s>=84)return 'S'; if($s>=76)return 'A'; if($s>=66)return 'B'; if($s>=54)return 'C'; if($s>=40)return 'D'; return 'E'; }
function badge($d){ return strtolower(in_array($d,array('BUY','COVER','WATCH','SKIP'),true)?$d:'watch'); }
function decision_from_prod($s,$risk){ $s=n($s); $risk=n($risk); if($s>=86 && $risk<50)return 'BUY'; if($s>=70)return 'COVER'; if($s>=50)return 'WATCH'; return 'SKIP'; }
function role_from_rank($rank,$score,$gap,$risk){ if($rank==1 && $score>=70 && $risk<58) return '主席膽'; if($rank<=2 && $score>=62) return 'Q膽'; if($rank<=4 && $score>=52) return '主力腳'; if($rank<=6 && $gap<=16) return '冷門腳'; return '觀察'; }
function state_v44($s,$stability,$risk){ if($s>=88&&$stability>=70&&$risk<45)return 'PRODUCTION_CORE'; if($s>=76)return 'PRODUCTION_STRONG'; if($s>=64)return 'PRODUCTION_LIVE'; if($s>=52)return 'PRODUCTION_WATCH'; if($risk>=70)return 'PRODUCTION_RISK'; return 'PRODUCTION_WEAK'; }
function ins44($db,$table,$arr,$update=array()){
    $cols=array_keys($arr); $vals=array();
    foreach($cols as $c){ $vals[] = is_numeric($arr[$c]) ? $arr[$c] : q($db,$arr[$c]); }
    $sql='INSERT INTO '.$table.' ('.implode(',',$cols).') VALUES ('.implode(',',$vals).')';
    if($update){ $u=array(); foreach($update as $c){ $u[]=$c.'=VALUES('.$c.')'; } $sql.=' ON DUPLICATE KEY UPDATE '.implode(',',$u); }
    return @$db->query($sql);
}
function latest_race_date($db){
    if(table_exists($db,'wr_chairman_integration_score_v43')) return (string)scalar($db,"SELECT MAX(race_date) FROM wr_chairman_integration_score_v43",date('Y-m-d'));
    if(table_exists($db,'wr_chairman_horse_profile_v42')) return (string)scalar($db,"SELECT MAX(race_date) FROM wr_chairman_horse_profile_v42",date('Y-m-d'));
    return date('Y-m-d');
}
function ensure_v44($db){
    $tables=array();
    $tables[]="CREATE TABLE IF NOT EXISTS wr_chairman_production_score_v44 (
        id INT AUTO_INCREMENT PRIMARY KEY, production_key VARCHAR(700) NOT NULL, run_key VARCHAR(80) NOT NULL,
        race_date DATE NULL, venue VARCHAR(80) NOT NULL DEFAULT '', race_num INT NOT NULL DEFAULT 0, horse_num VARCHAR(20) NOT NULL DEFAULT '', horse_name VARCHAR(180) NOT NULL DEFAULT '',
        v43_score DECIMAL(10,4) NOT NULL DEFAULT 0, optimized_score DECIMAL(10,4) NOT NULL DEFAULT 0, calibrated_score DECIMAL(10,4) NOT NULL DEFAULT 0,
        win_score DECIMAL(10,4) NOT NULL DEFAULT 0, place_score DECIMAL(10,4) NOT NULL DEFAULT 0, q_score DECIMAL(10,4) NOT NULL DEFAULT 0, trio_score DECIMAL(10,4) NOT NULL DEFAULT 0,
        risk_score DECIMAL(10,4) NOT NULL DEFAULT 0, confidence_score DECIMAL(10,4) NOT NULL DEFAULT 0, stability_score DECIMAL(10,4) NOT NULL DEFAULT 0,
        race_rank INT NOT NULL DEFAULT 0, role_tag VARCHAR(80) NOT NULL DEFAULT 'WATCH', final_decision VARCHAR(30) NOT NULL DEFAULT 'WATCH', production_grade VARCHAR(30) NOT NULL DEFAULT 'C', production_state VARCHAR(80) NOT NULL DEFAULT 'PRODUCTION_WATCH',
        score_gap DECIMAL(10,4) NOT NULL DEFAULT 0, top_probability DECIMAL(10,4) NOT NULL DEFAULT 0, api_payload LONGTEXT NULL, reason_zh TEXT NULL, trace TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uk_v44_prod(production_key), KEY idx_v44_prod_run(run_key), KEY idx_v44_prod_race(race_date,venue,race_num), KEY idx_v44_prod_rank(race_rank), KEY idx_v44_prod_score(calibrated_score)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
    $tables[]="CREATE TABLE IF NOT EXISTS wr_chairman_race_optimizer_v44 (
        id INT AUTO_INCREMENT PRIMARY KEY, optimizer_key VARCHAR(700) NOT NULL, run_key VARCHAR(80) NOT NULL,
        race_date DATE NULL, venue VARCHAR(80) NOT NULL DEFAULT '', race_num INT NOT NULL DEFAULT 0,
        horse_count INT NOT NULL DEFAULT 0, race_strength DECIMAL(10,4) NOT NULL DEFAULT 0, race_stability DECIMAL(10,4) NOT NULL DEFAULT 0, race_entropy DECIMAL(10,4) NOT NULL DEFAULT 0,
        top_horse VARCHAR(20) NOT NULL DEFAULT '', top_score DECIMAL(10,4) NOT NULL DEFAULT 0, second_horse VARCHAR(20) NOT NULL DEFAULT '', second_score DECIMAL(10,4) NOT NULL DEFAULT 0,
        gap12 DECIMAL(10,4) NOT NULL DEFAULT 0, gap14 DECIMAL(10,4) NOT NULL DEFAULT 0, race_mode VARCHAR(80) NOT NULL DEFAULT 'BALANCED', race_hint VARCHAR(120) NOT NULL DEFAULT 'RACE_REVIEW',
        q_suggestion VARCHAR(180) NOT NULL DEFAULT '', trio_suggestion VARCHAR(260) NOT NULL DEFAULT '', sixup_suggestion VARCHAR(260) NOT NULL DEFAULT '', avoid_suggestion VARCHAR(260) NOT NULL DEFAULT '',
        json_payload LONGTEXT NULL, reason_zh TEXT NULL, trace TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uk_v44_optimizer(optimizer_key), KEY idx_v44_optimizer_run(run_key), KEY idx_v44_optimizer_race(race_date,venue,race_num)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
    $tables[]="CREATE TABLE IF NOT EXISTS wr_chairman_analysis_api_v44 (
        id INT AUTO_INCREMENT PRIMARY KEY, api_key VARCHAR(700) NOT NULL, run_key VARCHAR(80) NOT NULL,
        race_date DATE NULL, venue VARCHAR(80) NOT NULL DEFAULT '', race_num INT NOT NULL DEFAULT 0, api_type VARCHAR(80) NOT NULL DEFAULT 'ANALYSIS_PHP_READY',
        json_payload LONGTEXT NULL, php_hint LONGTEXT NULL, reason_zh TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uk_v44_api(api_key), KEY idx_v44_api_run(run_key), KEY idx_v44_api_race(race_date,venue,race_num)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
    $tables[]="CREATE TABLE IF NOT EXISTS wr_chairman_parameter_learning_v44 (
        id INT AUTO_INCREMENT PRIMARY KEY, param_key VARCHAR(700) NOT NULL, run_key VARCHAR(80) NOT NULL,
        parameter_name VARCHAR(120) NOT NULL DEFAULT '', old_weight DECIMAL(10,4) NOT NULL DEFAULT 0, suggested_weight DECIMAL(10,4) NOT NULL DEFAULT 0, learning_delta DECIMAL(10,4) NOT NULL DEFAULT 0,
        sample_rows INT NOT NULL DEFAULT 0, confidence_score DECIMAL(10,4) NOT NULL DEFAULT 0, reason_zh TEXT NULL, trace TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uk_v44_param(param_key), KEY idx_v44_param_run(run_key), KEY idx_v44_param_name(parameter_name)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
    $tables[]="CREATE TABLE IF NOT EXISTS wr_chairman_production_run_log_v44 (
        id INT AUTO_INCREMENT PRIMARY KEY, run_key VARCHAR(80) NOT NULL, race_date DATE NULL, venue VARCHAR(80) NOT NULL DEFAULT '', context_mode VARCHAR(40) NOT NULL DEFAULT 'BALANCED', status VARCHAR(30) NOT NULL DEFAULT 'START',
        source_rows INT NOT NULL DEFAULT 0, production_rows INT NOT NULL DEFAULT 0, optimizer_rows INT NOT NULL DEFAULT 0, api_rows INT NOT NULL DEFAULT 0, param_rows INT NOT NULL DEFAULT 0,
        top_horse VARCHAR(40) NOT NULL DEFAULT '', top_score DECIMAL(10,4) NOT NULL DEFAULT 0, message TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        KEY idx_v44_log_run(run_key), KEY idx_v44_log_date(race_date,venue)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
    foreach($tables as $sql){ $db->query($sql); }
}
ensure_v44($conn);

function source_v44($db,$raceDate,$venue,$raceNum){
    $where=array(); if($raceDate) $where[]='race_date='.q($db,$raceDate); if($venue!=='') $where[]='venue='.q($db,$venue); if(i($raceNum)>0) $where[]='race_num='.i($raceNum);
    if(table_exists($db,'wr_chairman_integration_score_v43')){
        $sql='SELECT * FROM wr_chairman_integration_score_v43'.($where?' WHERE '.implode(' AND ',$where):'').' ORDER BY race_date, venue, race_num, race_rank, calibrated_score DESC, production_score DESC LIMIT 1500';
        $r=rows($db,$sql); if($r) return $r;
    }
    if(table_exists($db,'wr_chairman_horse_decision_v42')){
        $sql='SELECT race_date,venue,race_num,horse_num,horse_name,horse_score AS production_score,horse_score AS base_horse_score,chairman_alignment AS chairman_score,win_score,place_score,q_score,trio_score,risk_score,confidence_score,final_decision,0 AS race_rank,"WATCH" AS role_tag,"V42_FALLBACK" AS integration_state FROM wr_chairman_horse_decision_v42'.($where?' WHERE '.implode(' AND ',$where):'').' ORDER BY race_date, venue, race_num, horse_score DESC LIMIT 1500';
        return rows($db,$sql);
    }
    return array();
}
function optimize_v44($source,$run,$mode){
    $by=array(); foreach($source as $r){ $g=$r['race_date'].'|'.$r['venue'].'|'.$r['race_num']; if(!isset($by[$g])) $by[$g]=array(); $by[$g][]=$r; }
    $prod=array(); $opt=array(); $apis=array();
    foreach($by as $g=>$arr){
        $scores=array(); foreach($arr as $r){ $scores[]=n(isset($r['production_score'])?$r['production_score']:0); }
        $avg=count($scores)?array_sum($scores)/count($scores):0; $max=count($scores)?max($scores):0; $min=count($scores)?min($scores):0; $entropy=clampv(100-($max-$avg)*1.25,0,100); $strength=clampv($avg*0.38+$max*0.42+(100-$entropy)*0.20,0,100);
        $tmp=array();
        foreach($arr as $r){
            $v43=n(isset($r['production_score'])?$r['production_score']:(isset($r['horse_score'])?$r['horse_score']:0));
            $win=n(isset($r['win_score'])?$r['win_score']:0); $place=n(isset($r['place_score'])?$r['place_score']:0); $q=n(isset($r['q_score'])?$r['q_score']:0); $trio=n(isset($r['trio_score'])?$r['trio_score']:0);
            $risk=n(isset($r['risk_score'])?$r['risk_score']:0); $conf=n(isset($r['confidence_score'])?$r['confidence_score']:50); $chair=n(isset($r['chairman_score'])?$r['chairman_score']:50);
            $marketBalance=clampv(($win*0.25+$place*0.25+$q*0.25+$trio*0.25),0,100);
            $modeAdj=0; if($mode==='AGGRESSIVE') $modeAdj=($win-$risk)*0.04; elseif($mode==='CONSERVATIVE') $modeAdj=($place+$q-$risk)*0.035; elseif($mode==='DEFENSIVE') $modeAdj=(100-$risk)*0.05;
            $optimized=clampv($v43*0.42+$marketBalance*0.20+$chair*0.16+$conf*0.12+(100-$risk)*0.10+$modeAdj,0,100);
            $stability=clampv($conf*0.38+(100-$risk)*0.30+$place*0.16+$q*0.16,0,100);
            $calibrated=clampv($optimized*0.72+$stability*0.18+($strength-$entropy)*0.04,0,100);
            $tmp[]=array('src'=>$r,'v43'=>$v43,'optimized'=>$optimized,'calibrated'=>$calibrated,'stability'=>$stability,'risk'=>$risk,'conf'=>$conf,'win'=>$win,'place'=>$place,'q'=>$q,'trio'=>$trio,'chair'=>$chair);
        }
        usort($tmp,function($a,$b){ if($a['calibrated']==$b['calibrated']) return 0; return $a['calibrated']<$b['calibrated']?1:-1; });
        $top=count($tmp)?$tmp[0]['calibrated']:0; $second=count($tmp)>1?$tmp[1]['calibrated']:0; $fourth=count($tmp)>3?$tmp[3]['calibrated']:$second; $total=0; foreach($tmp as $x){ $total+=max(1,$x['calibrated']); }
        $rank=1; $apiHorses=array(); $qPick=array(); $trioPick=array(); $sixPick=array(); $avoid=array();
        foreach($tmp as $x){
            $r=$x['src']; $gap=$top-$x['calibrated']; $role=role_from_rank($rank,$x['calibrated'],$gap,$x['risk']); $decision=decision_from_prod($x['calibrated'],$x['risk']); $grade=grade_from_score($x['calibrated']); $state=state_v44($x['calibrated'],$x['stability'],$x['risk']); $prob=$total>0?clampv($x['calibrated']/$total*100,0,100):0;
            if($rank<=2) $qPick[]=$r['horse_num']; if($rank<=4) $trioPick[]=$r['horse_num']; if($rank<=2) $sixPick[]=$r['horse_num']; if($x['risk']>=68 || $decision==='SKIP') $avoid[]=$r['horse_num'];
            $payload=array('race_date'=>$r['race_date'],'venue'=>$r['venue'],'race_num'=>i($r['race_num']),'horse_num'=>$r['horse_num'],'horse_name'=>$r['horse_name'],'chairman_final_score'=>round($x['calibrated'],2),'rank'=>$rank,'role'=>$role,'decision'=>$decision,'grade'=>$grade,'state'=>$state,'risk'=>round($x['risk'],2),'confidence'=>round($x['conf'],2),'win'=>round($x['win'],2),'place'=>round($x['place'],2),'q'=>round($x['q'],2),'trio'=>round($x['trio'],2));
            $prod[]=array('production_key'=>sha1($run.'|PROD|'.$r['race_date'].'|'.$r['venue'].'|'.$r['race_num'].'|'.$r['horse_num']),'run_key'=>$run,'race_date'=>$r['race_date'],'venue'=>$r['venue'],'race_num'=>i($r['race_num']),'horse_num'=>(string)$r['horse_num'],'horse_name'=>(string)$r['horse_name'],'v43_score'=>$x['v43'],'optimized_score'=>$x['optimized'],'calibrated_score'=>$x['calibrated'],'win_score'=>$x['win'],'place_score'=>$x['place'],'q_score'=>$x['q'],'trio_score'=>$x['trio'],'risk_score'=>$x['risk'],'confidence_score'=>$x['conf'],'stability_score'=>$x['stability'],'race_rank'=>$rank,'role_tag'=>$role,'final_decision'=>$decision,'production_grade'=>$grade,'production_state'=>$state,'score_gap'=>$gap,'top_probability'=>$prob,'api_payload'=>json_encode($payload,JSON_UNESCAPED_UNICODE),'reason_zh'=>'V44 Production Optimizer：#'.$r['horse_num'].' '.$r['horse_name'].' Rank #'.$rank.'，Final='.number_format($x['calibrated'],1).'，V43='.number_format($x['v43'],1).'，Stability='.number_format($x['stability'],1).'，Gap='.number_format($gap,1).'。','trace'=>'V44_PRODUCTION|R'.$r['race_num'].'|H'.$r['horse_num'].'|rank='.$rank.'|score='.number_format($x['calibrated'],2));
            $apiHorses[]=$payload; $rank++;
        }
        list($rd,$ve,$rn)=explode('|',$g); $raceMode=$entropy>=72?'混戰場':(($top-$second)>=10?'主席膽場':'主力腳場'); $hint=$raceMode==='主席膽場'?'TOP_PICK_ALLOWED':($raceMode==='主力腳場'?'Q_TRIO_PRIORITY':'WIDE_COVER_REQUIRED');
        $json=array('run_key'=>$run,'race_date'=>$rd,'venue'=>$ve,'race_num'=>i($rn),'race_mode'=>$raceMode,'race_hint'=>$hint,'top_horse'=>isset($tmp[0])?$tmp[0]['src']['horse_num']:'','gap12'=>$top-$second,'horses'=>$apiHorses,'q_suggestion'=>$qPick,'trio_suggestion'=>$trioPick,'sixup_suggestion'=>$sixPick,'avoid'=>$avoid);
        $opt[]=array('optimizer_key'=>sha1($run.'|OPT|'.$g),'run_key'=>$run,'race_date'=>$rd,'venue'=>$ve,'race_num'=>i($rn),'horse_count'=>count($tmp),'race_strength'=>$strength,'race_stability'=>clampv(100-$entropy+($top-$second)*2,0,100),'race_entropy'=>$entropy,'top_horse'=>isset($tmp[0])?$tmp[0]['src']['horse_num']:'','top_score'=>$top,'second_horse'=>isset($tmp[1])?$tmp[1]['src']['horse_num']:'','second_score'=>$second,'gap12'=>$top-$second,'gap14'=>$top-$fourth,'race_mode'=>$raceMode,'race_hint'=>$hint,'q_suggestion'=>implode(',',$qPick),'trio_suggestion'=>implode(',',$trioPick),'sixup_suggestion'=>implode(',',$sixPick),'avoid_suggestion'=>implode(',',$avoid),'json_payload'=>json_encode($json,JSON_UNESCAPED_UNICODE),'reason_zh'=>'V44 Race Optimizer：R'.$rn.' '.$raceMode.'，Top='.($json['top_horse']).'，Gap12='.number_format($top-$second,1).'，Q='.implode(',',$qPick).'，Trio='.implode(',',$trioPick).'。','trace'=>'V44_RACE_OPT|R'.$rn.'|'.$hint);
        $phpHint="// V44 analysis.php integration hint\n// SELECT * FROM wr_chairman_production_score_v44 WHERE race_date=? AND venue=? AND race_num=? ORDER BY race_rank\n// Use calibrated_score as Chairman Final Score. Use role_tag for 主席膽/Q膽/主力腳.\n";
        $apis[]=array('api_key'=>sha1($run.'|API|'.$g),'run_key'=>$run,'race_date'=>$rd,'venue'=>$ve,'race_num'=>i($rn),'api_type'=>'ANALYSIS_PHP_READY','json_payload'=>json_encode($json,JSON_UNESCAPED_UNICODE),'php_hint'=>$phpHint,'reason_zh'=>'V44 API：analysis.php 可直接讀取主席最終分、排名、Q/Trio/Six-up 建議。');
    }
    return array($prod,$opt,$apis);
}
function build_params_v44($prod,$run){
    $weights=array('V43_SCORE_WEIGHT'=>0.42,'MARKET_BALANCE_WEIGHT'=>0.20,'CHAIRMAN_WEIGHT'=>0.16,'CONFIDENCE_WEIGHT'=>0.12,'RISK_CONTROL_WEIGHT'=>0.10);
    $avgRisk=0;$avgConf=0;$n=max(1,count($prod)); foreach($prod as $p){$avgRisk+=n($p['risk_score']);$avgConf+=n($p['confidence_score']);} $avgRisk/=$n; $avgConf/=$n;
    $out=array(); foreach($weights as $name=>$old){ $delta=0; if($name==='RISK_CONTROL_WEIGHT' && $avgRisk>55) $delta=0.03; if($name==='CONFIDENCE_WEIGHT' && $avgConf>65) $delta=0.02; if($name==='MARKET_BALANCE_WEIGHT' && $avgRisk>65) $delta=-0.02; $new=clampv($old+$delta,0.05,0.60); $out[]=array('param_key'=>sha1($run.'|PARAM|'.$name),'run_key'=>$run,'parameter_name'=>$name,'old_weight'=>$old,'suggested_weight'=>$new,'learning_delta'=>$new-$old,'sample_rows'=>count($prod),'confidence_score'=>clampv($avgConf,0,100),'reason_zh'=>'V44 Parameter Learning：'.$name.' old='.number_format($old,2).' → suggested='.number_format($new,2).'，AvgRisk='.number_format($avgRisk,1).'，AvgConf='.number_format($avgConf,1).'。','trace'=>'V44_PARAM|'.$name); }
    return $out;
}
function save_v44($db,$run,$raceDate,$venue,$mode,$source,$prod,$opt,$apis,$params){
    $db->begin_transaction(); $c=array('prod'=>0,'opt'=>0,'api'=>0,'param'=>0);
    foreach($prod as $r){ if(ins44($db,'wr_chairman_production_score_v44',$r,array('v43_score','optimized_score','calibrated_score','win_score','place_score','q_score','trio_score','risk_score','confidence_score','stability_score','race_rank','role_tag','final_decision','production_grade','production_state','score_gap','top_probability','api_payload','reason_zh','trace'))) $c['prod']++; }
    foreach($opt as $r){ if(ins44($db,'wr_chairman_race_optimizer_v44',$r,array('horse_count','race_strength','race_stability','race_entropy','top_horse','top_score','second_horse','second_score','gap12','gap14','race_mode','race_hint','q_suggestion','trio_suggestion','sixup_suggestion','avoid_suggestion','json_payload','reason_zh','trace'))) $c['opt']++; }
    foreach($apis as $r){ if(ins44($db,'wr_chairman_analysis_api_v44',$r,array('json_payload','php_hint','reason_zh'))) $c['api']++; }
    foreach($params as $r){ if(ins44($db,'wr_chairman_parameter_learning_v44',$r,array('old_weight','suggested_weight','learning_delta','sample_rows','confidence_score','reason_zh','trace'))) $c['param']++; }
    $top='';$score=0;if($prod){$top=$prod[0]['horse_num'];$score=n($prod[0]['calibrated_score']);}
    $msg='Built V44 Production Optimizer: production '.$c['prod'].' | races '.$c['opt'].' | api '.$c['api'].' | params '.$c['param'].' | top '.$top.' score '.number_format($score,1);
    $db->query("INSERT INTO wr_chairman_production_run_log_v44 (run_key,race_date,venue,context_mode,status,source_rows,production_rows,optimizer_rows,api_rows,param_rows,top_horse,top_score,message) VALUES (".q($db,$run).",".q($db,$raceDate).",".q($db,$venue).",".q($db,$mode).",'DONE',".count($source).",".$c['prod'].",".$c['opt'].",".$c['api'].",".$c['param'].",".q($db,$top).",".n($score).",".q($db,$msg).")");
    $db->commit(); return array($c,$msg);
}

$raceDate=isset($_GET['race_date'])?$_GET['race_date']:latest_race_date($conn);
$venue=isset($_GET['venue'])?$_GET['venue']:'';
$raceNum=isset($_GET['race_num'])?i($_GET['race_num']):0;
$mode=strtoupper(isset($_GET['mode'])?$_GET['mode']:'BALANCED');
$action=isset($_GET['action'])?$_GET['action']:'preview';
$errors=array(); if(!table_exists($conn,'wr_chairman_integration_score_v43') && !table_exists($conn,'wr_chairman_horse_decision_v42')) $errors[]='Missing source: build V43 Integration or V42 Horse Decision first.';
$started=microtime(true); $run='PREVIEW_'.run_key(); $source=array(); $prod=array(); $opt=array(); $apis=array(); $params=array(); $msg='';
if(!$errors){ $source=source_v44($conn,$raceDate,$venue,$raceNum); if(!$source) $errors[]='No V43/V42 source rows found for selected date / venue / race.'; }
if(!$errors){ list($prod,$opt,$apis)=optimize_v44($source,$run,$mode); $params=build_params_v44($prod,$run); if($action==='build'){ $run=run_key(); list($prod,$opt,$apis)=optimize_v44($source,$run,$mode); $params=build_params_v44($prod,$run); list($saveCounts,$msg)=save_v44($conn,$run,$raceDate,$venue,$mode,$source,$prod,$opt,$apis,$params); } }
$elapsed=round(microtime(true)-$started,3);
$prodRows=rows($conn,"SELECT * FROM wr_chairman_production_score_v44 ORDER BY race_date DESC, venue, race_num, race_rank LIMIT 240");
$optRows=rows($conn,"SELECT * FROM wr_chairman_race_optimizer_v44 ORDER BY race_date DESC, venue, race_num LIMIT 80");
$apiRows=rows($conn,"SELECT * FROM wr_chairman_analysis_api_v44 ORDER BY id DESC LIMIT 40");
$paramRows=rows($conn,"SELECT * FROM wr_chairman_parameter_learning_v44 ORDER BY id DESC LIMIT 40");
$logRows=rows($conn,"SELECT * FROM wr_chairman_production_run_log_v44 ORDER BY id DESC LIMIT 40");
$totalProd=scalar($conn,"SELECT COUNT(*) FROM wr_chairman_production_score_v44",0); $totalRaces=scalar($conn,"SELECT COUNT(*) FROM wr_chairman_race_optimizer_v44",0); $latestTop=scalar($conn,"SELECT top_horse FROM wr_chairman_production_run_log_v44 ORDER BY id DESC LIMIT 1",''); $avgScore=scalar($conn,"SELECT AVG(calibrated_score) FROM wr_chairman_production_score_v44",0);
?>
<!doctype html><html lang="zh-Hant"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>WinRacing V44 Chairman Ranking Optimizer</title><style>
body{margin:0;background:#050914;color:#e7fbff;font-family:Arial,'Microsoft JhengHei',sans-serif;font-size:13px}.wrap{padding:22px;max-width:1760px;margin:auto}.hero{border:1px solid #31486b;border-radius:18px;background:radial-gradient(circle at top left,#3b2807,#0b1325 45%,#050914);padding:22px 28px;margin-bottom:16px}.k{color:#7fd3ff;text-transform:uppercase;letter-spacing:2px;font-size:11px;font-weight:900}.title{font-size:31px;font-weight:900}.title span{color:#ffc107}.sub{color:#9ed9ff}.pill{display:inline-block;border-radius:6px;padding:5px 9px;font-weight:900;font-size:12px;background:#11233c;border:1px solid #34506d;margin:2px}.panel{border:1px solid #283c59;border-radius:14px;background:#0c1423;margin-bottom:18px;overflow:hidden}.panel h3{margin:0;padding:14px 16px;border-bottom:1px solid #283c59}.body{padding:14px 16px}.grid{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:18px}.stat{background:#101a2c;border:1px solid #283c59;border-radius:12px;padding:16px}.stat small{display:block;color:#83cfff;text-transform:uppercase;font-size:10px}.stat b{font-size:25px;display:block;margin-top:8px}.form{display:grid;grid-template-columns:1fr .8fr .5fr .8fr auto auto;gap:10px;align-items:end}.inp{width:100%;box-sizing:border-box;background:#091222;color:#fff;border:1px solid #314966;border-radius:5px;padding:9px}.btn{background:#ffc107;color:#111;border:0;border-radius:6px;padding:10px 14px;font-weight:900;text-decoration:none}.btn2{background:#1f6feb;color:#fff}.ok{border:1px solid #18b26b;background:#07321f;color:#c9ffe8;border-radius:10px;padding:12px 14px;margin:10px 0}.warn{border:1px solid #ff3860;background:#30111a;color:#ffd5df;border-radius:10px;padding:12px 14px;margin:10px 0}.note{color:#92d7ff;font-size:12px;margin-top:10px;border-top:1px solid #283c59;padding-top:10px}.split{display:grid;grid-template-columns:1fr 1fr;gap:16px}.scroll{overflow:auto;max-height:640px}table{width:100%;border-collapse:collapse}th,td{border-bottom:1px solid #243650;padding:8px;vertical-align:top;font-size:12px}th{background:#101a2c;color:#d7ecff;text-transform:uppercase;font-size:11px;position:sticky;top:0}.badge{border-radius:999px;padding:4px 9px;font-weight:900;font-size:11px;display:inline-block}.b-buy{background:#18b26b;color:#001b12}.b-cover{background:#2dd4bf;color:#001b12}.b-watch{background:#ffc107;color:#111}.b-skip{background:#ff3860;color:#fff}.pos{color:#32ffa7;font-weight:900}.neg{color:#ff5a86;font-weight:900}.gold{color:#ffc107}.small{color:#9ed9ff;font-size:12px}.layer{font-weight:900;color:#b6e6ff}@media(max-width:1100px){.grid,.form,.split{grid-template-columns:1fr}}
</style></head><body><div class="wrap"><div class="hero"><div style="display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap"><div><div class="k">WinRacing Chairman AI</div><div class="title">🏆 V44.0 — Chairman <span>Ranking Optimizer</span> Ultimate</div><div class="sub">V43 Integration → Production Score → Race Optimizer → Q/Trio/Six-up → analysis.php Ready API。</div></div><div><span class="pill">PHP 7.4 Compatible</span><span class="pill">V43 Source</span><span class="pill">不改 analysis.php</span><span class="pill">Production Integration</span></div></div></div><?php foreach($errors as $e):?><div class="warn">✖ <?=h($e)?></div><?php endforeach;?><?php if($msg):?><div class="ok">✅ <?=h($msg)?></div><?php endif;?>
<div class="grid"><div class="stat"><small>Production Rows</small><b class="gold"><?=h($totalProd)?></b></div><div class="stat"><small>Optimized Races</small><b><?=h($totalRaces)?></b></div><div class="stat"><small>Preview Source</small><b><?=h(count($source))?></b></div><div class="stat"><small>Preview Output</small><b><?=h(count($prod))?></b></div><div class="stat"><small>Latest Top Horse</small><b class="gold"><?=h($latestTop?:'N/A')?></b></div><div class="stat"><small>Avg Final Score</small><b><?=h(number_format(n($avgScore),1))?></b></div></div>
<div class="panel"><h3>⚙️ Build V44 Production Ranking</h3><div class="body"><form class="form" method="get"><div><label>Race Date</label><input class="inp" type="date" name="race_date" value="<?=h($raceDate)?>"></div><div><label>Venue</label><input class="inp" name="venue" value="<?=h($venue)?>" placeholder="optional"></div><div><label>Race #</label><input class="inp" type="number" name="race_num" value="<?=h($raceNum)?>"></div><div><label>Mode</label><select class="inp" name="mode"><option <?=$mode==='BALANCED'?'selected':''?>>BALANCED</option><option <?=$mode==='AGGRESSIVE'?'selected':''?>>AGGRESSIVE</option><option <?=$mode==='CONSERVATIVE'?'selected':''?>>CONSERVATIVE</option><option <?=$mode==='DEFENSIVE'?'selected':''?>>DEFENSIVE</option></select></div><button class="btn" name="action" value="build">Build V44.0</button><a class="btn btn2" href="?">Refresh</a></form><div class="note">Preview Run <?=h($run)?>；Elapsed <?=h($elapsed)?>s；V44 reads V43 integration_score, fallback to V42 horse_decision。</div></div></div>
<div class="panel"><h3>🚀 V44 Production Ranking — analysis.php Ready</h3><div class="scroll"><table><tr><th>Date</th><th>Venue</th><th>Race</th><th>Rank</th><th>Horse</th><th>Name</th><th>Role</th><th>Decision</th><th>Final</th><th>V43</th><th>Opt</th><th>Win</th><th>Place</th><th>Q</th><th>Trio</th><th>Risk</th><th>Conf</th><th>Stable</th><th>Gap</th><th>State</th><th>Reason</th></tr><?php foreach($prodRows as $r):?><tr><td><?=h($r['race_date'])?></td><td><?=h($r['venue'])?></td><td>R<?=h($r['race_num'])?></td><td class="gold">#<?=h($r['race_rank'])?></td><td class="gold"><?=h($r['horse_num'])?></td><td><?=h($r['horse_name'])?></td><td><?=h($r['role_tag'])?></td><td><span class="badge b-<?=badge($r['final_decision'])?>"><?=h($r['final_decision'])?></span></td><td class="gold"><?=h(number_format(n($r['calibrated_score']),1))?></td><td><?=h(number_format(n($r['v43_score']),1))?></td><td><?=h(number_format(n($r['optimized_score']),1))?></td><td><?=h(number_format(n($r['win_score']),1))?></td><td><?=h(number_format(n($r['place_score']),1))?></td><td><?=h(number_format(n($r['q_score']),1))?></td><td><?=h(number_format(n($r['trio_score']),1))?></td><td class="neg"><?=h(number_format(n($r['risk_score']),1))?></td><td><?=h(number_format(n($r['confidence_score']),1))?></td><td><?=h(number_format(n($r['stability_score']),1))?></td><td><?=h(number_format(n($r['score_gap']),1))?></td><td><?=h($r['production_state'])?></td><td class="small"><?=h($r['reason_zh'])?></td></tr><?php endforeach;?></table></div></div>
<div class="panel"><h3>🏇 Race Optimizer Summary</h3><div class="scroll"><table><tr><th>Date</th><th>Venue</th><th>Race</th><th>Horses</th><th>Mode</th><th>Hint</th><th>Top</th><th>Top Score</th><th>Second</th><th>Gap12</th><th>Gap14</th><th>Strength</th><th>Stability</th><th>Entropy</th><th>Q</th><th>Trio</th><th>Six-up</th><th>Avoid</th><th>Reason</th></tr><?php foreach($optRows as $r):?><tr><td><?=h($r['race_date'])?></td><td><?=h($r['venue'])?></td><td>R<?=h($r['race_num'])?></td><td><?=h($r['horse_count'])?></td><td class="gold"><?=h($r['race_mode'])?></td><td><?=h($r['race_hint'])?></td><td class="gold"><?=h($r['top_horse'])?></td><td class="gold"><?=h(number_format(n($r['top_score']),1))?></td><td><?=h($r['second_horse'])?></td><td><?=h(number_format(n($r['gap12']),1))?></td><td><?=h(number_format(n($r['gap14']),1))?></td><td><?=h(number_format(n($r['race_strength']),1))?></td><td><?=h(number_format(n($r['race_stability']),1))?></td><td class="neg"><?=h(number_format(n($r['race_entropy']),1))?></td><td class="pos"><?=h($r['q_suggestion'])?></td><td class="pos"><?=h($r['trio_suggestion'])?></td><td class="gold"><?=h($r['sixup_suggestion'])?></td><td class="neg"><?=h($r['avoid_suggestion'])?></td><td class="small"><?=h($r['reason_zh'])?></td></tr><?php endforeach;?></table></div></div>
<div class="split"><div class="panel"><h3>🧠 Parameter Learning</h3><div class="scroll"><table><tr><th>Parameter</th><th>Old</th><th>Suggested</th><th>Delta</th><th>Rows</th><th>Confidence</th><th>Reason</th></tr><?php foreach($paramRows as $r):?><tr><td class="layer"><?=h($r['parameter_name'])?></td><td><?=h(number_format(n($r['old_weight']),3))?></td><td class="gold"><?=h(number_format(n($r['suggested_weight']),3))?></td><td class="<?=n($r['learning_delta'])<0?'neg':'pos'?>"><?=h(number_format(n($r['learning_delta']),3))?></td><td><?=h($r['sample_rows'])?></td><td><?=h(number_format(n($r['confidence_score']),1))?></td><td class="small"><?=h($r['reason_zh'])?></td></tr><?php endforeach;?></table></div></div><div class="panel"><h3>🕘 Build / Save / Replay Log</h3><div class="scroll"><table><tr><th>Time</th><th>Run</th><th>Date</th><th>Venue</th><th>Status</th><th>Source</th><th>Production</th><th>Races</th><th>API</th><th>Params</th><th>Top</th><th>Score</th><th>Message</th></tr><?php foreach($logRows as $r):?><tr><td><?=h($r['created_at'])?></td><td><?=h($r['run_key'])?></td><td><?=h($r['race_date'])?></td><td><?=h($r['venue'])?></td><td><?=h($r['status'])?></td><td><?=h($r['source_rows'])?></td><td><?=h($r['production_rows'])?></td><td><?=h($r['optimizer_rows'])?></td><td><?=h($r['api_rows'])?></td><td><?=h($r['param_rows'])?></td><td class="gold"><?=h($r['top_horse'])?></td><td><?=h(number_format(n($r['top_score']),1))?></td><td class="small"><?=h($r['message'])?></td></tr><?php endforeach;?></table></div></div></div>
<div class="panel"><h3>🔌 analysis.php API Payload</h3><div class="scroll"><table><tr><th>Time</th><th>Date</th><th>Venue</th><th>Race</th><th>Type</th><th>PHP Hint</th><th>Reason</th></tr><?php foreach($apiRows as $r):?><tr><td><?=h($r['created_at'])?></td><td><?=h($r['race_date'])?></td><td><?=h($r['venue'])?></td><td>R<?=h($r['race_num'])?></td><td><?=h($r['api_type'])?></td><td class="small"><pre style="white-space:pre-wrap;color:#9ed9ff;margin:0"><?=h($r['php_hint'])?></pre></td><td class="small"><?=h($r['reason_zh'])?></td></tr><?php endforeach;?></table></div></div>
<div class="small" style="text-align:center;margin:30px">WinRacing V44.0 — Chairman Ranking Optimizer Ultimate | Production Score + Race Optimizer + analysis.php Ready API | Next: V45 Production Auto Learning</div></div></body></html>
