<?php

declare(strict_types=1);

namespace Admin\Controllers;

use App\Core\Controller;

/**
 * Abstract Base Admin Controller
 *
 * Provides common functionality for all admin panel controllers,
 * including admin-specific view rendering with layout support.
 */
abstract class AdminController extends Controller
{
    /**
     * Base path for admin view files
     */
    private const ADMIN_VIEW_PATH = APP_ROOT . '/admin/Views/';

    /**
     * Render an admin view wrapped in the admin layout.
     *
     * Captures the specific view output, then passes it as $content
     * to the admin layout which includes the sidebar and top bar.
     *
     * @param string $view The view path relative to /admin/Views/
     * @param array<string, mixed> $data Associative array of data to pass to the view
     * @return never
     */
    protected function adminView(string $view, array $data = []): never
    {
        // Extract data into local variables for the view
        extract($data, EXTR_SKIP);

        // Make flash messages available in views
        $flash_error   = flash('error');
        $flash_success = flash('success');
        $flash_warning = flash('warning');
        $flash_info    = flash('info');

        // CSRF token for forms
        $csrfToken = generateCsrfToken();

        // Current user for top bar
        $currentUser = getCurrentUser();

        // Default page title
        $title = $title ?? 'Admin Panel';
        $currentPage = $currentPage ?? '';

        // Build the full path to the view file
        $viewFile = self::ADMIN_VIEW_PATH . $view . '.php';

        if (!file_exists($viewFile)) {
            http_response_code(500);
            error_log("Admin view not found: {$viewFile}");
            echo "Error: Admin view '{$view}' could not be found.";
            exit;
        }

        // Capture the view content into $content
        ob_start();
        require $viewFile;
        $content = ob_get_clean();

        // Render the admin layout with the captured content
        $layoutFile = self::ADMIN_VIEW_PATH . 'layout.php';

        if (!file_exists($layoutFile)) {
            // Fallback: output content without layout
            echo $content;
            exit;
        }

        require $layoutFile;
        exit;
    }

    /**
     * Render the login view (not wrapped in admin layout).
     *
     * @param array<string, mixed> $data Data to pass to the login view
     * @return never
     */
    protected function loginView(array $data = []): never
    {
        extract($data, EXTR_SKIP);

        $flash_error   = flash('error');
        $flash_success = flash('success');
        $csrfToken     = generateCsrfToken();
        $title         = $title ?? 'Admin Login';

        $viewFile = self::ADMIN_VIEW_PATH . 'login.php';

        if (!file_exists($viewFile)) {
            http_response_code(500);
            echo "Error: Admin login view could not be found.";
            exit;
        }

        require $viewFile;
        exit;
    }

    /**
     * Handle image upload with validation.
     *
     * Validates file type, generates a unique filename, and moves
     * the uploaded file to the designated uploads directory.
     *
     * @param string $fieldName The form field name for the file input
     * @param string $subDir Subdirectory within uploads (e.g. 'sliders', 'courses')
     * @return string|null The relative path to the uploaded file, or null on failure
     */
    protected function handleImageUpload(string $fieldName, string $subDir = ''): ?string
    {
        if (!isset($_FILES[$fieldName]) || $_FILES[$fieldName]['error'] !== UPLOAD_ERR_OK) {
            return null;
        }

        $file = $_FILES[$fieldName];

        // Validate file size (max 5MB)
        if ($file['size'] > 5 * 1024 * 1024) {
            flash('error', 'Image size must be less than 5MB.');
            return null;
        }

        // Validate MIME type
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_file($finfo, $file['tmp_name']);
        finfo_close($finfo);

        if (!in_array($mimeType, $allowedTypes, true)) {
            flash('error', 'Only JPG, PNG, GIF, and WebP images are allowed.');
            return null;
        }

        // Generate unique filename
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = uniqid('img_', true) . '.' . $extension;

        // Build upload directory path
        $uploadDir = PUBLIC_ROOT . '/uploads/' . $subDir;
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        $destination = $uploadDir . '/' . $filename;

        if (!move_uploaded_file($file['tmp_name'], $destination)) {
            flash('error', 'Failed to upload image. Please try again.');
            return null;
        }

        return 'uploads/' . ($subDir ? $subDir . '/' : '') . $filename;
    }
}
