<?php
/**
 * Booking plugin — bootstrap.
 *
 * Registers admin nav, dashboard widget, public route, customer
 * dashboard widget (upcoming + past appointments), and a cron
 * handler for 24h + 1h reminder emails.
 */

require_once __DIR__ . '/BookingAPI.php';

class Booking extends Plugin {

    public function boot(): void {
        Hook::addFilter('admin_nav_items',           [$this, 'addAdminNav']);
        Hook::addFilter('admin_dashboard_widgets',   [$this, 'addAdminDashboardWidget']);
        Hook::addFilter('customer_dashboard_widgets',[$this, 'addCustomerDashboardWidget']);
        Hook::addFilter('public_routes',             [$this, 'addPublicRoutes']);
        Hook::addAction('frequent_cron',             [$this, 'sendReminders']);
    }

    public function addAdminNav(array $items): array {
        if (!Auth::can('booking.view') && !Auth::isSuperAdmin()) return $items;

        $items[] = ['slug' => 'booking',              'label' => __('booking', 'Booking'),
                    'href' => $this->url('admin/index.php'),
                    'icon' => 'calendar',  'order' => 600, 'group' => 'booking'];
        $items[] = ['slug' => 'booking-appointments', 'label' => __('booking_appointments', 'Appointments'),
                    'href' => $this->url('admin/appointments.php'),
                    'icon' => 'clipboard-list', 'perm' => 'booking.view', 'order' => 601, 'group' => 'booking'];
        $items[] = ['slug' => 'booking-services',     'label' => __('booking_services', 'Services'),
                    'href' => $this->url('admin/services.php'),
                    'icon' => 'tag', 'perm' => 'booking.manage_services', 'order' => 602, 'group' => 'booking'];
        $items[] = ['slug' => 'booking-providers',    'label' => __('booking_providers', 'Providers'),
                    'href' => $this->url('admin/providers.php'),
                    'icon' => 'users', 'perm' => 'booking.manage_providers', 'order' => 603, 'group' => 'booking'];
        return $items;
    }

    public function addPublicRoutes(array $routes): array {
        $routes['book'] = [
            'handler' => $this->dir('public/router.php'),
            'methods' => ['GET', 'POST'],
        ];
        return $routes;
    }

    public function addAdminDashboardWidget(array $widgets): array {
        if (!Auth::can('booking.view')) return $widgets;
        $tid = current_tenant_id();
        try {
            $today = (int) Database::value(
                "SELECT COUNT(*) FROM booking_appointments
                  WHERE tenant_id = ? AND status='confirmed'
                    AND DATE(starts_at) = CURDATE()", [$tid]);
            $week  = (int) Database::value(
                "SELECT COUNT(*) FROM booking_appointments
                  WHERE tenant_id = ? AND status='confirmed'
                    AND starts_at >= NOW() AND starts_at <= NOW() + INTERVAL 7 DAY", [$tid]);
            $services = (int) Database::value(
                "SELECT COUNT(*) FROM booking_services
                  WHERE tenant_id = ? AND is_active=1", [$tid]);
        } catch (\Throwable $e) {
            return $widgets;
        }

        ob_start(); ?>
        <div class="card">
            <div class="card-header"><h2><?= __('booking', 'Booking') ?></h2></div>
            <div class="stat-grid">
                <div class="stat">
                    <div class="stat-label">Today</div>
                    <div class="stat-value"><?= $today ?></div>
                </div>
                <div class="stat">
                    <div class="stat-label">Next 7 days</div>
                    <div class="stat-value"><?= $week ?></div>
                </div>
                <div class="stat">
                    <div class="stat-label">Active services</div>
                    <div class="stat-value"><?= $services ?></div>
                </div>
            </div>
            <div class="mt-2">
                <a href="<?= e($this->url('admin/appointments.php')) ?>" class="btn btn-sm">View appointments →</a>
            </div>
        </div>
        <?php
        $widgets[] = ob_get_clean();
        return $widgets;
    }

    public function addCustomerDashboardWidget(array $widgets): array {
        $cid = Auth::customerId();
        if ($cid === null) return $widgets;

        try {
            $upcoming = Database::rows(
                "SELECT a.*, s.name AS service_name, p.name AS provider_name
                   FROM booking_appointments a
                   JOIN booking_services  s ON s.id = a.service_id
                   JOIN booking_providers p ON p.id = a.provider_id
                  WHERE a.customer_id = ? AND a.status = 'confirmed'
                    AND a.starts_at >= NOW()
               ORDER BY a.starts_at LIMIT 5",
                [$cid]
            );
        } catch (\Throwable $e) {
            return $widgets;
        }
        if (!$upcoming) return $widgets;

        ob_start(); ?>
        <div class="card">
            <div class="card-header"><h2>Upcoming appointments</h2></div>
            <ul class="kv-list">
                <?php foreach ($upcoming as $a): ?>
                    <li class="kv-row">
                        <span class="kv-label">
                            <strong style="color:var(--text);"><?= e($a['service_name']) ?></strong><br>
                            <span class="text-xs"><?= e($a['provider_name']) ?> · ref <code><?= e($a['ref']) ?></code></span>
                        </span>
                        <span class="kv-value">
                            <?= e(date('j M Y, H:i', strtotime($a['starts_at']))) ?>
                        </span>
                    </li>
                <?php endforeach; ?>
            </ul>
        </div>
        <?php
        $widgets[] = ob_get_clean();
        return $widgets;
    }

    /**
     * Send 24h + 1h reminders. Idempotent — flags on each appointment
     * record so we never send twice. Designed to be called every
     * ~5 minutes; cheap if nothing's due.
     */
    public function sendReminders(): void {
        try {
            // 24h window: due in (24h ±15m)
            $rows24 = Database::rows(
                "SELECT a.*, s.name AS service_name, p.name AS provider_name
                   FROM booking_appointments a
                   JOIN booking_services  s ON s.id = a.service_id
                   JOIN booking_providers p ON p.id = a.provider_id
                  WHERE a.status='confirmed' AND a.reminder_24h_sent=0
                    AND a.starts_at >  NOW() + INTERVAL 23 HOUR + INTERVAL 45 MINUTE
                    AND a.starts_at <= NOW() + INTERVAL 24 HOUR + INTERVAL 15 MINUTE"
            );
            foreach ($rows24 as $a) {
                BookingAPI::sendReminder($a, '24 hours');
                Database::update('booking_appointments', ['reminder_24h_sent' => 1], 'id = ?', [$a['id']]);
            }

            // 1h window: due in (1h ±10m)
            $rows1 = Database::rows(
                "SELECT a.*, s.name AS service_name, p.name AS provider_name
                   FROM booking_appointments a
                   JOIN booking_services  s ON s.id = a.service_id
                   JOIN booking_providers p ON p.id = a.provider_id
                  WHERE a.status='confirmed' AND a.reminder_1h_sent=0
                    AND a.starts_at >  NOW() + INTERVAL 50 MINUTE
                    AND a.starts_at <= NOW() + INTERVAL 70 MINUTE"
            );
            foreach ($rows1 as $a) {
                BookingAPI::sendReminder($a, '1 hour');
                Database::update('booking_appointments', ['reminder_1h_sent' => 1], 'id = ?', [$a['id']]);
            }
        } catch (\Throwable $e) {
            slate_log('Booking: reminder cron failed: ' . $e->getMessage(), 'error');
        }
    }
}
