<?php
/**
 * pollster_api_ijl.php — IntelJunky Pollster API
 * IJL2.2 / LMNA 3.2 — Full conversion from pollster_api.php
 *
 * Sitewide polling — works from any subdomain via CORS.
 * All poll content encrypted at input boundary, decrypted at output.
 *
 * ACTIONS:
 *   create       — Create a new poll (auth required)
 *   get          — Get poll + options + user vote status
 *   vote         — Cast a vote
 *   results      — Get vote counts
 *   list         — List polls (paginated)
 *   delete       — Delete poll (owner or admin)
 *   update       — Update poll question/options
 *   my_polls     — Get current user's polls
 *   featured     — Get featured/active polls for widget injection
 *   track_embed  — Record widget load (analytics)
 *
 * PHP 5.4 / mysql_* / IJL2.2 throughout.
 */

// ── IJL2.2 Bootstrap ─────────────────────────────────────────────────────────
// CRITICAL: Session configuration MUST be set BEFORE any session operations
// This ensures cross-subdomain session sharing with main inteljunky.com site
ini_set('session.cookie_domain', '.inteljunkysandbox.com');
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.name', 'PHPSESSID');

define('IJL_RUNNING', true);
$_ijl_core = '/home/inteljun/ijl_core/ijl_bootstrap.php';
if (!file_exists($_ijl_core)) $_ijl_core = dirname(__FILE__) . '/ijl_core/ijl_bootstrap.php';
require_once $_ijl_core;

// ── Credentials ──────────────────────────────────────────────────────────────
$_secret = '/home/inteljun/secret_file.php';
if (file_exists($_secret) && !defined('DB_HOST')) require_once $_secret;

// ── Session ───────────────────────────────────────────────────────────────────
// Session already configured via ini_set() at top of file
if (session_status() !== PHP_SESSION_ACTIVE) {
    // ── LMNA SSO Session Bridge ──
    // Must set session_name BEFORE session_start() so PHP reads the correct cookie.
    // The LMNA_CORE_SESSION cookie (shared across .inteljunkysandbox.com) contains
    // user_id, auth data, etc. Without this, PHP reads PHPSESSID → empty session.
    if (session_status() === PHP_SESSION_NONE) {
        session_name('LMNA_CORE_SESSION');
        ini_set('session.cookie_domain', '.inteljunkysandbox.com');
        ini_set('session.cookie_samesite', 'Lax');
        ini_set('session.cookie_httponly', 1);
        ini_set('session.cookie_secure', 1);
    }
    session_start();
}

// ── CORS — allow all *.inteljunky.com subdomains ──────────────────────────────
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
if ($origin && preg_match('/^https?:\/\/([a-zA-Z0-9\-]+\.)?inteljunkysandbox\.com$/', $origin)) {
    header('Access-Control-Allow-Origin: '   . $origin);
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, X-Requested-With');
}
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

header('Content-Type: application/json; charset=utf-8');
header('X-Powered-By: IJL2.2');
header('X-Content-Type-Options: nosniff');

// ── DB Connect ────────────────────────────────────────────────────────────────
$db = IJL_db_connect(DB_HOST, DB_USER, DB_PASS, DB_AI);
if (!$db) {
    echo IJL_json_encode(array('success' => false, 'error' => 'DB unavailable'));
    exit;
}

// ── Auto-create tables ────────────────────────────────────────────────────────
IJL_db_query("CREATE TABLE IF NOT EXISTS `polls` (
    `id`              INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `user_id`         INT(11) UNSIGNED NOT NULL DEFAULT 0,
    `slug`            VARCHAR(128) NOT NULL UNIQUE,
    `encrypted_question` TEXT NOT NULL,
    `context`         VARCHAR(64)  NOT NULL DEFAULT 'general',
    `is_active`       TINYINT(1)   NOT NULL DEFAULT 1,
    `is_featured`     TINYINT(1)   NOT NULL DEFAULT 0,
    `allow_multiple`  TINYINT(1)   NOT NULL DEFAULT 0,
    `ends_at`         DATETIME NULL,
    `embed_count`     INT(11) UNSIGNED NOT NULL DEFAULT 0,
    `vote_count`      INT(11) UNSIGNED NOT NULL DEFAULT 0,
    `created_at`      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`      DATETIME NULL,
    PRIMARY KEY (`id`),
    KEY `idx_slug`    (`slug`),
    KEY `idx_context` (`context`),
    KEY `idx_active`  (`is_active`),
    KEY `idx_featured`(`is_featured`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8");

IJL_db_query("CREATE TABLE IF NOT EXISTS `poll_options` (
    `id`              INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `poll_id`         INT(11) UNSIGNED NOT NULL,
    `encrypted_text`  TEXT NOT NULL,
    `sort_order`      INT(11) NOT NULL DEFAULT 0,
    `vote_count`      INT(11) UNSIGNED NOT NULL DEFAULT 0,
    PRIMARY KEY (`id`),
    KEY `idx_poll` (`poll_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8");

IJL_db_query("CREATE TABLE IF NOT EXISTS `poll_votes` (
    `id`              INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `poll_id`         INT(11) UNSIGNED NOT NULL,
    `option_id`       INT(11) UNSIGNED NOT NULL,
    `user_id`         INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 = anonymous/fingerprint',
    `fingerprint`     VARCHAR(64)  NOT NULL DEFAULT '' COMMENT 'browser fingerprint for anon dedup',
    `ip_hash`         VARCHAR(64)  NOT NULL DEFAULT '' COMMENT 'hashed IP, not stored in plain',
    `created_at`      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_user_option`  (`poll_id`, `option_id`, `user_id`),
    KEY `idx_poll_id` (`poll_id`),
    KEY `idx_option`  (`option_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8");

// ── Helpers ───────────────────────────────────────────────────────────────────
function poll_respond($data) {
    echo IJL_json_encode($data);
    exit;
}

function poll_esc($s) {
    return IJL_db_escape((string)$s);
}

$user_id   = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0;
$is_admin  = isset($_SESSION['user_level']) && (int)$_SESSION['user_level'] >= 9;

// ── Parse input ───────────────────────────────────────────────────────────────
$raw   = file_get_contents('php://input');
$input = array();
if ($raw) {
    $decoded = IJL_decrypt($raw);
    $input   = @json_decode($decoded, true);
    if (!is_array($input)) $input = @json_decode($raw, true);
}
if (!is_array($input)) {
    // Also support GET params
    $input = array_merge($_GET, $_POST);
}

$action = isset($input['action']) ? trim($input['action']) : 'list';

// ── Route ─────────────────────────────────────────────────────────────────────
switch ($action) {

    // =========================================================================
    // CREATE
    // =========================================================================
    case 'create':
        if (!$user_id) poll_respond(array('success' => false, 'error' => 'Login required'));

        $question      = isset($input['question']) ? trim($input['question']) : '';
        $options_raw   = isset($input['options'])  ? $input['options']        : array();
        $context       = isset($input['context'])  ? trim($input['context'])  : 'general';
        $allow_multiple= (int)(isset($input['allow_multiple']) ? $input['allow_multiple'] : 0);
        $ends_at       = isset($input['ends_at'])  ? trim($input['ends_at'])  : null;
        $is_featured   = (int)(isset($input['is_featured']) ? $input['is_featured'] : 0);

        if (!$question)                 poll_respond(array('success' => false, 'error' => 'question required'));
        if (count($options_raw) < 2)    poll_respond(array('success' => false, 'error' => 'At least 2 options required'));
        if (count($options_raw) > 10)   poll_respond(array('success' => false, 'error' => 'Maximum 10 options'));

        // Encrypt question at input boundary
        $enc_q    = poll_esc(IJL_encrypt($question));
        $ctx_esc  = poll_esc($context);
        $ends_sql = $ends_at ? "'" . poll_esc($ends_at) . "'" : 'NULL';

        // Generate unique slug
        $base_slug = preg_replace('/[^a-z0-9]+/', '-', strtolower($question));
        $base_slug = trim(substr($base_slug, 0, 60), '-');
        $slug      = $base_slug . '-' . substr(md5(uniqid('', true)), 0, 6);
        $slug_esc  = poll_esc($slug);

        // Admin can feature, others need approval
        $featured_val = ($is_admin && $is_featured) ? 1 : 0;

        $poll_id = IJL_db_insert("INSERT INTO polls
            (user_id, slug, encrypted_question, context, allow_multiple,
             ends_at, is_featured, is_active, created_at)
            VALUES
            ($user_id, '$slug_esc', '$enc_q', '$ctx_esc', $allow_multiple,
             $ends_sql, $featured_val, 1, NOW())");

        if (!$poll_id) poll_respond(array('success' => false, 'error' => 'Insert failed'));

        // Insert options — each encrypted at input boundary
        foreach ($options_raw as $i => $opt_text) {
            $opt_text = trim((string)$opt_text);
            if (!$opt_text) continue;
            $enc_opt = poll_esc(IJL_encrypt($opt_text));
            $sort    = (int)$i;
            IJL_db_insert("INSERT INTO poll_options (poll_id, encrypted_text, sort_order)
                           VALUES ($poll_id, '$enc_opt', $sort)");
        }

        poll_respond(array('success' => true, 'poll_id' => (int)$poll_id, 'slug' => $slug));
        break;

    // =========================================================================
    // GET
    // =========================================================================
    case 'get':
        $slug    = isset($input['slug'])    ? trim($input['slug'])    : '';
        $poll_id = (int)(isset($input['poll_id']) ? $input['poll_id'] : 0);

        $where = $slug ? "slug = '" . poll_esc($slug) . "'" : "id = $poll_id";
        $poll  = IJL_db_query_row("SELECT * FROM polls WHERE $where AND is_active = 1 LIMIT 1");
        if (!$poll) poll_respond(array('success' => false, 'error' => 'Poll not found'));

        $pid  = (int)$poll['id'];
        $opts = IJL_db_query_all("SELECT id, encrypted_text, sort_order, vote_count
                                   FROM poll_options WHERE poll_id = $pid
                                   ORDER BY sort_order ASC");

        // Decrypt options at output boundary
        $options_out = array();
        foreach ($opts as $o) {
            $options_out[] = array(
                'id'         => (int)$o['id'],
                'text'       => IJL_decrypt($o['encrypted_text']),
                'vote_count' => (int)$o['vote_count'],
            );
        }

        // Check if current user has voted
        $user_voted = false;
        $user_vote_option_ids = array();
        if ($user_id) {
            $votes = IJL_db_query_all("SELECT option_id FROM poll_votes
                                        WHERE poll_id = $pid AND user_id = $user_id");
            if ($votes) {
                $user_voted = true;
                foreach ($votes as $v) $user_vote_option_ids[] = (int)$v['option_id'];
            }
        }

        poll_respond(array(
            'success'    => true,
            'poll' => array(
                'id'             => $pid,
                'slug'           => $poll['slug'],
                'question'       => IJL_decrypt($poll['encrypted_question']),
                'context'        => $poll['context'],
                'allow_multiple' => (int)$poll['allow_multiple'],
                'ends_at'        => $poll['ends_at'],
                'vote_count'     => (int)$poll['vote_count'],
                'is_featured'    => (int)$poll['is_featured'],
                'created_at'     => $poll['created_at'],
            ),
            'options'    => $options_out,
            'user_voted' => $user_voted,
            'user_votes' => $user_vote_option_ids,
        ));
        break;

    // =========================================================================
    // VOTE
    // =========================================================================
    case 'vote':
        $poll_id  = (int)(isset($input['poll_id'])  ? $input['poll_id']  : 0);
        $option_id= (int)(isset($input['option_id'])? $input['option_id']: 0);

        if (!$poll_id || !$option_id) poll_respond(array('success' => false, 'error' => 'poll_id and option_id required'));

        $poll = IJL_db_query_row("SELECT id, allow_multiple, ends_at, is_active FROM polls WHERE id = $poll_id LIMIT 1");
        if (!$poll || !$poll['is_active']) poll_respond(array('success' => false, 'error' => 'Poll not found or inactive'));

        // Check expiry
        if ($poll['ends_at'] && strtotime($poll['ends_at']) < time()) {
            poll_respond(array('success' => false, 'error' => 'Poll has ended'));
        }

        // Verify option belongs to poll
        $opt = IJL_db_query_row("SELECT id FROM poll_options WHERE id = $option_id AND poll_id = $poll_id LIMIT 1");
        if (!$opt) poll_respond(array('success' => false, 'error' => 'Invalid option'));

        // Dedup: check if already voted (this option)
        if ($user_id) {
            $existing = IJL_db_query_row("SELECT id FROM poll_votes
                                           WHERE poll_id = $poll_id AND option_id = $option_id AND user_id = $user_id
                                           LIMIT 1");
            if ($existing) poll_respond(array('success' => false, 'error' => 'Already voted on this option'));
        }

        // Fingerprint (anon support)
        $fp  = isset($input['fingerprint']) ? trim($input['fingerprint']) : '';
        $fp_esc = poll_esc($fp);

        // Hash IP — never store plain IP
        $ip_hash = hash('sha256', isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '');
        $ip_esc  = poll_esc($ip_hash);

        $uid_sql = $user_id ?: 0;

        IJL_db_insert("INSERT IGNORE INTO poll_votes (poll_id, option_id, user_id, fingerprint, ip_hash, created_at)
                       VALUES ($poll_id, $option_id, $uid_sql, '$fp_esc', '$ip_esc', NOW())");

        // Increment counters
        IJL_db_update("UPDATE poll_options SET vote_count = vote_count + 1 WHERE id = $option_id");
        IJL_db_update("UPDATE polls SET vote_count = vote_count + 1 WHERE id = $poll_id");

        // Return updated results
        $opts = IJL_db_query_all("SELECT id, encrypted_text, vote_count FROM poll_options
                                   WHERE poll_id = $poll_id ORDER BY sort_order ASC");
        $total = (int)IJL_db_query_value("SELECT vote_count FROM polls WHERE id = $poll_id");
        $results = array();
        foreach ($opts as $o) {
            $cnt = (int)$o['vote_count'];
            $results[] = array(
                'id'         => (int)$o['id'],
                'text'       => IJL_decrypt($o['encrypted_text']),
                'vote_count' => $cnt,
                'percent'    => $total > 0 ? round(($cnt / $total) * 100, 1) : 0,
            );
        }

        poll_respond(array('success' => true, 'results' => $results, 'total' => $total));
        break;

    // =========================================================================
    // RESULTS
    // =========================================================================
    case 'results':
        $poll_id = (int)(isset($input['poll_id']) ? $input['poll_id'] : 0);
        $slug    = isset($input['slug']) ? trim($input['slug']) : '';
        $where   = $slug ? "slug = '" . poll_esc($slug) . "'" : "id = $poll_id";

        $poll = IJL_db_query_row("SELECT id, vote_count, encrypted_question FROM polls WHERE $where LIMIT 1");
        if (!$poll) poll_respond(array('success' => false, 'error' => 'Poll not found'));

        $pid   = (int)$poll['id'];
        $total = (int)$poll['vote_count'];
        $opts  = IJL_db_query_all("SELECT id, encrypted_text, vote_count FROM poll_options
                                    WHERE poll_id = $pid ORDER BY vote_count DESC");

        $results = array();
        foreach ($opts as $o) {
            $cnt = (int)$o['vote_count'];
            $results[] = array(
                'id'         => (int)$o['id'],
                'text'       => IJL_decrypt($o['encrypted_text']),
                'vote_count' => $cnt,
                'percent'    => $total > 0 ? round(($cnt / $total) * 100, 1) : 0,
            );
        }

        poll_respond(array(
            'success'  => true,
            'question' => IJL_decrypt($poll['encrypted_question']),
            'total'    => $total,
            'results'  => $results,
        ));
        break;

    // =========================================================================
    // LIST
    // =========================================================================
    case 'list':
        $context = isset($input['context']) ? trim($input['context']) : '';
        $limit   = min((int)(isset($input['limit']) ? $input['limit'] : 20), 100);
        $offset  = (int)(isset($input['offset']) ? $input['offset'] : 0);
        $where   = "is_active = 1";
        if ($context) $where .= " AND context = '" . poll_esc($context) . "'";

        $rows = IJL_db_query_all("SELECT id, slug, encrypted_question, context,
                                         vote_count, is_featured, ends_at, created_at
                                   FROM polls WHERE $where
                                   ORDER BY is_featured DESC, created_at DESC
                                   LIMIT $limit OFFSET $offset");

        $polls = array();
        if (!is_array($rows)) $rows = array();

        foreach ($rows as $r) {
            $polls[] = array(
                'id'         => (int)$r['id'],
                'slug'       => $r['slug'],
                'question'   => IJL_decrypt($r['encrypted_question']),
                'context'    => $r['context'],
                'vote_count' => (int)$r['vote_count'],
                'is_featured'=> (int)$r['is_featured'],
                'ends_at'    => $r['ends_at'],
                'created_at' => $r['created_at'],
            );
        }

        $total_count = (int)IJL_db_query_value("SELECT COUNT(*) FROM polls WHERE $where");
        poll_respond(array('success' => true, 'polls' => $polls, 'total' => $total_count));
        break;

    // =========================================================================
    // DELETE
    // =========================================================================
    case 'delete':
        if (!$user_id) poll_respond(array('success' => false, 'error' => 'Login required'));
        $poll_id = (int)(isset($input['poll_id']) ? $input['poll_id'] : 0);
        if (!$poll_id) poll_respond(array('success' => false, 'error' => 'poll_id required'));

        $poll = IJL_db_query_row("SELECT id, user_id FROM polls WHERE id = $poll_id LIMIT 1");
        if (!$poll) poll_respond(array('success' => false, 'error' => 'Not found'));
        if ($poll['user_id'] != $user_id && !$is_admin)
            poll_respond(array('success' => false, 'error' => 'Access denied'));

        IJL_db_delete("DELETE FROM poll_votes   WHERE poll_id = $poll_id");
        IJL_db_delete("DELETE FROM poll_options WHERE poll_id = $poll_id");
        IJL_db_delete("DELETE FROM polls        WHERE id      = $poll_id");
        poll_respond(array('success' => true));
        break;

    // =========================================================================
    // UPDATE
    // =========================================================================
    case 'update':
        if (!$user_id) poll_respond(array('success' => false, 'error' => 'Login required'));
        $poll_id  = (int)(isset($input['poll_id']) ? $input['poll_id'] : 0);
        if (!$poll_id) poll_respond(array('success' => false, 'error' => 'poll_id required'));

        $poll = IJL_db_query_row("SELECT id, user_id FROM polls WHERE id = $poll_id LIMIT 1");
        if (!$poll || ($poll['user_id'] != $user_id && !$is_admin))
            poll_respond(array('success' => false, 'error' => 'Access denied'));

        $sets = array();
        if (isset($input['question'])) {
            $sets[] = "encrypted_question = '" . poll_esc(IJL_encrypt(trim($input['question']))) . "'";
        }
        if (isset($input['context']))    $sets[] = "context = '"    . poll_esc(trim($input['context']))    . "'";
        if (isset($input['is_active']))  $sets[] = "is_active = "   . (int)$input['is_active'];
        if (isset($input['is_featured'])&& $is_admin)
                                          $sets[] = "is_featured = " . (int)$input['is_featured'];
        if (isset($input['ends_at']))    $sets[] = "ends_at = '"    . poll_esc(trim($input['ends_at']))    . "'";

        if (!empty($sets)) {
            $sets[] = "updated_at = NOW()";
            IJL_db_update("UPDATE polls SET " . implode(', ', $sets) . " WHERE id = $poll_id");
        }

        poll_respond(array('success' => true));
        break;

    // =========================================================================
    // MY_POLLS
    // =========================================================================
    case 'my_polls':
        if (!$user_id) poll_respond(array('success' => false, 'error' => 'Login required'));

        $rows = IJL_db_query_all("SELECT id, slug, encrypted_question, context,
                                         vote_count, is_active, created_at
                                   FROM polls WHERE user_id = $user_id
                                   ORDER BY created_at DESC LIMIT 50");

        $polls = array();
        foreach ($rows as $r) {
            $polls[] = array(
                'id'         => (int)$r['id'],
                'slug'       => $r['slug'],
                'question'   => IJL_decrypt($r['encrypted_question']),
                'context'    => $r['context'],
                'vote_count' => (int)$r['vote_count'],
                'is_active'  => (int)$r['is_active'],
                'created_at' => $r['created_at'],
            );
        }

        poll_respond(array('success' => true, 'polls' => $polls));
        break;

    // =========================================================================
    // FEATURED — for widget injection
    // =========================================================================
    case 'featured':
        $context = isset($input['context']) ? trim($input['context']) : '';
        $where   = "is_active = 1 AND is_featured = 1";
        if ($context) $where .= " AND (context = '" . poll_esc($context) . "' OR context = 'general')";
        $where .= " AND (ends_at IS NULL OR ends_at > NOW())";

        $row = IJL_db_query_row("SELECT id, slug, encrypted_question, context, vote_count
                                  FROM polls WHERE $where
                                  ORDER BY vote_count DESC LIMIT 1");

        if (!$row) {
            // Fall back to most recent active poll
            $row = IJL_db_query_row("SELECT id, slug, encrypted_question, context, vote_count
                                      FROM polls WHERE is_active = 1
                                      ORDER BY created_at DESC LIMIT 1");
        }

        if (!$row) poll_respond(array('success' => true, 'poll' => null));

        $pid  = (int)$row['id'];
        $opts = IJL_db_query_all("SELECT id, encrypted_text, vote_count FROM poll_options
                                   WHERE poll_id = $pid ORDER BY sort_order ASC");
        $options = array();
        foreach ($opts as $o) {
            $options[] = array(
                'id'         => (int)$o['id'],
                'text'       => IJL_decrypt($o['encrypted_text']),
                'vote_count' => (int)$o['vote_count'],
            );
        }

        poll_respond(array(
            'success' => true,
            'poll' => array(
                'id'         => $pid,
                'slug'       => $row['slug'],
                'question'   => IJL_decrypt($row['encrypted_question']),
                'options'    => $options,
                'vote_count' => (int)$row['vote_count'],
            )
        ));
        break;

    // =========================================================================
    // TRACK_EMBED
    // =========================================================================
    case 'track_embed':
        $poll_id = (int)(isset($input['poll_id']) ? $input['poll_id'] : 0);
        if ($poll_id) {
            IJL_db_update("UPDATE polls SET embed_count = embed_count + 1 WHERE id = $poll_id");
        }
        poll_respond(array('success' => true));
        break;

    default:
        poll_respond(array('success' => false, 'error' => 'Unknown action: ' . $action));
        break;
}