<?php
/**
 * Subscription Management Functions
 * LandSales Pro - Handle subscription checking, plan limits, and expiry
 */

if (!defined('APP_RUNNING')) {
    define('APP_RUNNING', true);
}

/**
 * Get user's active subscription
 */
function getActiveSubscription($user_id) {
    global $conn;

    $sql = "SELECT s.*, p.name as plan_name, p.slug as plan_slug,
                   p.max_projects, p.max_plots, p.max_agents, p.features
            FROM subscriptions s
            JOIN plans p ON s.plan_id = p.id
            WHERE s.user_id = ?
            AND s.status IN ('active', 'trial')
            AND s.expires_at >= NOW()
            ORDER BY s.expires_at DESC
            LIMIT 1";

    $stmt = $conn->prepare($sql);
    $stmt->bind_param("i", $user_id);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows > 0) {
        $subscription = $result->fetch_assoc();
        $subscription['features'] = json_decode($subscription['features'], true) ?? [];
        return $subscription;
    }

    return null;
}

/**
 * Check if user has active subscription
 */
function hasActiveSubscription($user_id) {
    return getActiveSubscription($user_id) !== null;
}

/**
 * Check if subscription is in trial
 */
function isInTrial($user_id) {
    $subscription = getActiveSubscription($user_id);
    return $subscription && $subscription['status'] === 'trial';
}

/**
 * Get days remaining in subscription
 */
function getSubscriptionDaysRemaining($user_id) {
    $subscription = getActiveSubscription($user_id);
    if (!$subscription) return 0;

    $expires = strtotime($subscription['expires_at']);
    $now = time();
    $diff = $expires - $now;

    return max(0, ceil($diff / 86400));
}

/**
 * Require active subscription - redirect if expired
 */
function requireSubscription($redirect = null) {
    requireAuth();

    $user_id = $_SESSION['user_id'];

    // Admins don't need subscription
    if (isAdmin()) return true;

    if (!hasActiveSubscription($user_id)) {
        $redirect = $redirect ?? SITE_URL . '/dashboard/settings/subscription.php?expired=1';
        header('Location: ' . $redirect);
        exit;
    }

    return true;
}

/**
 * Check plan limit for an entity
 */
function checkPlanLimit($user_id, $entity) {
    $subscription = getActiveSubscription($user_id);
    if (!$subscription) return ['allowed' => false, 'limit' => 0, 'current' => 0];

    $limit_field = "max_{$entity}";
    $limit = $subscription[$limit_field] ?? 0;

    // -1 means unlimited
    if ($limit == -1) {
        return ['allowed' => true, 'limit' => -1, 'current' => 0, 'unlimited' => true];
    }

    // Get current count
    $current = getCurrentCount($user_id, $entity);

    return [
        'allowed' => $current < $limit,
        'limit' => $limit,
        'current' => $current,
        'remaining' => max(0, $limit - $current),
        'unlimited' => false
    ];
}

/**
 * Get current count of an entity for user
 */
function getCurrentCount($user_id, $entity) {
    global $conn;

    $table = '';
    switch ($entity) {
        case 'projects':
            $table = 'projects';
            break;
        case 'plots':
            $table = 'plots';
            break;
        case 'agents':
            $table = 'agents';
            break;
        default:
            return 0;
    }

    $result = $conn->query("SELECT COUNT(*) as count FROM {$table} WHERE user_id = {$user_id}");
    $row = $result->fetch_assoc();
    return $row['count'];
}

/**
 * Check if user can create more of an entity
 */
function canCreate($user_id, $entity) {
    $check = checkPlanLimit($user_id, $entity);
    return $check['allowed'];
}

/**
 * Check if user has feature access
 */
function hasFeature($user_id, $feature) {
    $subscription = getActiveSubscription($user_id);
    if (!$subscription) return false;

    return isset($subscription['features'][$feature]) && $subscription['features'][$feature];
}

/**
 * Get all subscription plans
 */
function getAllPlans() {
    global $conn;

    $result = $conn->query("SELECT * FROM plans WHERE is_active = 1 ORDER BY sort_order ASC");
    return $result->fetch_all(MYSQLI_ASSOC);
}

/**
 * Get plan by ID
 */
function getPlanById($plan_id) {
    global $conn;

    $stmt = $conn->prepare("SELECT * FROM plans WHERE id = ?");
    $stmt->bind_param("i", $plan_id);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($row = $result->fetch_assoc()) {
        $row['features'] = json_decode($row['features'], true) ?? [];
        return $row;
    }

    return null;
}

/**
 * Get plan price by billing cycle
 */
function getPlanPrice($plan, $billing_cycle) {
    $price_field = "price_{$billing_cycle}";
    return $plan[$price_field] ?? $plan['price_monthly'];
}

/**
 * Create a new subscription
 */
function createSubscription($user_id, $plan_id, $billing_cycle, $is_trial = false) {
    global $conn;

    $plan = getPlanById($plan_id);
    if (!$plan) return false;

    $amount = getPlanPrice($plan, $billing_cycle);
    $months = billingCycleMonths($billing_cycle);

    $starts_at = date('Y-m-d H:i:s');

    if ($is_trial) {
        $status = 'trial';
        $expires_at = date('Y-m-d H:i:s', strtotime("+{TRIAL_DAYS} days"));
        $trial_ends_at = $expires_at;
    } else {
        $status = 'active';
        $expires_at = date('Y-m-d H:i:s', strtotime("+{$months} months"));
        $trial_ends_at = null;
    }

    $stmt = $conn->prepare("INSERT INTO subscriptions
        (user_id, plan_id, billing_cycle, amount, status, starts_at, expires_at, trial_ends_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)");

    $stmt->bind_param("iisdsss",
        $user_id, $plan_id, $billing_cycle, $amount, $status, $starts_at, $expires_at, $trial_ends_at
    );

    if ($stmt->execute()) {
        return $conn->insert_id;
    }

    return false;
}

/**
 * Extend subscription
 */
function extendSubscription($subscription_id, $months) {
    global $conn;

    $stmt = $conn->prepare("UPDATE subscriptions SET
        expires_at = DATE_ADD(expires_at, INTERVAL ? MONTH),
        status = 'active',
        updated_at = NOW()
        WHERE id = ?");

    $stmt->bind_param("ii", $months, $subscription_id);
    return $stmt->execute();
}

/**
 * Cancel subscription
 */
function cancelSubscription($subscription_id, $reason = null) {
    global $conn;

    $stmt = $conn->prepare("UPDATE subscriptions SET
        status = 'cancelled',
        cancelled_at = NOW(),
        cancellation_reason = ?,
        updated_at = NOW()
        WHERE id = ?");

    $stmt->bind_param("si", $reason, $subscription_id);
    return $stmt->execute();
}

/**
 * Record subscription payment
 */
function recordSubscriptionPayment($data) {
    global $conn;

    $stmt = $conn->prepare("INSERT INTO subscription_payments
        (subscription_id, user_id, amount, payment_method, reference_number, receipt_number,
         payment_date, period_start, period_end, status, notes, recorded_by)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

    $stmt->bind_param("iidssssssssi",
        $data['subscription_id'],
        $data['user_id'],
        $data['amount'],
        $data['payment_method'],
        $data['reference_number'],
        $data['receipt_number'],
        $data['payment_date'],
        $data['period_start'],
        $data['period_end'],
        $data['status'] ?? 'confirmed',
        $data['notes'],
        $data['recorded_by']
    );

    if ($stmt->execute()) {
        // Also extend the subscription
        $months = billingCycleMonths($data['billing_cycle'] ?? 'monthly');
        extendSubscription($data['subscription_id'], $months);
        return $conn->insert_id;
    }

    return false;
}

/**
 * Get subscription payment history
 */
function getSubscriptionPayments($user_id, $limit = 10) {
    global $conn;

    $stmt = $conn->prepare("SELECT sp.*, p.name as plan_name
        FROM subscription_payments sp
        JOIN subscriptions s ON sp.subscription_id = s.id
        JOIN plans p ON s.plan_id = p.id
        WHERE sp.user_id = ?
        ORDER BY sp.payment_date DESC
        LIMIT ?");

    $stmt->bind_param("ii", $user_id, $limit);
    $stmt->execute();
    return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}

/**
 * Check expired subscriptions and update status
 * This should be run by a cron job
 */
function updateExpiredSubscriptions() {
    global $conn;

    // Update expired subscriptions
    $conn->query("UPDATE subscriptions SET status = 'expired'
                  WHERE status IN ('active', 'trial') AND expires_at < NOW()");

    return $conn->affected_rows;
}

/**
 * Get subscription status label with color
 */
function subscriptionStatusBadge($status) {
    $badges = [
        'trial' => ['color' => 'info', 'label' => 'Trial'],
        'active' => ['color' => 'success', 'label' => 'Active'],
        'expired' => ['color' => 'danger', 'label' => 'Expired'],
        'cancelled' => ['color' => 'secondary', 'label' => 'Cancelled'],
        'suspended' => ['color' => 'warning', 'label' => 'Suspended']
    ];

    $badge = $badges[$status] ?? ['color' => 'secondary', 'label' => ucfirst($status)];
    return '<span class="badge bg-' . $badge['color'] . '">' . $badge['label'] . '</span>';
}

/**
 * Get usage stats for dashboard
 */
function getUsageStats($user_id) {
    $subscription = getActiveSubscription($user_id);
    if (!$subscription) {
        return null;
    }

    return [
        'projects' => checkPlanLimit($user_id, 'projects'),
        'plots' => checkPlanLimit($user_id, 'plots'),
        'agents' => checkPlanLimit($user_id, 'agents'),
        'plan' => $subscription['plan_name'],
        'expires_at' => $subscription['expires_at'],
        'days_remaining' => getSubscriptionDaysRemaining($user_id),
        'status' => $subscription['status']
    ];
}

/**
 * Get subscription summary for sidebar
 */
function getSubscriptionSummary($user_id) {
    $subscription = getActiveSubscription($user_id);

    if (!$subscription) {
        return [
            'active' => false,
            'plan' => 'No Plan',
            'status' => 'expired',
            'days_remaining' => 0,
            'message' => 'Subscription expired'
        ];
    }

    $days = getSubscriptionDaysRemaining($user_id);

    return [
        'active' => true,
        'plan' => $subscription['plan_name'],
        'status' => $subscription['status'],
        'days_remaining' => $days,
        'expires_at' => $subscription['expires_at'],
        'message' => $days > 30 ? 'Active' : ($days . ' days remaining')
    ];
}
