<?php
function setCorsHeaders() {
    $origin = getenv('FRONTEND_URL') ?: '*';
    header('Access-Control-Allow-Origin: ' . $origin);
    header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Allow-Credentials: true');
    header('Content-Type: application/json; charset=utf-8');
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        http_response_code(204); exit;
    }
}

function respond($data, $code = 200) {
    http_response_code($code);
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function error($msg, $code = 400) {
    respond(['error' => $msg], $code);
}

function getBody() {
    static $body = null;
    if ($body === null) {
        $raw  = file_get_contents('php://input');
        $body = json_decode($raw, true) ?: [];
    }
    return $body;
}

function get($key, $default = null) {
    $body = getBody();
    return $body[$key] ?? $_POST[$key] ?? $default;
}

function getAuthHeader() {
    if (!empty($_SERVER['HTTP_AUTHORIZATION']))
        return $_SERVER['HTTP_AUTHORIZATION'];
    if (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
        return $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
    if (function_exists('apache_request_headers')) {
        $h = apache_request_headers();
        if (!empty($h['Authorization'])) return $h['Authorization'];
        if (!empty($h['authorization'])) return $h['authorization'];
    }
    $env = getenv('HTTP_AUTHORIZATION');
    if ($env) return $env;
    return '';
}

function base64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
    return base64_decode(strtr($data, '-_', '+/') . str_repeat('=', 3 - (3 + strlen($data)) % 4));
}

function createJWT($payload, $secret, $expiresIn = '15m') {
    $header  = base64url_encode(json_encode(['alg'=>'HS256','typ'=>'JWT']));
    $payload['exp'] = time() + parseExpiry($expiresIn);
    $payload['iat'] = time();
    $p   = base64url_encode(json_encode($payload));
    $sig = base64url_encode(hash_hmac('sha256', "$header.$p", $secret, true));
    return "$header.$p.$sig";
}

function verifyJWT($token, $secret) {
    $parts = explode('.', $token);
    if (count($parts) !== 3) return null;
    [$header, $payload, $sig] = $parts;
    $expected = base64url_encode(hash_hmac('sha256', "$header.$payload", $secret, true));
    if (!hash_equals($expected, $sig)) return null;
    $data = json_decode(base64url_decode($payload), true);
    if (!$data || $data['exp'] < time()) return null;
    return $data;
}

function parseExpiry($str) {
    $unit = substr($str, -1);
    $val  = (int) substr($str, 0, -1);
    switch($unit) {
        case 'm': return $val * 60;
        case 'h': return $val * 3600;
        case 'd': return $val * 86400;
        default:  return 900;
    }
}

function requireAuth() {
    $header = getAuthHeader();
    if (empty($header) || stripos($header, 'Bearer ') !== 0) {
        error('No token provided', 401);
    }

    $token = substr($header, 7);
    $data  = verifyJWT($token, getenv('JWT_SECRET'));
    if (!$data) error('Invalid or expired token', 401);

    $user = queryOne('SELECT * FROM users WHERE id=? AND is_active=1', [$data['userId']]);
    if (!$user) error('User not found', 401);

    // ─── Single session enforcement ───────────
    // If token contains session token (st), verify it matches DB
    if (!empty($data['st']) && !empty($user['session_token'])) {
        if ($data['st'] !== $user['session_token']) {
            // Session was replaced by another login — kick this device out
            error('Session expired. You have been logged in from another device.', 401);
        }
    }

    return $user;
}

function requireAdmin() {
    $user = requireAuth();
    if ($user['role'] !== 'admin') error('Admin access required', 403);
    return $user;
}

function requireSubscription($user) {
    if ($user['role'] === 'admin') return;
    $active = $user['sub_end'] && strtotime($user['sub_end']) > time()
           && in_array($user['sub_status'], ['trial','active']);
    if (!$active) error('Subscription required', 403);
}

function generateOTP() {
    return str_pad(random_int(100000, 999999), 6, '0', STR_PAD_LEFT);
}

function otpExpiry() {
    $mins = (int)(getenv('OTP_EXPIRES_MINUTES') ?: 10);
    return date('Y-m-d H:i:s', time() + $mins * 60);
}

function sendOTPEmail($to, $name, $otp, $type = 'verify') {
    $subject = $type === 'reset'
        ? 'Numerology App — Password Reset Code'
        : 'Numerology App — Verify Your Email';
    $title = $type === 'reset' ? 'Reset Your Password' : 'Verify Your Email';
    $msg   = $type === 'reset' ? 'Your password reset code:' : 'Your email verification code:';
    $html  = "
<div style='font-family:Arial,sans-serif;max-width:480px;margin:0 auto;padding:20px;color:#1a2530'>
  <h1 style='color:#2563a8;font-size:24px;margin:0 0 4px'>Numerology</h1>
  <p style='color:#7a9aaa;font-size:11px;letter-spacing:.1em;text-transform:uppercase;margin:0 0 24px'>Sacred Mathematics</p>
  <h2 style='font-size:18px;margin-bottom:8px'>$title</h2>
  <p>Hi $name,</p>
  <p>$msg</p>
  <div style='background:#f0ede6;border-radius:10px;padding:20px;text-align:center;margin:20px 0'>
    <span style='font-size:36px;font-weight:bold;letter-spacing:8px;color:#2563a8'>$otp</span>
  </div>
  <p style='color:#7a9aaa;font-size:13px'>This code expires in 10 minutes. Do not share it.</p>
</div>";
    $from = getenv('EMAIL_FROM') ?: getenv('EMAIL_USER');
    $headers  = "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=UTF-8\r\n";
    $headers .= "From: $from\r\n";
    return @mail($to, $subject, $html, $headers);
}

function userResponse($u) {
    return [
        'id'            => (int)$u['id'],
        'name'          => $u['name'],
        'email'         => $u['email'],
        'phone'         => $u['phone'],
        'role'          => $u['role'],
        'emailVerified' => (bool)$u['email_verified'],
        'phoneVerified' => (bool)$u['phone_verified'],
        'subscription'  => [
            'status'    => $u['sub_status'],
            'plan'      => $u['sub_plan'],
            'startDate' => $u['sub_start'],
            'endDate'   => $u['sub_end'],
            'trialUsed' => (bool)$u['trial_used'],
        ],
        'features' => [
            'triangleCalculator' => (bool)$u['feature_triangle'],
            'numberEnergy'       => (bool)$u['feature_energy'],
        ],
        'isSubscriptionActive' => isSubActive($u),
    ];
}

function isSubActive($u) {
    if ($u['role'] === 'admin') return true;
    if (!$u['sub_end']) return false;
    return strtotime($u['sub_end']) > time()
        && in_array($u['sub_status'], ['trial','active']);
}

// ════════════════════════════════════════════════════════
// ADDED FOR USER MANAGEMENT & ROLE-BASED SYSTEM
// Verify token for User Management API
// ════════════════════════════════════════════════════════
function verifyToken($token) {
    // Use existing JWT verification
    $jwtSecret = getenv('JWT_SECRET');
    $data = verifyJWT($token, $jwtSecret);
    
    if (!$data || empty($data['userId'])) {
        return null;
    }
    
    // Get user from database
    $user = queryOne('SELECT id, email, role, is_active FROM users WHERE id=? AND is_active=1', [$data['userId']]);
    
    if (!$user) {
        return null;
    }
    
    return [
        'id' => (int)$user['id'],
        'email' => $user['email'],
        'role' => $user['role']
    ];
}
?>
