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

use App\Core\Auth;
use App\Core\Database;
use App\Core\Response;
use App\Core\Security;

$user = Auth::requireUser();
if (!Auth::hasPermission('notifications.manage', $user)
    && !Auth::hasPermission('walks.manage', $user)
    && !Auth::hasPermission('walks.edit', $user)) {
    Response::error('You do not have permission to manage WhatsApp message presets.', 403);
}

$pdo = Database::connection();
$input = request_input();
$action = (string)($input['action'] ?? 'list');

function pyrk_wa_preset_table_exists(PDO $pdo): bool
{
    try {
        $stmt = $pdo->prepare('SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ?');
        $stmt->execute(['whatsapp_message_presets']);
        return (int)$stmt->fetchColumn() > 0;
    } catch (Throwable) {
        return false;
    }
}

function pyrk_wa_preset_use_cases(): array
{
    return [
        'open_walk' => 'New open walk',
        'invitation_only' => 'Invitation-only walk',
        'walk_update' => 'Walk update',
        'reminder' => 'Reminder',
        'cancelled' => 'Postponed / cancelled',
        'custom' => 'Custom',
    ];
}

function pyrk_wa_preset_allowed_tokens(): array
{
    return [
        '{first_name}' => 'Member first name',
        '{last_name}' => 'Member last name',
        '{full_name}' => 'Member full name',
        '{walk_title}' => 'Walk title',
        '{walk_date}' => 'Walk date',
        '{walk_time}' => 'Walk start time',
        '{route_name}' => 'Route name',
        '{distance_km}' => 'Route distance in KM',
        '{walk_link}' => 'Direct walk link',
    ];
}

function pyrk_wa_preset_unknown_tokens(string $value): array
{
    preg_match_all('/\{[a-zA-Z0-9_]+\}|\$[a-zA-Z0-9_]+\$/', $value, $matches);
    $allowed = array_keys(pyrk_wa_preset_allowed_tokens());
    foreach (array_keys(pyrk_wa_preset_allowed_tokens()) as $token) {
        $allowed[] = '$' . trim($token, '{}') . '$';
    }
    return array_values(array_diff(array_unique($matches[0] ?? []), $allowed));
}

function pyrk_wa_preset_clean_text(string $value, int $maxLength): string
{
    $value = trim(str_replace(["\r\n", "\r"], "\n", $value));
    if (function_exists('mb_substr')) return mb_substr($value, 0, $maxLength, 'UTF-8');
    return substr($value, 0, $maxLength);
}

function pyrk_wa_preset_rows(PDO $pdo, bool $activeOnly = false): array
{
    $where = $activeOnly ? 'WHERE is_active = 1' : '';
    $stmt = $pdo->query("SELECT id, preset_name, use_case, headline_template, message_template, audience_default, is_default, is_active, sort_order, created_by, updated_by, created_at, updated_at
        FROM whatsapp_message_presets
        {$where}
        ORDER BY is_active DESC, sort_order ASC, preset_name ASC, id ASC");
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

function pyrk_wa_preset_preview(string $headline, string $message): array
{
    $sample = [
        '{first_name}' => 'Alex',
        '{last_name}' => 'Walker',
        '{full_name}' => 'Alex Walker',
        '{walk_title}' => 'Beirut Sunrise Walk',
        '{walk_date}' => date('d/m/Y', strtotime('+7 days')),
        '{walk_time}' => '07:00',
        '{route_name}' => 'Pyrk Waterfront Route',
        '{distance_km}' => '6.4',
        '{walk_link}' => 'https://thepyrk.com/steps/public/walk.php?id=123',
    ];
    foreach ($sample as $token => $value) {
        $sample['$' . trim($token, '{}') . '$'] = $value;
    }
    return [
        'headline' => strtr($headline, $sample),
        'message' => strtr($message, $sample),
    ];
}

if ($action === 'list' || $action === 'overview') {
    $installed = pyrk_wa_preset_table_exists($pdo);
    Response::ok([
        'installed' => $installed ? 1 : 0,
        'presets' => $installed ? pyrk_wa_preset_rows($pdo, !empty($input['active_only'])) : [],
        'use_cases' => pyrk_wa_preset_use_cases(),
        'variables' => pyrk_wa_preset_allowed_tokens(),
        'migration' => 'database/migrations/043_whatsapp_message_presets.sql',
    ]);
}

if (!pyrk_wa_preset_table_exists($pdo)) {
    Response::error('WhatsApp presets are not installed. Import database/migrations/043_whatsapp_message_presets.sql first.');
}

if ($action === 'get') {
    $id = (int)($input['id'] ?? 0);
    if ($id <= 0) Response::error('Choose a preset.');
    $stmt = $pdo->prepare('SELECT * FROM whatsapp_message_presets WHERE id = ? LIMIT 1');
    $stmt->execute([$id]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$row) Response::error('Preset not found.', 404);
    Response::ok(['preset' => $row, 'preview' => pyrk_wa_preset_preview((string)$row['headline_template'], (string)$row['message_template'])]);
}

if ($action === 'save') {
    $id = (int)($input['id'] ?? 0);
    $isNewPreset = $id <= 0;
    $name = pyrk_wa_preset_clean_text((string)($input['preset_name'] ?? ''), 120);
    $useCase = (string)($input['use_case'] ?? 'custom');
    $headline = pyrk_wa_preset_clean_text((string)($input['headline_template'] ?? ''), 180);
    $message = pyrk_wa_preset_clean_text((string)($input['message_template'] ?? ''), 4000);
    $audience = (string)($input['audience_default'] ?? 'auto');
    $isDefault = !empty($input['is_default']) ? 1 : 0;
    $isActive = array_key_exists('is_active', $input) ? (!empty($input['is_active']) ? 1 : 0) : 1;
    $sortOrder = max(0, min(9999, (int)($input['sort_order'] ?? 100)));

    $useCases = pyrk_wa_preset_use_cases();
    if ($name === '') Response::error('Preset name is required.');
    if (!isset($useCases[$useCase])) Response::error('Choose a valid preset use case.');
    if ($headline === '') Response::error('WhatsApp headline is required.');
    if ($message === '') Response::error('WhatsApp message is required.');
    if (!in_array($audience, ['auto', 'all', 'invited'], true)) Response::error('Choose a valid default audience.');

    $unknown = array_values(array_unique(array_merge(
        pyrk_wa_preset_unknown_tokens($headline),
        pyrk_wa_preset_unknown_tokens($message)
    )));
    if ($unknown) Response::error('Unknown variable(s): ' . implode(', ', $unknown) . '. Use only the variables shown in the editor.');

    if ($isDefault && !$isActive) Response::error('A default preset must be active.');

    $pdo->beginTransaction();
    try {
        if ($id > 0) {
            $exists = $pdo->prepare('SELECT id FROM whatsapp_message_presets WHERE id = ? FOR UPDATE');
            $exists->execute([$id]);
            if (!$exists->fetchColumn()) throw new RuntimeException('Preset not found.');

            $stmt = $pdo->prepare('UPDATE whatsapp_message_presets
                SET preset_name = ?, use_case = ?, headline_template = ?, message_template = ?, audience_default = ?, is_default = ?, is_active = ?, sort_order = ?, updated_by = ?, updated_at = NOW()
                WHERE id = ?');
            $stmt->execute([$name, $useCase, $headline, $message, $audience, $isDefault, $isActive, $sortOrder, (int)$user['id'], $id]);
        } else {
            $stmt = $pdo->prepare('INSERT INTO whatsapp_message_presets
                (preset_name, use_case, headline_template, message_template, audience_default, is_default, is_active, sort_order, created_by, updated_by, created_at, updated_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())');
            $stmt->execute([$name, $useCase, $headline, $message, $audience, $isDefault, $isActive, $sortOrder, (int)$user['id'], (int)$user['id']]);
            $id = (int)$pdo->lastInsertId();
        }

        if ($isDefault) {
            $unset = $pdo->prepare('UPDATE whatsapp_message_presets SET is_default = 0, updated_at = NOW() WHERE use_case = ? AND id <> ?');
            $unset->execute([$useCase, $id]);
        }

        $pdo->commit();
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        Response::error($e->getMessage() ?: 'Could not save the preset.');
    }

    try {
        Security::audit((int)$user['id'], $isNewPreset ? 'whatsapp_preset_created' : 'whatsapp_preset_saved', 'whatsapp_message_presets', $id, [
            'preset_name' => $name,
            'use_case' => $useCase,
            'is_default' => $isDefault,
            'is_active' => $isActive,
        ]);
    } catch (Throwable) {}

    $stmt = $pdo->prepare('SELECT * FROM whatsapp_message_presets WHERE id = ? LIMIT 1');
    $stmt->execute([$id]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    Response::ok(['preset' => $row, 'presets' => pyrk_wa_preset_rows($pdo)], 'WhatsApp preset saved.');
}

if ($action === 'delete') {
    $id = (int)($input['id'] ?? 0);
    if ($id <= 0) Response::error('Choose a preset to delete.');

    $pdo->beginTransaction();
    try {
        $stmt = $pdo->prepare('SELECT id, preset_name, use_case, is_default FROM whatsapp_message_presets WHERE id = ? FOR UPDATE');
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) throw new RuntimeException('Preset not found.');

        $del = $pdo->prepare('DELETE FROM whatsapp_message_presets WHERE id = ?');
        $del->execute([$id]);

        if ((int)$row['is_default'] === 1) {
            $replacement = $pdo->prepare('SELECT id FROM whatsapp_message_presets WHERE use_case = ? AND is_active = 1 ORDER BY sort_order ASC, id ASC LIMIT 1');
            $replacement->execute([(string)$row['use_case']]);
            $replacementId = (int)($replacement->fetchColumn() ?: 0);
            if ($replacementId > 0) {
                $promote = $pdo->prepare('UPDATE whatsapp_message_presets SET is_default = 1, updated_at = NOW() WHERE id = ?');
                $promote->execute([$replacementId]);
            }
        }

        $pdo->commit();
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        Response::error($e->getMessage() ?: 'Could not delete the preset.');
    }

    try {
        Security::audit((int)$user['id'], 'whatsapp_preset_deleted', 'whatsapp_message_presets', $id, [
            'preset_name' => (string)($row['preset_name'] ?? ''),
            'use_case' => (string)($row['use_case'] ?? ''),
        ]);
    } catch (Throwable) {}

    Response::ok(['presets' => pyrk_wa_preset_rows($pdo)], 'WhatsApp preset deleted.');
}

if ($action === 'preview') {
    $headline = pyrk_wa_preset_clean_text((string)($input['headline_template'] ?? ''), 180);
    $message = pyrk_wa_preset_clean_text((string)($input['message_template'] ?? ''), 4000);
    Response::ok(['preview' => pyrk_wa_preset_preview($headline, $message)]);
}

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