<?php
/**
 * Manage Election - Positions and Candidates
 */

require_once __DIR__ . '/../../includes/auth.php';
require_once __DIR__ . '/../../includes/voting.php';
require_once __DIR__ . '/../../includes/fellowships.php';
requireAuth();

requirePermission('voting.manage');

if (!isVotingEnabled()) {
    header('Location: ' . BASE_PATH . '/voting?toast_error=' . urlencode('Voting system is currently disabled.'));
    exit;
}

$election = getElection($id);
if (!$election) {
    header('Location: ' . BASE_PATH . '/voting?toast_error=' . urlencode('Election not found.'));
    exit;
}

// Lock editing once the election starts (draft editable, active/closed locked)
$endTs = !empty($election['end_date']) ? strtotime($election['end_date']) : false;
$electionOver = ($election['status'] ?? '') === 'closed' || ($endTs !== false && time() >= $endTs);
$canEdit = (($election['status'] ?? '') === 'draft') && !$electionOver;

if (!canManageElection($id)) {
    header('Location: ' . BASE_PATH . '/voting?toast_error=' . urlencode('You do not have permission to manage this election.'));
    exit;
}

// Handle POST actions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    
    $mutationActions = ['add_position', 'delete_position', 'add_candidate', 'delete_candidate', 'update_counts'];
    if (in_array($action, $mutationActions, true) && !$canEdit) {
        header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('Election is locked. No further changes are allowed.'));
        exit;
    }
    
    if ($action === 'add_position' && $election['type'] === 'fellowship') {
        $name = trim($_POST['position_name'] ?? '');
        $order = (int)($_POST['position_order'] ?? 0);
        if (!empty($name)) {
            $stmt = $pdo->prepare('INSERT INTO election_positions (election_id, name, position_order) VALUES (?, ?, ?)');
            $stmt->execute([$id, $name, $order]);
            header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast=' . urlencode('Position added.'));
            exit;
        }
    }
    
    if ($action === 'delete_position' && $election['type'] === 'fellowship') {
        $positionId = (int)($_POST['position_id'] ?? 0);
        if ($positionId > 0) {
            $pdo->prepare('DELETE FROM election_positions WHERE id = ? AND election_id = ?')->execute([$positionId, $id]);
            header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast=' . urlencode('Position deleted.'));
            exit;
        }
    }
    
    if ($action === 'add_candidate') {
        $memberId = (int)($_POST['member_id'] ?? 0);
        $positionId = $election['type'] === 'fellowship' ? (int)($_POST['position_id'] ?? 0) : null;
        
        if ($memberId > 0) {
            // Fetch member details for eligibility check
            $mStmt = $pdo->prepare('SELECT id, first_name, last_name, date_of_birth, gender, status, date_of_death FROM members WHERE id = ?');
            $mStmt->execute([$memberId]);
            $mData = $mStmt->fetch();
            if ($mData) {
                // Eligibility gate: member must belong to the election's assigned group
                $mName      = trim(($mData['first_name'] ?? '') . ' ' . ($mData['last_name'] ?? ''));
                $groupType  = $election['group_type'] ?? null;
                $groupId    = $election['group_id']   ?? null;
                $groupName  = $election['group_name'] ?? null;
                $ineligible = false;
                $groupLabel = 'this election';

                if ($election['type'] === 'fellowship') {
                    if ($groupType === 'service_grp' && $groupId) {
                        $chk = $pdo->prepare("SELECT id FROM member_ministries WHERE member_id = ? AND ministry_id = ?");
                        $chk->execute([$memberId, $groupId]);
                        $ineligible = !$chk->fetch();
                        // Fetch ministry name for error
                        $mnStmt = $pdo->prepare("SELECT name FROM ministries WHERE id = ?");
                        $mnStmt->execute([$groupId]);
                        $groupLabel = $mnStmt->fetchColumn() ?: 'the assigned service group';
                    } elseif ($groupType === 'gen_grp' && $groupName) {
                        $ageExpr = "TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE())";
                        switch ($groupName) {
                            case 'YPG':                $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 18 AND $ageExpr < 30"; break;
                            case 'YAF':                $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 30 AND $ageExpr < 40"; break;
                            case "Men's Fellowship":   $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 40 AND UPPER(TRIM(gender)) IN ('MALE','M')"; break;
                            case "Women's Fellowship": $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 40 AND UPPER(TRIM(gender)) IN ('FEMALE','F')"; break;
                            case 'Junior Youth':       $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 12 AND $ageExpr < 18"; break;
                            case "Children's Service": $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr < 12"; break;
                            default:                   $ageWhere = null;
                        }
                        if ($ageWhere) {
                            $chk = $pdo->prepare("SELECT id FROM members WHERE id = ? AND $ageWhere");
                            $chk->execute([$memberId]);
                            $ineligible = !$chk->fetch();
                        }
                        $groupLabel = $groupName;
                    }
                }

                if ($ineligible) {
                    header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode(
                        $mName . ' is not a member of ' . $groupLabel . ' and cannot stand for this election.'
                    ));
                    exit;
                }
                try {
                    if ($election['type'] === 'fellowship') {
                        if ($positionId > 0) {
                            // Explicit duplicate check (NULL position_id breaks the DB unique key)
                            $dup = $pdo->prepare('SELECT id FROM election_candidates WHERE position_id = ? AND member_id = ?');
                            $dup->execute([$positionId, $memberId]);
                            if ($dup->fetch()) {
                                header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('This member is already a candidate for that position.'));
                                exit;
                            }
                            $stmt = $pdo->prepare('INSERT INTO election_candidates (position_id, election_id, member_id) VALUES (?, ?, ?)');
                            $stmt->execute([$positionId, $id, $memberId]);
                        }
                    } else {
                        // Explicit duplicate check for presbyters (NULL position_id issue)
                        $dup = $pdo->prepare('SELECT id FROM election_candidates WHERE election_id = ? AND member_id = ? AND position_id IS NULL');
                        $dup->execute([$id, $memberId]);
                        if ($dup->fetch()) {
                            header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('This member is already a candidate in this election.'));
                            exit;
                        }
                        $stmt = $pdo->prepare('INSERT INTO election_candidates (election_id, member_id) VALUES (?, ?)');
                        $stmt->execute([$id, $memberId]);
                    }
                    header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast=' . urlencode('Candidate added.'));
                } catch (PDOException $e) {
                    if (strpos($e->getMessage(), 'Duplicate') !== false) {
                        header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('This member is already a candidate.'));
                    } else {
                        header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('Error adding candidate.'));
                    }
                }
                exit;
            }
        }
        header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('Member not found.'));
        exit;
    }
    
    if ($action === 'update_counts' && $election['type'] === 'presbyters') {
        $nFemales = max(0, (int)($_POST['number_of_females'] ?? 0));
        $nMales   = max(0, (int)($_POST['number_of_males']   ?? 0));
        $pdo->prepare('UPDATE elections SET number_of_females = ?, number_of_males = ? WHERE id = ?')
            ->execute([$nFemales, $nMales, $id]);
        // Reload election data
        $election = getElection($id);
        header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast=' . urlencode('Election counts updated.'));
        exit;
    }

    if ($action === 'delete_candidate') {
        if ($election['status'] === 'active') {
            header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast_error=' . urlencode('Candidates cannot be removed once voting has started.'));
            exit;
        }
        $candidateId = (int)($_POST['candidate_id'] ?? 0);
        if ($candidateId > 0) {
            $pdo->prepare('DELETE FROM election_candidates WHERE id = ? AND election_id = ?')->execute([$candidateId, $id]);
            header('Location: ' . BASE_PATH . '/voting/manage/' . $id . '?toast=' . urlencode('Candidate removed.'));
            exit;
        }
    }
}

$positions = $election['type'] === 'fellowship' ? getElectionPositions($id) : [];

// ── Build the eligible-candidate pool based on election group assignment ───────
$activeWhere = "(status != 'deceased' OR status IS NULL) AND date_of_death IS NULL";
$ageExpr     = "TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE())";

if ($election['type'] === 'fellowship') {
    $groupType = $election['group_type'] ?? null;
    $groupId   = $election['group_id']   ?? null;
    $groupName = $election['group_name'] ?? null;

    if ($groupType === 'service_grp' && $groupId) {
        $stmt = $pdo->prepare("
            SELECT DISTINCT m.id, m.title, m.first_name, m.middle_name, m.last_name, m.photo, m.gender, m.date_of_birth
            FROM members m
            JOIN member_ministries mm ON mm.member_id = m.id
            WHERE mm.ministry_id = ? AND $activeWhere
            ORDER BY m.last_name, m.first_name
        ");
        $stmt->execute([$groupId]);
        $allMembers = $stmt->fetchAll();
    } elseif ($groupType === 'gen_grp' && $groupName) {
        switch ($groupName) {
            case 'YPG':                $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 18 AND $ageExpr < 30"; break;
            case 'YAF':                $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 30 AND $ageExpr < 40"; break;
            case "Men's Fellowship":   $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 40 AND UPPER(TRIM(gender)) IN ('MALE','M')"; break;
            case "Women's Fellowship": $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 40 AND UPPER(TRIM(gender)) IN ('FEMALE','F')"; break;
            case 'Junior Youth':       $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr >= 12 AND $ageExpr < 18"; break;
            case "Children's Service": $ageWhere = "date_of_birth IS NOT NULL AND $ageExpr < 12"; break;
            default:                   $ageWhere = '1'; // unknown group — allow all
        }
        $allMembers = $pdo->query("
            SELECT id, title, first_name, middle_name, last_name, photo, gender, date_of_birth
            FROM members WHERE $activeWhere AND $ageWhere
            ORDER BY last_name, first_name
        ")->fetchAll();
    } else {
        // No group assigned — show all active members
        $allMembers = $pdo->query("SELECT id, title, first_name, middle_name, last_name, photo, gender, date_of_birth FROM members WHERE $activeWhere ORDER BY last_name, first_name")->fetchAll();
    }
} else {
    // Presbyters — whole-church, 18+
    $allMembers = $pdo->query("
        SELECT id, title, first_name, middle_name, last_name, photo, gender, date_of_birth
        FROM members WHERE $activeWhere AND (date_of_birth IS NULL OR $ageExpr >= 18)
        ORDER BY last_name, first_name
    ")->fetchAll();
}


// Collect already-added candidate IDs to exclude from search results
$alreadyAddedFemaleIds = [];
$alreadyAddedMaleIds   = [];
$positionCandidateIds  = []; // [positionId => [memberId, ...]]

if ($election['type'] === 'presbyters') {
    $existingFemales = getPresbytersCandidates($id, 'Female');
    $existingMales   = getPresbytersCandidates($id, 'Male');
    $alreadyAddedFemaleIds = array_map('intval', array_column($existingFemales, 'member_id'));
    $alreadyAddedMaleIds   = array_map('intval', array_column($existingMales,   'member_id'));
} else {
    foreach ($positions as $pos) {
        $cands = getPositionCandidates($pos['id']);
        $positionCandidateIds[(int)$pos['id']] = array_map('intval', array_column($cands, 'member_id'));
    }
}

// Prepare JSON datasets for the live-search comboboxes
$membersForSearch = array_map(function($m) {
    return ['id' => (int)$m['id'], 'name' => trim(($m['first_name'] ?? '') . ' ' . ($m['middle_name'] ?? '') . ' ' . ($m['last_name'] ?? ''))];
}, $allMembers);

// Build a gender-keyed lookup for quick filtering
$genderById = [];
foreach ($allMembers as $raw) { $genderById[(int)$raw['id']] = strtolower($raw['gender'] ?? ''); }

$femaleMembersForSearch = array_values(array_filter($membersForSearch, function($m) use ($genderById, $alreadyAddedFemaleIds) {
    return ($genderById[$m['id']] ?? '') === 'female' && !in_array($m['id'], $alreadyAddedFemaleIds, true);
}));
$maleMembersForSearch = array_values(array_filter($membersForSearch, function($m) use ($genderById, $alreadyAddedMaleIds) {
    return ($genderById[$m['id']] ?? '') === 'male' && !in_array($m['id'], $alreadyAddedMaleIds, true);
}));

// Handle add_member query parameter (from members page)
$addMemberId = isset($_GET['add_member']) ? (int)$_GET['add_member'] : null;
$addMember = null;
if ($addMemberId) {
    $stmt = $pdo->prepare('SELECT id, title, first_name, middle_name, last_name, photo, gender FROM members WHERE id = ?');
    $stmt->execute([$addMemberId]);
    $addMember = $stmt->fetch();
}

$pageTitle = 'Manage Election';
require_once __DIR__ . '/../../includes/header.php';
?>

<?php
$eStats   = getVoterStats($id);
$hasVList = electionHasVoterList($id);
// UI uses "$isActive" to mean "editing is locked" (forms only show when !$isActive)
$isActive = !$canEdit;

$electedFemaleIds = [];
$electedMaleIds   = [];
$electedCandidateIdByPosition = []; // fellowship: [positionId => candidateId]

if ($isActive) {
    $tickResults = getElectionResults($id);
    if (($election['type'] ?? '') === 'presbyters') {
        $nF = (int)($election['number_of_females'] ?? 0);
        $nM = (int)($election['number_of_males'] ?? 0);

        foreach (($tickResults['females'] ?? []) as $idx => $r) {
            if ($idx < $nF) $electedFemaleIds[(int)($r['candidate']['id'] ?? 0)] = true;
        }
        foreach (($tickResults['males'] ?? []) as $idx => $r) {
            if ($idx < $nM) $electedMaleIds[(int)($r['candidate']['id'] ?? 0)] = true;
        }
    } else {
        foreach (($tickResults ?? []) as $posResult) {
            $posId = (int)($posResult['position']['id'] ?? 0);
            $leading = $posResult['candidates'][0] ?? null;
            if ($leading && (int)($leading['votes'] ?? 0) > 0) {
                $electedCandidateIdByPosition[$posId] = (int)($leading['candidate']['id'] ?? 0);
            }
        }
    }
}
$statusColors = ['draft' => ['bg'=>'#f1f5f9','text'=>'#475569','dot'=>'#94a3b8'], 'active' => ['bg'=>'#dcfce7','text'=>'#166534','dot'=>'#22c55e'], 'closed' => ['bg'=>'#fee2e2','text'=>'#991b1b','dot'=>'#ef4444']];
$sc = $statusColors[$election['status']] ?? $statusColors['draft'];
?>

<div class="header">
    <div>
        <h1 style="margin:0 0 0.25rem;"><?= htmlspecialchars($election['title']) ?></h1>
        <div style="display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;">
            <span style="font-size:0.8125rem; color:#64748b;"><?= $election['type'] === 'fellowship' ? 'Group Election' : "Presbyters' Election" ?><?= !empty($election['group_name']) ? ' · ' . htmlspecialchars($election['group_name']) : (!empty($election['group_id']) ? ' · Service Group' : '') ?></span>
            <span style="display:inline-flex; align-items:center; gap:0.35rem; background:<?= $sc['bg'] ?>; color:<?= $sc['text'] ?>; font-size:0.75rem; font-weight:600; border-radius:999px; padding:0.2rem 0.65rem;">
                <span style="width:7px;height:7px;border-radius:50%;background:<?= $sc['dot'] ?>;display:inline-block;"></span>
                <?= ucfirst($election['status']) ?>
            </span>
        </div>
    </div>
    <div class="header-actions">
        <a href="<?= BASE_PATH ?>/voting/edit/<?= $id ?>" class="btn btn-outline btn-sm">Edit Settings</a>
        <a href="<?= BASE_PATH ?>/voting/vote/<?= $id ?>?simulate=1" class="btn btn-outline btn-sm" target="_blank">Preview</a>
        <a href="<?= BASE_PATH ?>/voting" class="link-muted">← Elections</a>
        <a href="<?= BASE_PATH ?>/logout">Logout</a>
    </div>
</div>

<style>
.mgmt-tiles { display:grid; grid-template-columns:repeat(4,1fr); gap:0.75rem; margin-bottom:1.5rem; }
@media(max-width:600px){ .mgmt-tiles { grid-template-columns:repeat(2,1fr); } }
.mgmt-tile { display:flex; align-items:center; gap:0.85rem; padding:0.9rem 1rem; background:#fff; border:1.5px solid #e2e8f0; border-radius:0; text-decoration:none; color:inherit; transition:border-color .15s, box-shadow .15s; }
.mgmt-tile:hover { box-shadow:0 4px 16px rgba(0,0,0,0.07); }
.mgmt-tile-icon { width:38px; height:38px; border-radius:0; display:flex; align-items:center; justify-content:center; font-size:1.1rem; flex-shrink:0; }
.mgmt-tile-label { font-weight:600; font-size:0.875rem; color:#0f172a; line-height:1.2; }
.mgmt-tile-sub { font-size:0.75rem; color:#64748b; margin-top:0.15rem; }
</style>
<div class="mgmt-tiles">
    <a href="<?= BASE_PATH ?>/voting/voters/<?= $id ?>" class="mgmt-tile" style="border-top:3px solid #3b82f6;">
        <div class="mgmt-tile-icon" style="background:#eff6ff; color:#3b82f6;">👥</div>
        <div>
            <div class="mgmt-tile-label">Eligible Voters</div>
            <div class="mgmt-tile-sub"><?= $hasVList ? $eStats['eligible'] . ' on roll' : 'Not set up' ?></div>
        </div>
    </a>
    <a href="<?= BASE_PATH ?>/voting/checkin/<?= $id ?>" class="mgmt-tile" style="border-top:3px solid #f59e0b;">
        <div class="mgmt-tile-icon" style="background:#fffbeb; color:#b45309;">✅</div>
        <div>
            <div class="mgmt-tile-label">Check-in Desk</div>
            <div class="mgmt-tile-sub"><?= $hasVList ? $eStats['checked_in'] . ' / ' . $eStats['eligible'] . ' checked in' : '—' ?></div>
        </div>
    </a>
    <?php $kioskAllowed = (($election['status'] ?? '') === 'active') && !$electionOver; ?>
    <?php if ($kioskAllowed): ?>
        <a href="<?= BASE_PATH ?>/voting/kiosk/<?= $id ?>" target="_blank" class="mgmt-tile" style="border-top:3px solid #059669;">
            <div class="mgmt-tile-icon" style="background:#f0fdf4; color:#059669;">🗳️</div>
            <div>
                <div class="mgmt-tile-label">Voting Kiosk</div>
                <div class="mgmt-tile-sub">Opens in new tab</div>
            </div>
        </a>
    <?php else: ?>
        <a href="#" class="mgmt-tile" style="border-top:3px solid #cbd5e1; opacity:0.75;"
           data-confirm="This election is not active, so the voting kiosk cannot be opened."
           data-confirm-mode="info" data-confirm-btn="OK">
            <div class="mgmt-tile-icon" style="background:#f1f5f9; color:#64748b;">🗳️</div>
            <div>
                <div class="mgmt-tile-label">Voting Kiosk</div>
                <div class="mgmt-tile-sub">Unavailable</div>
            </div>
        </a>
    <?php endif; ?>
    <a href="<?= BASE_PATH ?>/voting/results/<?= $id ?>" class="mgmt-tile" style="border-top:3px solid #7c3aed;">
        <div class="mgmt-tile-icon" style="background:#f5f3ff; color:#7c3aed;">📊</div>
        <div>
            <div class="mgmt-tile-label">Results</div>
            <div class="mgmt-tile-sub"><?= $hasVList ? $eStats['voted'] . ' votes cast' : '—' ?></div>
        </div>
    </a>
</div>

<?php if (!$hasVList && $election['status'] !== 'draft'): ?>
<div style="display:flex; align-items:center; gap:0.6rem; background:#fffbeb; border-left:4px solid #f59e0b; border-radius:0 8px 8px 0; padding:0.75rem 1rem; margin-bottom:1.25rem;">
    <span style="font-size:1rem;">⚠️</span>
    <span style="font-size:0.875rem; color:#92400e;"><strong>No voter list set up.</strong> <a href="<?= BASE_PATH ?>/voting/voters/<?= $id ?>">Set up the voter list →</a> so members can be checked in before voting.</span>
</div>
<?php endif; ?>

<?php if ($election['type'] === 'presbyters'): ?>
<div class="card" style="margin-bottom:1.5rem;">
    <h3 style="margin:0 0 0.75rem; font-size:0.9375rem; color:#64748b; text-transform:uppercase; letter-spacing:0.04em; font-weight:600;">Seats to fill</h3>
    <?php if (!$isActive): ?>
    <form method="post">
        <input type="hidden" name="action" value="update_counts">
        <div style="display:flex; align-items:center; gap:1rem; flex-wrap:wrap;">
            <label style="display:flex; align-items:center; gap:0.5rem; font-size:0.9375rem;">
                <input type="number" name="number_of_females" min="0" value="<?= (int)($election['number_of_females'] ?? 0) ?>"
                       style="width:64px; padding:0.4rem 0.5rem; border:1.5px solid #e2e8f0; border-radius:6px; font-size:1rem; text-align:center; font-weight:600;">
                <span>Female(s)</span>
            </label>
            <label style="display:flex; align-items:center; gap:0.5rem; font-size:0.9375rem;">
                <input type="number" name="number_of_males" min="0" value="<?= (int)($election['number_of_males'] ?? 0) ?>"
                       style="width:64px; padding:0.4rem 0.5rem; border:1.5px solid #e2e8f0; border-radius:6px; font-size:1rem; text-align:center; font-weight:600;">
                <span>Male(s)</span>
            </label>
            <button type="submit" class="btn btn-sm">Save</button>
        </div>
    </form>
    <?php else: ?>
    <div style="color:#64748b; font-size:0.875rem; font-style:italic;">
        Seat counts are locked once the election starts. Winners are shown with ✓ Elected in the candidate lists below.
    </div>
    <?php endif; ?>
</div>
<?php endif; ?>

<?php if ($addMember): ?>
<?php $addMemberName = trim(($addMember['title'] ?? '') . ' ' . ($addMember['first_name'] ?? '') . ' ' . ($addMember['middle_name'] ?? '') . ' ' . ($addMember['last_name'] ?? '')); ?>
<div style="display:flex; align-items:center; gap:0.6rem; background:#eff6ff; border-left:4px solid #3b82f6; border-radius:0 8px 8px 0; padding:0.75rem 1rem; margin-bottom:1.25rem;">
    <span style="font-size:0.875rem; color:#1e40af;"><strong>Adding:</strong> <?= htmlspecialchars($addMemberName) ?></span>
    <a href="<?= BASE_PATH ?>/voting/manage/<?= $id ?>" style="margin-left:auto; font-size:0.8125rem; color:#64748b;">Cancel</a>
</div>
<?php endif; ?>

<?php if ($election['type'] === 'fellowship'): ?>

<!-- ── Section heading ─────────────────────────────────────── -->
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:1rem;">
    <h2 style="margin:0; font-size:1.125rem;">Positions &amp; Candidates</h2>
    <span style="font-size:0.8125rem; color:#94a3b8;"><?= count($positions) ?> position<?= count($positions) !== 1 ? 's' : '' ?></span>
</div>

<?php if (empty($positions)): ?>
<div class="card" style="text-align:center; padding:2rem; color:#64748b;">
    <p style="margin:0 0 0.25rem; font-size:1.5rem;">📋</p>
    <p style="margin:0 0 1rem; font-weight:600;">No positions yet</p>
    <p style="margin:0; font-size:0.875rem;">Use the form below to add your first position, then add candidates.</p>
</div>
<?php endif; ?>

<?php foreach ($positions as $pos): ?>
<?php $candidates = getPositionCandidates($pos['id']); ?>
<div class="card" style="margin-bottom:1rem;">
    <!-- Position header -->
    <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:1rem;">
        <div style="display:flex; align-items:center; gap:0.6rem;">
            <span style="background:#0b1b89; color:#fff; font-size:0.6875rem; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; border-radius:999px; padding:0.2rem 0.65rem;"><?= count($candidates) ?> candidate<?= count($candidates) !== 1 ? 's' : '' ?></span>
            <h3 style="margin:0; font-size:1.0625rem;"><?= htmlspecialchars($pos['name']) ?></h3>
        </div>
        <?php if (!$isActive): ?>
        <form method="post" style="margin:0;">
            <input type="hidden" name="action" value="delete_position">
            <input type="hidden" name="position_id" value="<?= $pos['id'] ?>">
            <button type="submit" class="btn btn-sm btn-outline-danger" data-confirm="Delete '<?= htmlspecialchars($pos['name'], ENT_QUOTES) ?>' and all its candidates?">Delete position</button>
        </form>
        <?php endif; ?>
    </div>

    <!-- Candidate list -->
    <?php if (!empty($candidates)): ?>
    <div style="display:flex; flex-wrap:wrap; gap:0.75rem; margin-bottom:1rem;">
        <?php foreach ($candidates as $cand):
            $name = trim(($cand['first_name'] ?? '') . ' ' . ($cand['middle_name'] ?? '') . ' ' . ($cand['last_name'] ?? ''));
            $photoUrl = !empty($cand['photo']) ? BASE_PATH . '/public/uploads/members/' . htmlspecialchars($cand['photo']) : null;
            $gender = strtolower($cand['gender'] ?? '');
            $defaultPhoto = BASE_PATH . '/public/img/' . (($gender === 'male' || $gender === 'm') ? 'male' : 'female') . '.jpg';
            $profileUrl = BASE_PATH . '/members/view/' . $cand['member_id'];
        ?>
        <div style="display:flex; align-items:center; gap:0.6rem; background:#f8fafc; border:1.5px solid #e2e8f0; border-radius:10px; padding:0.5rem 0.75rem; min-width:0;">
            <a href="<?= $profileUrl ?>" target="_blank" title="View profile" style="flex-shrink:0;">
                <img src="<?= $photoUrl ?: $defaultPhoto ?>" alt="" style="width:38px; height:38px; object-fit:cover; object-position:top center; border-radius:6px; display:block;"
                     onerror="this.src='<?= $defaultPhoto ?>'">
            </a>
            <a href="<?= $profileUrl ?>" target="_blank" style="font-weight:600; font-size:0.875rem; color:#1e293b; text-decoration:none; white-space:nowrap;" title="View profile"><?= htmlspecialchars($name) ?></a>
            <?php if ($isActive && isset($electedCandidateIdByPosition[(int)$pos['id']]) && (int)$electedCandidateIdByPosition[(int)$pos['id']] === (int)$cand['id']): ?>
            <span style="margin-left:auto; background:#ecfdf5; color:#059669; font-weight:800; font-size:0.75rem; padding:0.2rem 0.55rem; border-radius:999px; border:1px solid #34d399;">
                ✓ Elected
            </span>
            <?php endif; ?>
            <?php if (!$isActive): ?>
            <form method="post" style="margin:0; margin-left:0.25rem;">
                <input type="hidden" name="action" value="delete_candidate">
                <input type="hidden" name="candidate_id" value="<?= $cand['id'] ?>">
                <button type="submit" title="Remove candidate" data-confirm="Remove <?= htmlspecialchars($name, ENT_QUOTES) ?>?"
                    style="background:none; border:none; cursor:pointer; color:#ef4444; font-size:1rem; padding:0; line-height:1;">×</button>
            </form>
            <?php endif; ?>
        </div>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <!-- Add candidate -->
    <?php if (!$isActive): ?>
    <form method="post" class="add-candidate-form" data-position-id="<?= $pos['id'] ?>" style="display:flex; gap:0.5rem; align-items:flex-start;">
        <input type="hidden" name="action" value="add_candidate">
        <input type="hidden" name="position_id" value="<?= $pos['id'] ?>">
        <div class="member-search-wrap" style="flex:1;">
            <?php
            $preloadName = $addMember ? trim(($addMember['first_name'] ?? '') . ' ' . ($addMember['middle_name'] ?? '') . ' ' . ($addMember['last_name'] ?? '')) : '';
            ?>
            <input type="text" class="member-search-input" placeholder="Search for a candidate…"
                   value="<?= htmlspecialchars($preloadName) ?>" autocomplete="off">
            <input type="hidden" name="member_id" value="<?= $addMember ? htmlspecialchars($addMember['id']) : '' ?>">
            <ul class="member-search-results"></ul>
        </div>
        <button type="submit" class="btn btn-sm">+ Add</button>
    </form>
    <?php else: ?>
    <p style="margin:0; font-size:0.8125rem; color:#94a3b8; font-style:italic;">Candidates are locked. Winners are shown with ✓ Elected.</p>
    <?php endif; ?>
</div>
<?php endforeach; ?>

<!-- Add new position -->
<?php if (!$isActive): ?>
<div style="border:2px dashed #cbd5e1; border-radius:12px; padding:1.1rem 1.25rem; margin-top:0.5rem;">
    <p style="margin:0 0 0.6rem; font-weight:600; font-size:0.9375rem; color:#475569;">Add a new position</p>
    <form method="post" style="display:flex; gap:0.5rem; align-items:flex-start;">
        <input type="hidden" name="action" value="add_position">
        <input type="hidden" name="position_order" value="0">
        <input type="text" name="position_name" placeholder="e.g. Secretary, Treasurer…" required
               style="flex:1; padding:0.5rem 0.75rem; border:1.5px solid #e2e8f0; border-radius:6px; font-size:0.9375rem;">
        <button type="submit" class="btn">Add Position</button>
    </form>
</div>
<?php endif; ?>

<?php else: ?>
<!-- ── Presbyters: Female + Male Candidates ─────────────────── -->
<?php
$femaleCandidates = getPresbytersCandidates($id, 'Female');
$maleCandidates   = getPresbytersCandidates($id, 'Male');

function renderPresbyterSection($label, $gender, $candidates, $isActive, $electedIds, $id, $addMember, $BASE_PATH) {
    $genderKey = strtolower($gender);
    $preloadName = ($addMember && strtolower($addMember['gender'] ?? '') === $genderKey)
        ? trim(($addMember['first_name'] ?? '') . ' ' . ($addMember['middle_name'] ?? '') . ' ' . ($addMember['last_name'] ?? ''))
        : '';
    $preloadId = ($addMember && strtolower($addMember['gender'] ?? '') === $genderKey) ? $addMember['id'] : '';
    $defaultImg = $BASE_PATH . '/public/img/' . $genderKey . '.jpg';
    ?>
<div class="card" style="margin-bottom:1rem;">
    <div style="display:flex; align-items:center; gap:0.6rem; margin-bottom:1rem;">
        <span style="background:#0b1b89; color:#fff; font-size:0.6875rem; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; border-radius:999px; padding:0.2rem 0.65rem;"><?= count($candidates) ?> candidate<?= count($candidates) !== 1 ? 's' : '' ?></span>
        <h3 style="margin:0; font-size:1.0625rem;"><?= $label ?></h3>
    </div>

    <?php if (!empty($candidates)): ?>
    <div style="display:flex; flex-wrap:wrap; gap:0.75rem; margin-bottom:1rem;">
        <?php foreach ($candidates as $cand):
            $name = trim(($cand['first_name'] ?? '') . ' ' . ($cand['middle_name'] ?? '') . ' ' . ($cand['last_name'] ?? ''));
            $photoUrl = !empty($cand['photo']) ? $BASE_PATH . '/public/uploads/members/' . htmlspecialchars($cand['photo']) : null;
            $profileUrl = $BASE_PATH . '/members/view/' . $cand['member_id'];
        ?>
        <div style="display:flex; align-items:center; gap:0.6rem; background:#f8fafc; border:1.5px solid #e2e8f0; border-radius:10px; padding:0.5rem 0.75rem;">
            <a href="<?= $profileUrl ?>" target="_blank" title="View profile" style="flex-shrink:0;">
                <img src="<?= $photoUrl ?: $defaultImg ?>" alt="" style="width:38px; height:38px; object-fit:cover; object-position:top center; border-radius:6px; display:block;"
                     onerror="this.src='<?= $defaultImg ?>'">
            </a>
            <a href="<?= $profileUrl ?>" target="_blank" style="font-weight:600; font-size:0.875rem; color:#1e293b; text-decoration:none; white-space:nowrap;"><?= htmlspecialchars($name) ?></a>
            <?php if ($isActive && !empty($electedIds) && isset($electedIds[(int)$cand['id']])): ?>
            <span style="margin-left:auto; background:#ecfdf5; color:#059669; font-weight:800; font-size:0.75rem; padding:0.2rem 0.55rem; border-radius:999px; border:1px solid #34d399;">
                ✓ Elected
            </span>
            <?php endif; ?>
            <?php if (!$isActive): ?>
            <form method="post" style="margin:0; margin-left:0.25rem;">
                <input type="hidden" name="action" value="delete_candidate">
                <input type="hidden" name="candidate_id" value="<?= $cand['id'] ?>">
                <button type="submit" title="Remove" data-confirm="Remove <?= htmlspecialchars($name, ENT_QUOTES) ?>?"
                    style="background:none; border:none; cursor:pointer; color:#ef4444; font-size:1rem; padding:0; line-height:1;">×</button>
            </form>
            <?php endif; ?>
        </div>
        <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php if (!$isActive): ?>
    <form method="post" class="add-candidate-form" data-search-gender="<?= $genderKey ?>" style="display:flex; gap:0.5rem;">
        <input type="hidden" name="action" value="add_candidate">
        <div class="member-search-wrap" style="flex:1;">
            <input type="text" class="member-search-input" placeholder="Search for a <?= $genderKey ?> candidate…"
                   value="<?= htmlspecialchars($preloadName) ?>" autocomplete="off">
            <input type="hidden" name="member_id" value="<?= htmlspecialchars($preloadId) ?>">
            <ul class="member-search-results"></ul>
        </div>
        <button type="submit" class="btn btn-sm">+ Add</button>
    </form>
    <?php else: ?>
    <p style="margin:0; font-size:0.8125rem; color:#94a3b8; font-style:italic;">Candidates are locked. Winners are shown with ✓ Elected.</p>
    <?php endif; ?>
</div>
    <?php
}

renderPresbyterSection('Female Candidates', 'female', $femaleCandidates, $isActive, $electedFemaleIds, $id, $addMember, BASE_PATH);
renderPresbyterSection('Male Candidates',   'male',   $maleCandidates,   $isActive, $electedMaleIds,   $id, $addMember, BASE_PATH);
?>
<?php endif; ?>

<style>
.member-search-wrap { position: relative; }
.member-search-wrap .member-search-input {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 6px;
    font-size: 0.9375rem;
}
.member-search-wrap .member-search-input:focus {
    outline: none;
    border-color: var(--primary, #1e3a5f);
    box-shadow: 0 0 0 3px rgba(30,58,95,0.08);
}
.member-search-results {
    position: absolute;
    z-index: 200;
    top: calc(100% + 2px);
    left: 0; right: 0;
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.1);
    max-height: 220px;
    overflow-y: auto;
    list-style: none;
    margin: 0; padding: 0;
    display: none;
}
.member-search-results li {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    font-size: 0.875rem;
    border-bottom: 1px solid var(--border, #f1f5f9);
}
.member-search-results li:last-child { border-bottom: none; }
.member-search-results li:hover,
.member-search-results li.active { background: #f1f5f9; }
.member-search-results li .match { font-weight: 600; }
.member-search-no-results {
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    color: var(--text-muted, #718096);
}
</style>

<script>
(function () {
    var allMembers         = <?= json_encode(array_values($membersForSearch)) ?>;
    var femaleMembers      = <?= json_encode(array_values($femaleMembersForSearch)) ?>;
    var maleMembers        = <?= json_encode(array_values($maleMembersForSearch)) ?>;
    var posExclusions      = <?= json_encode($positionCandidateIds) ?>; // {positionId: [memberId, ...]}

    function escapeHtml(s) {
        return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    }

    function highlightMatch(name, q) {
        if (!q) return escapeHtml(name);
        var idx = name.toLowerCase().indexOf(q.toLowerCase());
        if (idx === -1) return escapeHtml(name);
        return escapeHtml(name.slice(0, idx))
             + '<span class="match">' + escapeHtml(name.slice(idx, idx + q.length)) + '</span>'
             + escapeHtml(name.slice(idx + q.length));
    }

    function initSearch(wrap, dataset) {
        var input   = wrap.querySelector('.member-search-input');
        var hidden  = wrap.querySelector('input[name="member_id"]');
        var results = wrap.querySelector('.member-search-results');
        var activeIdx = -1;

        function showResults(items, q) {
            results.innerHTML = '';
            activeIdx = -1;
            if (items.length === 0) {
                var li = document.createElement('li');
                li.className = 'member-search-no-results';
                li.textContent = 'No members found.';
                results.appendChild(li);
            } else {
                items.forEach(function (m, i) {
                    var li = document.createElement('li');
                    li.innerHTML = highlightMatch(m.name, q);
                    li.addEventListener('mousedown', function (e) {
                        e.preventDefault();
                        input.value  = m.name;
                        hidden.value = m.id;
                        results.style.display = 'none';
                    });
                    results.appendChild(li);
                });
            }
            results.style.display = 'block';
        }

        input.addEventListener('input', function () {
            var q = this.value.trim();
            hidden.value = '';
            if (q.length === 0) { results.style.display = 'none'; return; }
            var filtered = dataset.filter(function (m) {
                return m.name.toLowerCase().includes(q.toLowerCase());
            }).slice(0, 12);
            showResults(filtered, q);
        });

        input.addEventListener('keydown', function (e) {
            var items = results.querySelectorAll('li:not(.member-search-no-results)');
            if (!items.length) return;
            if (e.key === 'ArrowDown') {
                e.preventDefault();
                activeIdx = Math.min(activeIdx + 1, items.length - 1);
            } else if (e.key === 'ArrowUp') {
                e.preventDefault();
                activeIdx = Math.max(activeIdx - 1, 0);
            } else if (e.key === 'Enter') {
                e.preventDefault();
                if (activeIdx >= 0) items[activeIdx].dispatchEvent(new MouseEvent('mousedown'));
                return;
            } else if (e.key === 'Escape') {
                results.style.display = 'none';
                return;
            }
            items.forEach(function (li, i) {
                li.classList.toggle('active', i === activeIdx);
                if (i === activeIdx) li.scrollIntoView({ block: 'nearest' });
            });
        });

        input.addEventListener('blur', function () {
            setTimeout(function () { results.style.display = 'none'; }, 150);
        });

        input.addEventListener('focus', function () {
            if (this.value.trim().length > 0 && results.children.length) {
                results.style.display = 'block';
            }
        });
    }

    // Wire up every candidate form
    document.querySelectorAll('.add-candidate-form').forEach(function (form) {
        var gender     = form.dataset.searchGender;  // 'female' | 'male' | undefined
        var positionId = form.dataset.positionId;    // fellowship only
        var dataset;

        if (gender === 'female') {
            dataset = femaleMembers;
        } else if (gender === 'male') {
            dataset = maleMembers;
        } else if (positionId && posExclusions[positionId]) {
            // Fellowship: exclude members already added to this position
            var excluded = posExclusions[positionId];
            dataset = allMembers.filter(function (m) {
                return excluded.indexOf(m.id) === -1;
            });
        } else {
            dataset = allMembers;
        }

        var wrap = form.querySelector('.member-search-wrap');
        if (wrap) initSearch(wrap, dataset);
    });
})();
</script>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
