<?php
/**
 * 時間大富翁 - 股市 2.0 (基本面評等與漂移引擎)
 */
class StockEngine {
    
    public static function updateDailyPrices($mysql_db) {
        $today = date('Y-m-d');
        $current_month = date('Y-m'); 
        
        $days_in_month = (int)date('t');
        $current_day = (int)date('j');
        $days_left = max(1, $days_in_month - $current_day + 1);

        try {
            $mysql_db->beginTransaction();
            
            $stmt = $mysql_db->prepare("SELECT * FROM global_stocks WHERE is_active = 1 AND (last_update_date IS NULL OR last_update_date != :today) FOR UPDATE");
            $stmt->execute([':today' => $today]);
            $stocks = $stmt->fetchAll();
            
            if (count($stocks) === 0) {
                $mysql_db->commit();
                return; 
            }

            $stmt_events = $mysql_db->query("SELECT * FROM stock_market_events WHERE is_processed = 0 FOR UPDATE");
            $pending_events = $stmt_events->fetchAll();

            $stock_buffs = [];
            $global_buff = 0.0;
            
            foreach ($pending_events as $ev) {
                $val = (float)$ev['effect_value'];
                if ($ev['stock_code'] === 'ALL') {
                    $global_buff += $val;
                } else {
                    $code = $ev['stock_code'];
                    if (!isset($stock_buffs[$code])) $stock_buffs[$code] = 0.0;
                    $stock_buffs[$code] += $val;
                }
            }

            $stmt_players = $mysql_db->query("SELECT id, display_name, sqlite_file FROM users WHERE role = 'player'");
            $players = $stmt_players->fetchAll();

            foreach ($stocks as $stock) {
                $code = $stock['stock_code'];
                $limit = (float)$stock['volatility_limit']; 
                $current_price = (float)$stock['current_price'];
                $target_price = (float)$stock['target_price'];
                $rating = (int)($stock['rating'] ?? 3); 
                
                $month_start_price = (float)($stock['month_start_price'] ?? 0);
                if ($month_start_price <= 0) $month_start_price = $current_price;
                
                $is_new_month = ($stock['target_month'] !== $current_month);
                
                // =====================================
                // 1. 月初結算：除息發放與設定新目標
                // =====================================
                if ($is_new_month) {
                    
                    $dividend_per_share = 0;
                    
                    // 完美配息法：如果這個月有賺錢，就把賺到的 80% 當現金發掉
                    if ($current_price > $month_start_price) {
                        $monthly_profit = $current_price - $month_start_price;
                        $dividend_per_share = $monthly_profit * 0.80;
                    }

                    if ($dividend_per_share > 0) {
                        foreach ($players as $p) {
                            if (!empty($p['sqlite_file']) && file_exists(__DIR__ . '/' . $p['sqlite_file'])) {
                                $p_db = getPlayerSQLiteConnection($p['sqlite_file']);
                                
                                try { $p_db->exec("ALTER TABLE stock_portfolio ADD COLUMN total_dividends REAL DEFAULT 0.0"); } catch (Exception $e) {}
                                
                                $stmt_hold = $p_db->prepare("SELECT total_shares, average_cost FROM stock_portfolio WHERE stock_id = ? AND total_shares > 0");
                                $stmt_hold->execute([$stock['id']]);
                                $hold = $stmt_hold->fetch();
                                
                                if ($hold) {
                                    $shares = (int)$hold['total_shares'];
                                    $total_div = (int)round($shares * $dividend_per_share);
                                    
                                    if ($total_div > 0) {
                                        $p_db->beginTransaction();
                                        $p_db->exec("UPDATE wallet SET balance_minutes = balance_minutes + $total_div");
                                        
                                        // ★ 核心修正：只增加「累計領息」，不再扣減 average_cost (均價)
                                        $p_db->prepare("UPDATE stock_portfolio SET total_dividends = total_dividends + ? WHERE stock_id = ?")
                                             ->execute([$total_div, $stock['id']]);
                                             
                                        $desc = "💸 股市配息：【{$stock['stock_name']}】結算本月獲利，獲得 {$total_div} 分鐘！";
                                        $p_db->prepare("INSERT INTO transaction_logs (action_type, amount, description) VALUES ('stock_dividend', ?, ?)")->execute([$total_div, $desc]);
                                        $p_db->commit();
                                    }
                                }
                            }
                        }
                    }

                    // 除息後的新股價
                    $ex_dividend_price = max(0.01, $current_price - $dividend_per_share);

                    if ($rating == 5) { $growth_rate = mt_rand(50, 200) / 100; } 
                    elseif ($rating == 4) { $growth_rate = mt_rand(20, 100) / 100; } 
                    elseif ($rating == 3) { $growth_rate = mt_rand(-10, 50) / 100; } 
                    elseif ($rating == 2) { $growth_rate = mt_rand(-30, 20) / 100; } 
                    else { $growth_rate = mt_rand(-50, 10) / 100; }
                    
                    $target_price = $ex_dividend_price * (1 + $growth_rate);
                    $month_start_price = $ex_dividend_price;
                    
                    $base_price_for_today = $ex_dividend_price;
                    $current_price = $ex_dividend_price;
                } else {
                    $base_price_for_today = $current_price;
                }

                // =====================================
                // 2. 每日波動：目標漂移演算法
                // =====================================
                $required_return = 0;
                if ($current_price > 0 && $target_price > 0) {
                    $required_return = ($target_price - $current_price) / $current_price;
                }
                $daily_drift = $required_return / $days_left;

                $max_rand = (int)($limit * 10000);
                $system_factor = mt_rand(-$max_rand, $max_rand) / 10000;
                $system_factor += $daily_drift;
                
                $magic_factor = $global_buff;
                if (isset($stock_buffs[$code])) {
                    $magic_factor += $stock_buffs[$code];
                }

                $final_factor = $system_factor + $magic_factor;
                
                if ($final_factor > $limit) { $final_factor = $limit; }
                if ($final_factor < -$limit) { $final_factor = -$limit; }

                $new_price = $current_price * (1 + $final_factor);
                if ($new_price < 0.01) { $new_price = 0.01; }
                
                if ($is_new_month) {
                    $update_stmt = $mysql_db->prepare("UPDATE global_stocks SET base_price = ?, current_price = ?, last_update_date = ?, target_month = ?, target_price = ?, month_start_price = ? WHERE id = ?");
                    $update_stmt->execute([round($base_price_for_today, 2), round($new_price, 2), $today, $current_month, round($target_price, 2), round($month_start_price, 2), $stock['id']]);
                } else {
                    $update_stmt = $mysql_db->prepare("UPDATE global_stocks SET base_price = ?, current_price = ?, last_update_date = ? WHERE id = ?");
                    $update_stmt->execute([round($base_price_for_today, 2), round($new_price, 2), $today, $stock['id']]);
                }
            }

            if (count($pending_events) > 0) {
                $mysql_db->exec("UPDATE stock_market_events SET is_processed = 1 WHERE is_processed = 0");
            }

            $mysql_db->commit();
        } catch (Exception $e) {
            $mysql_db->rollBack();
            error_log("Stock Update Error: " . $e->getMessage());
        }
    }

    // ==========================================
    // 瞬間爆發魔法引擎 (卡牌立刻發威)
    // ==========================================
    public static function applyInstantMagic($mysql_db, $player_id, $stock_code, $effect_value) {
        try {
            $mysql_db->beginTransaction();
            
            if ($stock_code === 'ALL') {
                $stmt = $mysql_db->query("SELECT * FROM global_stocks WHERE is_active = 1 FOR UPDATE");
                $stocks = $stmt->fetchAll();
            } else {
                $stmt = $mysql_db->prepare("SELECT * FROM global_stocks WHERE is_active = 1 AND stock_code = ? FOR UPDATE");
                $stmt->execute([$stock_code]);
                $stocks = $stmt->fetchAll();
            }

            $applied_names = [];

            foreach ($stocks as $s) {
                $base_price = (float)$s['base_price']; 
                $current_price = (float)$s['current_price'];
                $limit = (float)$s['volatility_limit']; 

                $max_allowed_price = $base_price * (1 + $limit);
                $min_allowed_price = $base_price * (1 - $limit);

                $new_price = $current_price * (1 + (float)$effect_value);

                if ($new_price > $max_allowed_price) { $new_price = $max_allowed_price; }
                if ($new_price < $min_allowed_price) { $new_price = $min_allowed_price; }
                if ($new_price < 0.01) { $new_price = 0.01; }

                $stmt_up = $mysql_db->prepare("UPDATE global_stocks SET current_price = ? WHERE id = ?");
                $stmt_up->execute([round($new_price, 2), $s['id']]);
                $applied_names[] = $s['stock_name'];
            }

            $icon = ($effect_value > 0) ? '🚀' : '⚠️';
            $sign = ($effect_value > 0) ? '+' : '';
            $pct = (float)$effect_value * 100;
            $target_name_str = ($stock_code === 'ALL') ? '全體大盤' : implode('、', $applied_names);
            
            $msg = "【市場突發】{$icon} 市場遭到神秘資金突襲！目標：{$target_name_str}，引發 {$sign}{$pct}% 的劇烈震盪！";
            $stmt_msg = $mysql_db->prepare("INSERT INTO global_messages (message) VALUES (?)");
            $stmt_msg->execute([$msg]);

            $mysql_db->commit();
            return true;
        } catch (Exception $e) {
            $mysql_db->rollBack();
            return false;
        }
    }
}
?>