<?php
/**
 * handlers/vouchers_handler.php
 * Handles all POST actions for vouchers.php and users.php
 * Actions: release, bulk_release, revoke, bulk_revoke, delete_customer
 *
 * Expects: $conn, $flash, $flashType, $search to be defined by the caller.
 * Sets:    $flash, $flashType on completion.
 */

if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['action'])) return;

require_admin_role();
csrf_verify();

// ── Helper: count how many times a user has claimed a template voucher ────────
function countUserTemplateClaims(mysqli $conn, int $customerId, int $voucherId): int {
    $q = $conn->prepare("
        SELECT COUNT(*) c
        FROM voucher_claims vc
        JOIN vouchers v ON vc.voucher_id = v.id
        WHERE vc.customer_id = ?
          AND (v.id = ? OR v.parent_voucher_id = ?)
    ");
    $q->bind_param('iii', $customerId, $voucherId, $voucherId);
    $q->execute();
    $count = (int)$q->get_result()->fetch_assoc()['c'];
    $q->close();
    return $count;
}

$action = $_POST['action'];

// ── Release single voucher to one user ────────────────────────────────────────
if ($action === 'release') {
    $custId    = (int)($_POST['customer_id'] ?? 0);
    $voucherId = (int)($_POST['voucher_id']  ?? 0);

    $vInfo = $conn->prepare('SELECT max_per_user, event_name FROM vouchers WHERE id=? AND parent_voucher_id IS NULL');
    $vInfo->bind_param('i', $voucherId);
    $vInfo->execute();
    $voucher = $vInfo->get_result()->fetch_assoc();
    $vInfo->close();

    if (!$voucher) {
        $flash = 'Voucher not found.'; $flashType = 'error';
    } else {
        $alreadyClaimed = countUserTemplateClaims($conn, $custId, $voucherId);
        if ($alreadyClaimed >= $voucher['max_per_user']) {
            $flash     = "User already has the maximum claims ({$voucher['max_per_user']}) for \"{$voucher['event_name']}\".";
            $flashType = 'error';
        } else {
            $targetId = clone_voucher_for_user($conn, $voucherId);
            if (!$targetId) {
                $flash = 'Could not generate unique code. Try again.'; $flashType = 'error';
            } else {
                $ins = $conn->prepare('INSERT INTO voucher_claims (customer_id, voucher_id, status) VALUES (?, ?, "claimed")');
                $ins->bind_param('ii', $custId, $targetId);
                $ins->execute();
                $ins->close();
                $flash = "Voucher \"{$voucher['event_name']}\" released to user successfully.";
            }
        }
    }
}

// ── Bulk release one voucher to multiple users ────────────────────────────────
if ($action === 'bulk_release') {
    $voucherId   = (int)($_POST['voucher_id'] ?? 0);
    $customerIds = isset($_POST['customer_ids']) ? array_filter(array_map('intval', $_POST['customer_ids'])) : [];

    $vInfo = $conn->prepare('SELECT max_per_user, event_name FROM vouchers WHERE id=? AND parent_voucher_id IS NULL');
    $vInfo->bind_param('i', $voucherId);
    $vInfo->execute();
    $voucher = $vInfo->get_result()->fetch_assoc();
    $vInfo->close();

    if (!$voucher || empty($customerIds)) {
        $flash = 'Invalid voucher or no users selected.'; $flashType = 'error';
    } else {
        $released = 0; $skipped = 0;
        foreach ($customerIds as $cId) {
            $used = countUserTemplateClaims($conn, $cId, $voucherId);
            if ($used >= $voucher['max_per_user']) { $skipped++; continue; }

            $targetId = clone_voucher_for_user($conn, $voucherId);
            if (!$targetId) { $skipped++; continue; }

            $ins = $conn->prepare('INSERT INTO voucher_claims (customer_id, voucher_id, status) VALUES (?, ?, "claimed")');
            $ins->bind_param('ii', $cId, $targetId);
            $ins->execute();
            $ins->close();
            $released++;
        }
        $flash = "Released \"{$voucher['event_name']}\" to {$released} user(s).";
        if ($skipped) $flash .= " {$skipped} skipped (already at limit).";
        if ($released === 0) $flashType = 'error';
    }
}

// ── Revoke a single claim (any status) ───────────────────────────────────────
if ($action === 'revoke') {
    $claimId = (int)($_POST['claim_id'] ?? 0);

    $lookup = $conn->prepare('SELECT voucher_id, status FROM voucher_claims WHERE id=?');
    $lookup->bind_param('i', $claimId);
    $lookup->execute();
    $claimRow = $lookup->get_result()->fetch_assoc();
    $lookup->close();

    if (!$claimRow) {
        $flash = 'Claim not found.'; $flashType = 'error';
    } else {
        $del = $conn->prepare('DELETE FROM voucher_claims WHERE id=?');
        $del->bind_param('i', $claimId);
        $del->execute();

        if ($del->affected_rows > 0) {
            $hv = $conn->prepare("UPDATE vouchers SET status='revoked', is_public=0 WHERE id=? AND parent_voucher_id IS NOT NULL");
            $hv->bind_param('i', $claimRow['voucher_id']);
            $hv->execute();
            $hv->close();
            $flash = $claimRow['status'] === 'redeemed'
                ? 'Redeemed claim revoked and voucher hidden.'
                : 'Pending claim revoked and voucher hidden.';
        } else {
            $flash = 'Could not revoke claim.'; $flashType = 'error';
        }
        $del->close();
    }
}

// ── Bulk revoke multiple claims ───────────────────────────────────────────────
if ($action === 'bulk_revoke') {
    $claimIds = isset($_POST['claim_ids']) ? array_filter(array_map('intval', $_POST['claim_ids'])) : [];

    if (empty($claimIds)) {
        $flash = 'No claims selected.'; $flashType = 'error';
    } else {
        $revoked = 0; $failed = 0;
        foreach ($claimIds as $cid) {
            $lk = $conn->prepare('SELECT voucher_id FROM voucher_claims WHERE id=?');
            $lk->bind_param('i', $cid);
            $lk->execute();
            $lkRow = $lk->get_result()->fetch_assoc();
            $lk->close();

            $dq = $conn->prepare('DELETE FROM voucher_claims WHERE id=?');
            $dq->bind_param('i', $cid);
            $dq->execute();

            if ($dq->affected_rows > 0) {
                $revoked++;
                if ($lkRow) {
                    $hv2 = $conn->prepare("UPDATE vouchers SET status='revoked', is_public=0 WHERE id=? AND parent_voucher_id IS NOT NULL");
                    $hv2->bind_param('i', $lkRow['voucher_id']);
                    $hv2->execute();
                    $hv2->close();
                }
            } else {
                $failed++;
            }
            $dq->close();
        }
        $flash = "Revoked {$revoked} claim(s).";
        if ($failed)    $flash    .= " {$failed} could not be revoked.";
        if ($revoked === 0) $flashType = 'error';
    }
}

// ── Delete a customer ─────────────────────────────────────────────────────────
if ($action === 'delete_customer') {
    $custId = (int)($_POST['customer_id'] ?? 0);
    if ($custId <= 0) {
        $flash = 'Invalid customer.'; $flashType = 'error';
    } else {
        $del = $conn->prepare('DELETE FROM customers WHERE id=? LIMIT 1');
        $del->bind_param('i', $custId);
        $del->execute();
        if ($del->affected_rows > 0) {
            $redirectQ = trim($_POST['search_q'] ?? $search);
            header('Location: vouchers.php' . ($redirectQ !== '' ? '?q=' . urlencode($redirectQ) : ''));
            exit();
        }
        $flash = 'Customer could not be deleted.'; $flashType = 'error';
    }
}

// ── Add new customer ──────────────────────────────────────────────────────────
if ($action === 'add_customer') {
    if (!$isAdmin) {
        $flash = 'Admin access required.'; $flashType = 'error';
    } else {
        $name  = substr(trim($_POST['new_name']  ?? ''), 0, 100);
        $dial  = preg_replace('/\D/', '', trim($_POST['new_dial'] ?? '60'));
        $local = preg_replace('/\D/', '', trim($_POST['new_phone'] ?? ''));

        // Strip leading zero — match the same format as user self-registration
        $localStripped = ltrim($local, '0');
        $fullPhone     = $dial . $localStripped;

        if (empty($name)) {
            $flash = 'Name is required.'; $flashType = 'error';
        } elseif (strlen($local) < 7 || strlen($local) > 15) {
            $flash = 'Please enter a valid phone number.'; $flashType = 'error';
        } else {
            // Duplicate check
            $ck = $conn->prepare('SELECT id FROM customers WHERE phone=? LIMIT 1');
            $ck->bind_param('s', $fullPhone);
            $ck->execute();
            $ck->store_result();
            $exists = $ck->num_rows > 0;
            $ck->close();

            if ($exists) {
                $flash = "A user with phone {$fullPhone} already exists."; $flashType = 'error';
            } else {
                $ins = $conn->prepare('INSERT INTO customers (name, phone) VALUES (?, ?)');
                $ins->bind_param('ss', $name, $fullPhone);
                $ok  = $ins->execute();
                $newId = $conn->insert_id;
                $ins->close();

                if ($ok) {
                    header('Location: users.php?uid=' . $newId . '&added=1');
                    exit();
                }
                $flash = 'Could not create user. Please try again.'; $flashType = 'error';
            }
        }
    }
}

