<?php
require __DIR__ . '/bootstrap.php';

use App\Core\Auth;
use App\Core\Csrf;
use App\Core\Database;
use App\Core\Response;
use App\Core\Security;
use App\Services\CouponService;

$pdo = Database::connection();
$input = request_input();
$method = $_SERVER['REQUEST_METHOD'];
$action = $input['action'] ?? 'admin';
$user = Auth::requireUser();

function pyrk_can_manage_coupons(?array $user): void
{
    if (!$user || !Auth::hasPermission('rewards.manage', $user)) {
        Response::error('You do not have permission to manage coupons.', 403);
    }
}

function pyrk_coupon_datetime(?string $value): ?string
{
    $value = trim((string)$value);
    if ($value === '') return null;
    return str_replace('T', ' ', $value);
}

function pyrk_coupon_payload(array $input): array
{
    $svc = new CouponService();
    $code = $svc->normalizeCode((string)($input['code'] ?? ''));
    if ($code === '') Response::error('Coupon code is required.');

    $type = strtolower(trim((string)($input['discount_type'] ?? 'percent')));
    if (!in_array($type, ['percent', 'fixed'], true)) {
        $type = 'percent';
    }

    $value = (float)str_replace(',', '', (string)($input['discount_value'] ?? '0'));
    if ($value <= 0) Response::error('Discount value must be greater than 0.');
    if ($type === 'percent' && $value > 100) Response::error('Percentage coupon cannot be more than 100%.');

    $currency = strtoupper(trim((string)($input['currency'] ?? 'LBP')));
    if (!in_array($currency, ['LBP', 'USD', 'EUR'], true)) {
        $currency = 'LBP';
    }

    $status = strtolower(trim((string)($input['status'] ?? 'active')));
    if (!in_array($status, ['active', 'inactive'], true)) {
        $status = 'active';
    }

    $validFrom = pyrk_coupon_datetime($input['valid_from'] ?? null);
    $validUntil = pyrk_coupon_datetime($input['valid_until'] ?? null);
    if ($validFrom && $validUntil && strtotime($validFrom) > strtotime($validUntil)) {
        Response::error('Valid from cannot be after valid until.');
    }

    $maxUsesRaw = trim((string)($input['max_uses'] ?? ''));
    $maxUses = $maxUsesRaw === '' ? null : max(0, (int)$maxUsesRaw);
    $maxUsesPerUser = max(1, (int)($input['max_uses_per_user'] ?? 1));
    $minWalkAmount = max(0, (float)str_replace(',', '', (string)($input['min_walk_amount'] ?? '0')));

    return [
        'code' => $code,
        'description' => trim((string)($input['description'] ?? '')),
        'discount_type' => $type,
        'discount_value' => $value,
        'currency' => $currency,
        'valid_from' => $validFrom,
        'valid_until' => $validUntil,
        'max_uses' => $maxUses,
        'max_uses_per_user' => $maxUsesPerUser,
        'min_walk_amount' => $minWalkAmount,
        'status' => $status,
    ];
}

if ($method === 'GET' && $action === 'validate') {
    $walkId = (int)($input['walk_id'] ?? 0);
    $code = (string)($input['code'] ?? '');
    if (!$walkId) Response::error('Missing walk id.');
    try {
        $data = (new CouponService())->validateForWalk((int)$user['id'], $walkId, $code);
        Response::ok($data, 'Coupon applied.');
    } catch (Throwable $e) {
        Response::error($e->getMessage());
    }
}

if ($method === 'GET') {
    pyrk_can_manage_coupons($user);

    $coupons = $pdo->query('SELECT c.*, u.full_name AS created_by_name, (SELECT COUNT(*) FROM coupon_redemptions cr WHERE cr.coupon_id = c.id) AS used_count, (SELECT COALESCE(SUM(cr.discount_amount),0) FROM coupon_redemptions cr WHERE cr.coupon_id = c.id) AS total_discount FROM coupons c LEFT JOIN users u ON u.id = c.created_by ORDER BY c.created_at DESC, c.id DESC')->fetchAll(PDO::FETCH_ASSOC);
    $redemptions = $pdo->query('SELECT cr.*, c.code, c.discount_type, u.full_name, u.mobile, u.email, w.title AS walk_title FROM coupon_redemptions cr JOIN coupons c ON c.id = cr.coupon_id JOIN users u ON u.id = cr.user_id JOIN walks w ON w.id = cr.walk_id ORDER BY cr.redeemed_at DESC, cr.id DESC LIMIT 200')->fetchAll(PDO::FETCH_ASSOC);
    Response::ok(['coupons' => $coupons, 'redemptions' => $redemptions]);
}

if ($method === 'POST' && $action === 'save') {
    pyrk_can_manage_coupons($user);
    Csrf::validateFromRequest();

    $data = pyrk_coupon_payload($input);
    $id = (int)($input['id'] ?? 0);

    try {
        if ($id > 0) {
            $beforeStmt = $pdo->prepare('SELECT * FROM coupons WHERE id = ? LIMIT 1');
            $beforeStmt->execute([$id]);
            $before = $beforeStmt->fetch(PDO::FETCH_ASSOC);
            if (!$before) Response::error('Coupon not found.', 404);

            $stmt = $pdo->prepare('UPDATE coupons SET code = ?, description = ?, discount_type = ?, discount_value = ?, currency = ?, valid_from = ?, valid_until = ?, max_uses = ?, max_uses_per_user = ?, min_walk_amount = ?, status = ?, updated_at = NOW() WHERE id = ?');
            $stmt->execute([$data['code'], $data['description'], $data['discount_type'], $data['discount_value'], $data['currency'], $data['valid_from'], $data['valid_until'], $data['max_uses'], $data['max_uses_per_user'], $data['min_walk_amount'], $data['status'], $id]);
            Security::audit((int)$user['id'], 'coupon_updated', 'coupons', $id, ['code' => $data['code']], $before);
            Response::ok(['coupon_id' => $id], 'Coupon updated.');
        }

        $stmt = $pdo->prepare('INSERT INTO coupons (code, description, discount_type, discount_value, currency, valid_from, valid_until, max_uses, max_uses_per_user, min_walk_amount, status, created_by, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())');
        $stmt->execute([$data['code'], $data['description'], $data['discount_type'], $data['discount_value'], $data['currency'], $data['valid_from'], $data['valid_until'], $data['max_uses'], $data['max_uses_per_user'], $data['min_walk_amount'], $data['status'], (int)$user['id']]);
        $newId = (int)$pdo->lastInsertId();
        Security::audit((int)$user['id'], 'coupon_created', 'coupons', $newId, ['code' => $data['code']]);
        Response::ok(['coupon_id' => $newId], 'Coupon created.');
    } catch (Throwable $e) {
        Response::error('Could not save coupon: ' . $e->getMessage());
    }
}

if ($method === 'POST' && $action === 'deactivate') {
    pyrk_can_manage_coupons($user);
    Csrf::validateFromRequest();
    $id = (int)($input['id'] ?? 0);
    if (!$id) Response::error('Missing coupon id.');
    $pdo->prepare('UPDATE coupons SET status = "inactive", updated_at = NOW() WHERE id = ?')->execute([$id]);
    Security::audit((int)$user['id'], 'coupon_deactivated', 'coupons', $id);
    Response::ok([], 'Coupon deactivated.');
}

Response::error('Unsupported coupon action.', 404);
