<?php

declare(strict_types=1);

namespace Admin\Controllers;

/**
 * Admin Demo Class Controller
 *
 * Manages demo class booking requests submitted from the homepage.
 * Supports listing, status updates, admin notes, and deletion.
 * Auto-creates or repairs the database table if needed.
 */
class AdminDemoClassController extends AdminController
{
    /**
     * Required columns for the demo_class_requests table.
     */
    private const TABLE_COLUMNS = [
        'id'           => 'INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
        'student_name' => 'VARCHAR(255) NOT NULL',
        'email'        => 'VARCHAR(255) NOT NULL',
        'contact'      => 'VARCHAR(20) NOT NULL',
        'batch'        => 'VARCHAR(100) DEFAULT NULL',
        'course_id'    => 'INT UNSIGNED DEFAULT NULL',
        'demo_date'    => 'DATE NOT NULL',
        'status'       => "ENUM('pending','contacted','scheduled','completed','cancelled') NOT NULL DEFAULT 'pending'",
        'admin_note'   => 'TEXT DEFAULT NULL',
        'is_read'      => 'TINYINT(1) NOT NULL DEFAULT 0',
        'created_at'   => 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP',
        'updated_at'   => 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
    ];

    /**
     * Full CREATE TABLE SQL for the demo_class_requests table.
     */
    private const CREATE_TABLE_SQL = "
        CREATE TABLE IF NOT EXISTS `demo_class_requests` (
            `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
            `student_name` VARCHAR(255) NOT NULL,
            `email` VARCHAR(255) NOT NULL,
            `contact` VARCHAR(20) NOT NULL,
            `batch` VARCHAR(100) DEFAULT NULL,
            `course_id` INT UNSIGNED DEFAULT NULL,
            `demo_date` DATE NOT NULL,
            `status` ENUM('pending','contacted','scheduled','completed','cancelled') NOT NULL DEFAULT 'pending',
            `admin_note` TEXT DEFAULT NULL,
            `is_read` TINYINT(1) NOT NULL DEFAULT 0,
            `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `idx_status` (`status`),
            KEY `idx_is_read` (`is_read`),
            KEY `idx_demo_date` (`demo_date`),
            KEY `idx_course_id` (`course_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ";

    /**
     * Ensure the demo_class_requests table exists with ALL required columns.
     *
     * Strategy: Check existing columns. If ANY are missing → DROP and RECREATE.
     * This is more reliable than ALTER TABLE ADD COLUMN which can fail
     * with NOT NULL constraints on existing rows.
     *
     * @return void
     */
    private function ensureTableExists(): void
    {
        try {
            $stmt = $this->db->query('SHOW COLUMNS FROM `demo_class_requests`');
            $existingCols = array_column($stmt->fetchAll(\PDO::FETCH_ASSOC), 'Field');

            // Check if any required columns are missing
            $requiredCols = array_keys(self::TABLE_COLUMNS);
            $missingCols = array_diff($requiredCols, $existingCols);

            if (!empty($missingCols)) {
                // Table exists but is INCOMPLETE — drop and recreate
                error_log('Admin Demo class: Table incomplete, missing columns: ' . implode(', ', $missingCols) . ' — dropping and recreating');
                $this->db->exec('DROP TABLE IF EXISTS `demo_class_requests`');
                $this->db->exec(self::CREATE_TABLE_SQL);
                error_log('Admin Demo class: Table recreated successfully');
            }
        } catch (\Throwable $e) {
            // Table doesn't exist at all — create it fresh
            error_log('Admin Demo class: Table does not exist, creating: ' . $e->getMessage());
            $this->db->exec(self::CREATE_TABLE_SQL);
            error_log('Admin Demo class: Table created successfully');
        }
    }

    /**
     * List all demo class requests.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function index(array $params = []): void
    {
        requireAdmin();

        // Ensure the table exists and has all columns
        try {
            $this->ensureTableExists();
        } catch (\Throwable $e) {
            error_log('Admin Demo class: ensureTableExists failed: ' . $e->getMessage());
        }

        $stmt = $this->db->query(
            'SELECT d.*, c.name AS course_name FROM `demo_class_requests` d LEFT JOIN `courses` c ON d.course_id = c.id ORDER BY d.created_at DESC'
        );
        $requests = $stmt->fetchAll() ?: [];

        // Count by status
        $statusCounts = [
            'pending'   => 0,
            'contacted' => 0,
            'scheduled' => 0,
            'completed' => 0,
            'cancelled' => 0,
        ];
        foreach ($requests as $r) {
            $s = $r['status'] ?? '';
            if (isset($statusCounts[$s])) {
                $statusCounts[$s]++;
            }
        }

        $this->adminView('demo_class', [
            'title'        => 'Demo Class Requests',
            'currentPage'  => 'demo-class',
            'requests'     => $requests,
            'statusCounts' => $statusCounts,
        ]);
    }

    /**
     * Update the status of a demo class request.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function updateStatus(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);
        $status = sanitize($_POST['status'] ?? '');
        $note   = sanitize($_POST['admin_note'] ?? '');

        $allowedStatuses = ['pending', 'contacted', 'scheduled', 'completed', 'cancelled'];

        if ($id <= 0 || !in_array($status, $allowedStatuses, true)) {
            flash('error', 'Invalid request or status.');
            redirect(BASE_PATH . '/admin/demo-class');
        }

        $this->ensureTableExists();

        $stmt = $this->db->prepare(
            'UPDATE `demo_class_requests` SET `status` = :status, `is_read` = 1, `admin_note` = :note, `updated_at` = NOW() WHERE `id` = :id'
        );
        $stmt->execute([
            ':status' => $status,
            ':note'   => $note,
            ':id'     => $id,
        ]);

        flash('success', 'Demo class request status updated to "' . ucfirst($status) . '".');
        redirect(BASE_PATH . '/admin/demo-class');
    }

    /**
     * Mark a demo class request as read.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function markRead(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        if ($id <= 0) {
            flash('error', 'Invalid request.');
            redirect(BASE_PATH . '/admin/demo-class');
        }

        $this->ensureTableExists();

        $stmt = $this->db->prepare('UPDATE `demo_class_requests` SET `is_read` = 1 WHERE `id` = :id');
        $stmt->execute([':id' => $id]);

        flash('success', 'Request marked as read.');
        redirect(BASE_PATH . '/admin/demo-class');
    }

    /**
     * Delete a demo class request.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function delete(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);

        $this->ensureTableExists();

        $stmt = $this->db->prepare('DELETE FROM `demo_class_requests` WHERE `id` = :id');
        $stmt->execute([':id' => $id]);

        if ($stmt->rowCount() > 0) {
            flash('success', 'Demo class request deleted successfully.');
        } else {
            flash('warning', 'Request not found or already deleted.');
        }
        redirect(BASE_PATH . '/admin/demo-class');
    }
}
