<?php
declare(strict_types=1);
require_once __DIR__ . "/../auth_helper.php";
require_login();

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $election_id = $_POST["election_id"] ?? "";
    $raw_votes = $_POST["votes"] ?? []; // Array of position_id => candidate_id (string or array)
    $user = get_user();

    if (!$election_id) {
        die("Invalid submission.");
    }

    try {
        $pdo = db();
        $pdo->beginTransaction();

        // 1. Verify election is ongoing
        $eStmt = $pdo->prepare("SELECT status FROM elections WHERE id = ?");
        $eStmt->execute([$election_id]);
        $election = $eStmt->fetch();
        if (!$election || $election["status"] !== "Ongoing") {
            throw new Exception("Election is not currently ongoing.");
        }

        // 2. Verify user hasn't voted yet
        $vCheck = $pdo->prepare("SELECT COUNT(*) FROM votes WHERE election_id = ? AND voter_id = ?");
        $vCheck->execute([$election_id, $user["id"]]);
        if ($vCheck->fetchColumn() > 0) {
            throw new Exception("You have already cast your vote for this election.");
        }

        // 3. Prepare statement for inserting votes
        $stmt = $pdo->prepare("INSERT INTO votes (id, election_id, position_id, candidate_id, voter_id, ip_address, user_agent) VALUES (?, ?, ?, ?, ?, ?, ?)");
        
        // 4. Validate each position's votes
        foreach ($raw_votes as $position_id => $candidate_id) {
            if (empty($candidate_id)) continue;

            // Fetch position details
            $pStmt = $pdo->prepare("SELECT * FROM positions WHERE id = ? AND election_id = ?");
            $pStmt->execute([$position_id, $election_id]);
            $pos = $pStmt->fetch();

            if (!$pos) {
                throw new Exception("Invalid position detected.");
            }

            // Validate candidate
            $cStmt = $pdo->prepare("SELECT c.*, u.track FROM candidates c JOIN users u ON c.user_id = u.id WHERE c.id = ? AND c.position_id = ? AND c.approved = TRUE");
            $cStmt->execute([$candidate_id, $position_id]);
            $cand = $cStmt->fetch();

            if (!$cand) {
                throw new Exception("Invalid or unapproved candidate selected.");
            }

            // Check Track Specific logic
            if ($pos["type"] === "Track Specific" && $cand["track"] !== $user["track"]) {
                throw new Exception("Candidate track mismatch for position: " . $pos["name"]);
            }

            // Insert vote
            $stmt->execute([
                uuid(),
                $election_id,
                $position_id,
                $candidate_id,
                $user["id"],
                $_SERVER["REMOTE_ADDR"] ?? "unknown",
                $_SERVER["HTTP_USER_AGENT"] ?? "unknown"
            ]);
        }

        audit_log("Cast ballot", "elections", $election_id);
        
        $pdo->commit();
        header("Location: ../index.php?success=voted");
        exit;
    } catch (Exception $e) {
        if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
        die("Error casting vote: " . $e->getMessage());
    }
}
