<?php
require_once __DIR__ . '/../functions.php';
ensure_logged_in();
$method = $_SERVER['REQUEST_METHOD'];
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';

if ($method !== 'POST' || !verify_csrf_token($_POST['csrf'] ?? '')) {
    if ($isAjax) {
        header('Content-Type: application/json');
        echo json_encode(['status' => 'error', 'message' => 'Invalid CSRF token.']);
    } else {
        flash('Invalid session token.', 'error');
        header('Location: ' . BASE_URL . 'admin/index.php');
    }
    exit;
}

function respond($payload) {
    global $isAjax;
    if ($isAjax) {
        header('Content-Type: application/json');
        echo json_encode($payload);
        exit;
    }
    return $payload;
}

function log_action($action, $meta = null) {
    $stmt = pdo()->prepare('INSERT INTO activity_logs (user_id, action, meta) VALUES (:user_id, :action, :meta)');
    $stmt->execute([
        'user_id' => current_user()['id'] ?? null,
        'action' => $action,
        'meta' => $meta,
    ]);
}

$action = $_POST['action'] ?? '';

if (function_exists('ensure_seo_schema')) {
    ensure_seo_schema();
}

switch ($action) {
    case 'create_user':
        ensure_role(['Admin']);
        $name = clean($_POST['name'] ?? '');
        $email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
        $role = $_POST['role'] ?? 'Normal User';
        $status = $_POST['status'] === 'Inactive' ? 'Inactive' : 'Active';
        $password = $_POST['password'] ?? '';
        if (!$name || !$email || !$password) {
            respond(['status' => 'error', 'message' => 'Name, email, and password are required.']);
        }
        try {
            $hash = password_hash($password, PASSWORD_DEFAULT);
            $profilePicture = null;
            if (!empty($_FILES['profile_picture']['name'])) {
                $profilePicture = upload_image('profile_picture', 'profiles');
            }
            $stmt = pdo()->prepare('INSERT INTO users (name,email,password,role,status,profile_picture) VALUES (:name,:email,:password,:role,:status,:profile_picture)');
            $stmt->execute(['name'=>$name,'email'=>$email,'password'=>$hash,'role'=>$role,'status'=>$status,'profile_picture'=>$profilePicture]);
            log_action('Created user', $email);
            respond(['status' => 'success', 'message' => 'User created successfully.']);
        } catch (PDOException $e) {
            if ($e->getCode() == 23000) { // Duplicate entry
                respond(['status' => 'error', 'message' => 'A user with this email already exists.']);
            } else {
                respond(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
            }
        }
        break;

    case 'update_user':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        $name = clean($_POST['name'] ?? '');
        $email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
        $role = $_POST['role'] ?? 'Normal User';
        $status = $_POST['status'] === 'Inactive' ? 'Inactive' : 'Active';
        $password = $_POST['password'] ?? '';
        if (!$id || !$name || !$email) {
            respond(['status' => 'error', 'message' => 'Invalid user data.']);
        }
        try {
            $updates = 'name=:name,email=:email,role=:role,status=:status';
            $params = ['name'=>$name,'email'=>$email,'role'=>$role,'status'=>$status,'id'=>$id];
            if (!empty($_FILES['profile_picture']['name'])) {
                $profilePicture = upload_image('profile_picture', 'profiles');
                if ($profilePicture) {
                    $updates .= ',profile_picture=:profile_picture';
                    $params['profile_picture'] = $profilePicture;
                }
            }
            if ($password) {
                $updates .= ',password=:password';
                $params['password'] = password_hash($password, PASSWORD_DEFAULT);
            }
            $stmt = pdo()->prepare("UPDATE users SET $updates WHERE id = :id");
            $stmt->execute($params);
            log_action('Updated user', $email);
            respond(['status' => 'success', 'message' => 'User updated successfully.']);
        } catch (PDOException $e) {
            respond(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
        }
        break;

    case 'update_profile':
        ensure_logged_in();
        $userId = (int) (current_user()['id'] ?? 0);
        $name = clean($_POST['name'] ?? '');
        $email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
        $password = $_POST['password'] ?? '';
        $confirmPassword = $_POST['confirm_password'] ?? '';
        if (!$userId || !$name || !$email) {
            flash('Name and email are required.', 'error');
            header('Location: ' . BASE_URL . 'admin/profile.php');
            exit;
        }
        if ($password !== '' && $password !== $confirmPassword) {
            flash('Passwords do not match.', 'error');
            header('Location: ' . BASE_URL . 'admin/profile.php');
            exit;
        }
        try {
            $updates = 'name=:name,email=:email';
            $params = ['name'=>$name,'email'=>$email,'id'=>$userId];
            if (!empty($_FILES['profile_picture']['name'])) {
                $profilePicture = upload_image('profile_picture', 'profiles');
                if ($profilePicture) {
                    $updates .= ',profile_picture=:profile_picture';
                    $params['profile_picture'] = $profilePicture;
                }
            }
            if ($password) {
                $updates .= ',password=:password';
                $params['password'] = password_hash($password, PASSWORD_DEFAULT);
            }
            $stmt = pdo()->prepare("UPDATE users SET $updates WHERE id = :id");
            $stmt->execute($params);
            $stmt = pdo()->prepare('SELECT id,name,email,role,status,profile_picture FROM users WHERE id = :id');
            $stmt->execute(['id' => $userId]);
            $_SESSION['user'] = $stmt->fetch();
            flash('Profile updated successfully.', 'success');
        } catch (PDOException $e) {
            flash('Database error: ' . $e->getMessage(), 'error');
        }
        header('Location: ' . BASE_URL . 'admin/profile.php');
        exit;

    case 'delete_user':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid user id.']);
        }
        try {
            $stmt = pdo()->prepare('DELETE FROM users WHERE id = :id');
            $stmt->execute(['id'=>$id]);
            log_action('Deleted user', 'ID:' . $id);
            respond(['status' => 'success', 'message' => 'User removed.']);
        } catch (PDOException $e) {
            respond(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
        }
        break;

    case 'save_settings':
        ensure_role(['Admin']);
        $settings = [
            'site_name' => clean($_POST['site_name'] ?? ''),
            'site_whatsapp' => clean($_POST['whatsapp'] ?? ''),
            'site_phone' => clean($_POST['phone'] ?? ''),
            'site_email' => clean($_POST['email'] ?? ''),
            'site_footer' => clean($_POST['footer'] ?? ''),
            'site_copyright' => clean($_POST['copyright'] ?? ''),
            'site_about' => clean($_POST['about'] ?? ''),
            'social_facebook' => clean($_POST['facebook'] ?? ''),
            'social_twitter' => clean($_POST['twitter'] ?? ''),
            'social_linkedin' => clean($_POST['linkedin'] ?? ''),
            'mail_from_name' => clean($_POST['mail_from_name'] ?? ''),
            'mail_from_address' => clean($_POST['mail_from_address'] ?? ''),
            'mail_host' => clean($_POST['mail_host'] ?? ''),
            'mail_port' => clean($_POST['mail_port'] ?? ''),
            'mail_username' => clean($_POST['mail_username'] ?? ''),
            'mail_encryption' => clean($_POST['mail_encryption'] ?? ''),
        ];
        foreach ($settings as $key => $value) {
            set_setting($key, $value);
        }
        $mailPassword = $_POST['mail_password'] ?? '';
        if ($mailPassword !== '') {
            set_setting('mail_password', clean($mailPassword));
        }
        if (!empty($_FILES['logo']['name'])) {
            $path = upload_image('logo', 'logo');
            if ($path) {
                set_setting('site_logo', $path);
            }
        }
        if (!empty($_FILES['favicon']['name'])) {
            $path = upload_image('favicon', 'favicon');
            if ($path) {
                set_setting('site_favicon', $path);
            }
        }
        if (!empty($_POST['slide_title']) && is_array($_POST['slide_title'])) {
            $stmt = pdo()->prepare('UPDATE hero_slides SET title = :title, caption = :caption, title_font_size = :title_font_size, title_color = :title_color, title_position = :title_position, button_1_text = :button_1_text, button_1_url = :button_1_url, button_2_text = :button_2_text, button_2_url = :button_2_url, sort_order = :sort_order, status = :status WHERE id = :id');
            foreach ($_POST['slide_title'] as $id => $title) {
                $slideId = (int) $id;
                $caption = clean($_POST['slide_caption'][$id] ?? '');
                $fontSize = clean($_POST['slide_title_font_size'][$id] ?? '3rem');
                $titleColor = clean($_POST['slide_title_color'][$id] ?? '#ffffff');
                $titlePosition = in_array($_POST['slide_title_position'][$id] ?? 'center-left', ['top-left','top-right','center-left','center','center-right','bottom-left','bottom-right'], true) ? $_POST['slide_title_position'][$id] : 'center-left';
                $button1Text = clean($_POST['slide_button_1_text'][$id] ?? '');
                $button1Url = clean($_POST['slide_button_1_url'][$id] ?? '');
                $button2Text = clean($_POST['slide_button_2_text'][$id] ?? '');
                $button2Url = clean($_POST['slide_button_2_url'][$id] ?? '');
                $sortOrder = max(0, (int) ($_POST['slide_sort'][$id] ?? 0));
                $status = in_array($_POST['slide_status'][$id] ?? 'Published', ['Published', 'Draft'], true) ? $_POST['slide_status'][$id] : 'Published';
                $stmt->execute([
                    'title' => clean($title),
                    'caption' => $caption,
                    'title_font_size' => $fontSize,
                    'title_color' => $titleColor,
                    'title_position' => $titlePosition,
                    'button_1_text' => $button1Text,
                    'button_1_url' => $button1Url,
                    'button_2_text' => $button2Text,
                    'button_2_url' => $button2Url,
                    'sort_order' => $sortOrder,
                    'status' => $status,
                    'id' => $slideId,
                ]);
            }
        }
        if (!empty($_POST['team_name']) && is_array($_POST['team_name'])) {
            foreach ($_POST['team_name'] as $id => $name) {
                $memberId = (int) $id;
                $title = clean($_POST['team_title'][$id] ?? '');
                $sortOrder = max(0, (int) ($_POST['team_sort'][$id] ?? 0));
                $status = in_array($_POST['team_status'][$id] ?? 'Published', ['Published', 'Draft'], true) ? $_POST['team_status'][$id] : 'Published';
                $photoPath = null;
                if (isset($_FILES['team_photo']['name'][$id]) && $_FILES['team_photo']['error'][$id] === UPLOAD_ERR_OK) {
                    $_FILES['team_photo_file'] = [
                        'name' => $_FILES['team_photo']['name'][$id],
                        'type' => $_FILES['team_photo']['type'][$id],
                        'tmp_name' => $_FILES['team_photo']['tmp_name'][$id],
                        'error' => $_FILES['team_photo']['error'][$id],
                        'size' => $_FILES['team_photo']['size'][$id],
                    ];
                    $photoPath = upload_image('team_photo_file', 'team');
                }
                $updateSql = 'UPDATE team_members SET name = :name, title = :title, sort_order = :sort_order, status = :status';
                $params = [
                    'name' => clean($name),
                    'title' => $title,
                    'sort_order' => $sortOrder,
                    'status' => $status,
                    'id' => $memberId,
                ];
                if ($photoPath) {
                    $updateSql .= ', photo = :photo';
                    $params['photo'] = $photoPath;
                }
                $updateSql .= ' WHERE id = :id';
                $teamStmt = pdo()->prepare($updateSql);
                $teamStmt->execute($params);
            }
        }
        if (!empty($_FILES['hero_images']['name'][0])) {
            $paths = upload_images('hero_images', 'hero');
            foreach ($paths as $path) {
                $stmt = pdo()->prepare('INSERT INTO hero_slides (path, status) VALUES (:path, :status)');
                $stmt->execute(['path' => $path, 'status' => 'Published']);
            }
        }
        if (!empty($_POST['new_team_name']) || !empty($_FILES['new_team_photo']['name'])) {
            $newName = clean($_POST['new_team_name'] ?? '');
            $newTitle = clean($_POST['new_team_title'] ?? '');
            $newStatus = in_array($_POST['new_team_status'] ?? 'Published', ['Published', 'Draft'], true) ? $_POST['new_team_status'] : 'Published';
            $newSort = max(0, (int) ($_POST['new_team_sort'] ?? 0));
            $newPhoto = null;
            if (!empty($_FILES['new_team_photo']['name']) && $_FILES['new_team_photo']['error'] === UPLOAD_ERR_OK) {
                $newPhoto = upload_image('new_team_photo', 'team');
            }
            $stmt = pdo()->prepare('INSERT INTO team_members (name, title, photo, sort_order, status) VALUES (:name, :title, :photo, :sort_order, :status)');
            $stmt->execute([
                'name' => $newName,
                'title' => $newTitle,
                'photo' => $newPhoto,
                'sort_order' => $newSort,
                'status' => $newStatus,
            ]);
        }
        if (!empty($_FILES['team_photos']['name'][0])) {
            $teamPaths = upload_images('team_photos', 'team');
            foreach ($teamPaths as $path) {
                $stmt = pdo()->prepare('INSERT INTO team_members (photo, status) VALUES (:photo, :status)');
                $stmt->execute(['photo' => $path, 'status' => 'Published']);
            }
        }
        log_action('Updated settings');
        flash('Settings saved successfully.');
        header('Location: ' . BASE_URL . 'admin/settings.php');
        exit;
        break;

    case 'delete_hero_slide':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid hero slide id.']);
        }
        try {
            $stmt = pdo()->prepare('DELETE FROM hero_slides WHERE id = :id');
            $stmt->execute(['id' => $id]);
            respond(['status' => 'success', 'message' => 'Hero slide removed.']);
        } catch (PDOException $e) {
            respond(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
        }
        break;

    case 'delete_team_member':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid team member id.']);
        }
        try {
            $stmt = pdo()->prepare('DELETE FROM team_members WHERE id = :id');
            $stmt->execute(['id' => $id]);
            respond(['status' => 'success', 'message' => 'Team member removed.']);
        } catch (PDOException $e) {
            respond(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
        }
        break;

    case 'delete_service':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid service id.']);
        }
        try {
            $stmt = pdo()->prepare('DELETE FROM services WHERE id = :id');
            $stmt->execute(['id' => $id]);
            respond(['status' => 'success', 'message' => 'Service removed.']);
        } catch (PDOException $e) {
            respond(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
        }
        break;

    case 'create_service':
        ensure_role(['Admin','Manager']);
        $title = clean($_POST['title'] ?? '');
        $description = clean($_POST['description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        $sortOrder = max(0, (int) ($_POST['sort_order'] ?? 0));
        $thumbnail = null;
        if (!empty($_FILES['thumbnail']['name']) && $_FILES['thumbnail']['error'] === UPLOAD_ERR_OK) {
            $thumbnail = upload_image('thumbnail', 'services');
        }
        if (!$title) {
            flash('Service title is required.', 'error');
            header('Location: ' . BASE_URL . 'admin/services.php');
            exit;
        }
        if (!table_exists('services')) {
            pdo()->exec("CREATE TABLE IF NOT EXISTS services (
              id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
              title VARCHAR(255) NOT NULL,
              description TEXT DEFAULT NULL,
              thumbnail VARCHAR(255) DEFAULT NULL,
              sort_order INT UNSIGNED NOT NULL DEFAULT 0,
              status ENUM('Published','Draft') NOT NULL DEFAULT 'Published',
              created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
        }
        $stmt = pdo()->prepare('INSERT INTO services (title, description, thumbnail, sort_order, status) VALUES (:title, :description, :thumbnail, :sort_order, :status)');
        $stmt->execute(['title' => $title, 'description' => $description, 'thumbnail' => $thumbnail, 'sort_order' => $sortOrder, 'status' => $status]);
        flash('Service created successfully.', 'success');
        header('Location: ' . BASE_URL . 'admin/services.php');
        exit;
        break;

    case 'update_service':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $title = clean($_POST['title'] ?? '');
        $description = clean($_POST['description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        $sortOrder = max(0, (int) ($_POST['sort_order'] ?? 0));
        $thumbnail = null;
        if (!empty($_FILES['thumbnail']['name']) && $_FILES['thumbnail']['error'] === UPLOAD_ERR_OK) {
            $thumbnail = upload_image('thumbnail', 'services');
        }
        if (!$id || !$title) {
            flash('Service title is required.', 'error');
            header('Location: ' . BASE_URL . 'admin/services.php');
            exit;
        }
        if (!table_exists('services')) {
            pdo()->exec("CREATE TABLE IF NOT EXISTS services (
              id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
              title VARCHAR(255) NOT NULL,
              description TEXT DEFAULT NULL,
              thumbnail VARCHAR(255) DEFAULT NULL,
              sort_order INT UNSIGNED NOT NULL DEFAULT 0,
              status ENUM('Published','Draft') NOT NULL DEFAULT 'Published',
              created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
        }
        $updateSql = 'UPDATE services SET title = :title, description = :description, sort_order = :sort_order, status = :status';
        $params = ['title' => $title, 'description' => $description, 'sort_order' => $sortOrder, 'status' => $status, 'id' => $id];
        if ($thumbnail) {
            $updateSql .= ', thumbnail = :thumbnail';
            $params['thumbnail'] = $thumbnail;
        }
        $updateSql .= ' WHERE id = :id';
        $stmt = pdo()->prepare($updateSql);
        $stmt->execute($params);
        flash('Service updated successfully.', 'success');
        header('Location: ' . BASE_URL . 'admin/services.php');
        exit;
        break;

    case 'create_shop_category':
        ensure_role(['Admin','Manager']);
        $name = clean($_POST['name'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        $thumbnail = null;
        if (!empty($_FILES['thumbnail']['name'])) {
            $thumbnail = upload_image('thumbnail', 'shop_categories');
        }
        if (!$name) {
            flash('Category name is required.', 'error');
            header('Location: ' . BASE_URL . 'admin/shop.php');
            exit;
        }
        $stmt = pdo()->prepare('INSERT INTO shop_categories (name, thumbnail, seo_title, seo_description, status) VALUES (:name,:thumbnail,:seo_title,:seo_description,:status)');
        $stmt->execute(['name'=>$name,'thumbnail'=>$thumbnail,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status]);
        flash('Category created.', 'success');
        header('Location: ' . BASE_URL . 'admin/shop.php');
        exit;
        break;

    case 'update_shop_category':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $name = clean($_POST['name'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$id || !$name) {
            flash('Invalid category data.', 'error');
            header('Location: ' . BASE_URL . 'admin/shop.php');
            exit;
        }
        $thumbnail = null;
        $updates = 'name=:name,seo_title=:seo_title,seo_description=:seo_description,status=:status';
        $params = ['name'=>$name,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status,'id'=>$id];
        if (!empty($_FILES['thumbnail']['name'])) {
            $thumbnail = upload_image('thumbnail', 'shop_categories');
            if ($thumbnail) {
                $updates .= ',thumbnail=:thumbnail';
                $params['thumbnail'] = $thumbnail;
            }
        }
        $stmt = pdo()->prepare("UPDATE shop_categories SET $updates WHERE id=:id");
        $stmt->execute($params);
        flash('Category updated.', 'success');
        header('Location: ' . BASE_URL . 'admin/shop.php');
        exit;
        break;

    case 'create_blog_category':
        ensure_role(['Admin','Manager']);
        $name = clean($_POST['name'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$name) {
            flash('Blog category name is required.', 'error');
            header('Location: ' . BASE_URL . 'admin/blog.php');
            exit;
        }
        $thumbnail = null;
        if (!empty($_FILES['thumbnail']['name'])) {
            $thumbnail = upload_image('thumbnail', 'blog_categories');
        }
        $stmt = pdo()->prepare('INSERT INTO blog_categories (name, thumbnail, seo_title, seo_description, status) VALUES (:name,:thumbnail,:seo_title,:seo_description,:status)');
        $stmt->execute(['name'=>$name,'thumbnail'=>$thumbnail,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status]);
        flash('Blog category created.', 'success');
        header('Location: ' . BASE_URL . 'admin/blog.php');
        exit;
        break;

    case 'update_blog_category':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $name = clean($_POST['name'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$id || !$name) {
            flash('Invalid blog category data.', 'error');
            header('Location: ' . BASE_URL . 'admin/blog.php');
            exit;
        }
        $updates = 'name=:name,seo_title=:seo_title,seo_description=:seo_description,status=:status';
        $params = ['name'=>$name,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status,'id'=>$id];
        if (!empty($_FILES['thumbnail']['name'])) {
            $thumbnail = upload_image('thumbnail', 'blog_categories');
            if ($thumbnail) {
                $updates .= ',thumbnail=:thumbnail';
                $params['thumbnail'] = $thumbnail;
            }
        }
        $stmt = pdo()->prepare("UPDATE blog_categories SET $updates WHERE id=:id");
        $stmt->execute($params);
        flash('Blog category updated.', 'success');
        header('Location: ' . BASE_URL . 'admin/blog.php');
        exit;
        break;

    case 'delete_blog_category':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid blog category id.']);
        }
        $stmt = pdo()->prepare('DELETE FROM blog_categories WHERE id = :id');
        $stmt->execute(['id'=>$id]);
        respond(['status' => 'success', 'message' => 'Blog category removed.']);
        break;

    case 'create_portfolio_category':
        ensure_role(['Admin','Manager']);
        $name = clean($_POST['name'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$name) {
            flash('Portfolio category name is required.', 'error');
            header('Location: ' . BASE_URL . 'admin/portfolio.php');
            exit;
        }
        $thumbnail = null;
        if (!empty($_FILES['thumbnail']['name'])) {
            $thumbnail = upload_image('thumbnail', 'portfolio_categories');
        }
        $stmt = pdo()->prepare('INSERT INTO portfolio_categories (name, thumbnail, seo_title, seo_description, status) VALUES (:name,:thumbnail,:seo_title,:seo_description,:status)');
        $stmt->execute(['name'=>$name,'thumbnail'=>$thumbnail,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status]);
        flash('Portfolio category created.', 'success');
        header('Location: ' . BASE_URL . 'admin/portfolio.php');
        exit;
        break;

    case 'update_portfolio_category':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $name = clean($_POST['name'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$id || !$name) {
            flash('Invalid portfolio category data.', 'error');
            header('Location: ' . BASE_URL . 'admin/portfolio.php');
            exit;
        }
        $updates = 'name=:name,seo_title=:seo_title,seo_description=:seo_description,status=:status';
        $params = ['name'=>$name,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status,'id'=>$id];
        if (!empty($_FILES['thumbnail']['name'])) {
            $thumbnail = upload_image('thumbnail', 'portfolio_categories');
            if ($thumbnail) {
                $updates .= ',thumbnail=:thumbnail';
                $params['thumbnail'] = $thumbnail;
            }
        }
        $stmt = pdo()->prepare("UPDATE portfolio_categories SET $updates WHERE id=:id");
        $stmt->execute($params);
        flash('Portfolio category updated.', 'success');
        header('Location: ' . BASE_URL . 'admin/portfolio.php');
        exit;
        break;

    case 'delete_portfolio_category':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid portfolio category id.']);
        }
        $stmt = pdo()->prepare('DELETE FROM portfolio_categories WHERE id = :id');
        $stmt->execute(['id'=>$id]);
        respond(['status' => 'success', 'message' => 'Portfolio category removed.']);
        break;

    case 'delete_shop_category':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid shop category id.']);
        }
        $stmt = pdo()->prepare('DELETE FROM shop_categories WHERE id = :id');
        $stmt->execute(['id'=>$id]);
        respond(['status' => 'success', 'message' => 'Shop category removed.']);
        break;

    case 'create_shop_product':
        ensure_role(['Admin','Manager']);
        $name = clean($_POST['name'] ?? '');
        $description = clean($_POST['description'] ?? '');
        $specs = clean($_POST['specs'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $categoryId = (int) ($_POST['category_id'] ?? 0);
        $price = clean($_POST['price'] ?? '');
        $featured = isset($_POST['featured']) ? 1 : 0;
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$name || !$description || !$categoryId || !$price) {
            flash('Product name, description, category and price are required.', 'error');
            header('Location: ' . BASE_URL . 'admin/shop.php');
            exit;
        }
        $imagePath = null;
        if (!empty($_FILES['featured_image']['name'])) {
            $imagePath = upload_image('featured_image', 'shop');
        }
        $stmt = pdo()->prepare('INSERT INTO shop_products (name,description,specs,category_id,price,featured_image,featured,seo_title,seo_description,status) VALUES (:name,:description,:specs,:category_id,:price,:featured_image,:featured,:seo_title,:seo_description,:status)');
        $stmt->execute(['name'=>$name,'description'=>$description,'specs'=>$specs,'category_id'=>$categoryId,'price'=>$price,'featured_image'=>$imagePath,'featured'=>$featured,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status]);
        flash('Product created.', 'success');
        header('Location: ' . BASE_URL . 'admin/shop.php');
        exit;
        break;

    case 'update_shop_product':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $name = clean($_POST['name'] ?? '');
        $description = clean($_POST['description'] ?? '');
        $specs = clean($_POST['specs'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $categoryId = (int) ($_POST['category_id'] ?? 0);
        $price = clean($_POST['price'] ?? '');
        $status = $_POST['status'] === 'Draft' ? 'Draft' : 'Published';
        if (!$id || !$name || !$description || !$categoryId || !$price) {
            flash('Incomplete product details.', 'error');
            header('Location: ' . BASE_URL . 'admin/shop.php');
            exit;
        }
        $featured = isset($_POST['featured']) ? 1 : 0;
        $query = 'UPDATE shop_products SET name=:name,description=:description,specs=:specs,category_id=:category_id,price=:price,featured=:featured,seo_title=:seo_title,seo_description=:seo_description,status=:status';
        $params = ['name'=>$name,'description'=>$description,'specs'=>$specs,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'category_id'=>$categoryId,'price'=>$price,'status'=>$status,'featured'=>$featured,'id'=>$id];
        if (!empty($_FILES['featured_image']['name'])) {
            $imagePath = upload_image('featured_image', 'shop');
            if ($imagePath) {
                $query .= ',featured_image=:featured_image';
                $params['featured_image'] = $imagePath;
            }
        }
        $query .= ' WHERE id=:id';
        $stmt = pdo()->prepare($query);
        $stmt->execute($params);
        flash('Product updated.', 'success');
        header('Location: ' . BASE_URL . 'admin/shop.php');
        exit;
        break;

    case 'delete_shop_product':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid shop product id.']);
        }
        $stmt = pdo()->prepare('DELETE FROM shop_products WHERE id = :id');
        $stmt->execute(['id'=>$id]);
        respond(['status' => 'success', 'message' => 'Shop product removed.']);
        break;

    case 'create_project':
        ensure_role(['Admin','Manager']);
        $title = clean($_POST['title'] ?? '');
        $description = clean($_POST['description'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $technologies = clean($_POST['technologies'] ?? '');
        $outcome = clean($_POST['outcome'] ?? '');
        $categoryId = (int) ($_POST['category_id'] ?? 0);
        $status = $_POST['status'] === 'Published' ? 'Published' : 'Draft';
        ensure_column('portfolio_projects', 'featured_image', 'VARCHAR(255) DEFAULT NULL');
        if (!$title || !$description) {
            flash('Project title and description are required.', 'error');
            header('Location: ' . BASE_URL . 'admin/portfolio.php');
            exit;
        }
        $featuredImage = null;
        if (!empty($_FILES['featured_image']['name'])) {
            $featuredImage = upload_image('featured_image', 'portfolio');
        }
        $stmt = pdo()->prepare('INSERT INTO portfolio_projects (title,description,seo_title,seo_description,technologies,outcome,category_id,featured_image,status) VALUES (:title,:description,:seo_title,:seo_description,:technologies,:outcome,:category_id,:featured_image,:status)');
        $stmt->execute(['title'=>$title,'description'=>$description,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'technologies'=>$technologies,'outcome'=>$outcome,'category_id'=>$categoryId,'featured_image'=>$featuredImage,'status'=>$status]);
        $projectId = pdo()->lastInsertId();
        if (!empty($_FILES['images']['name'][0])) {
            foreach ($_FILES['images']['tmp_name'] as $index => $tmpName) {
                if ($_FILES['images']['error'][$index] === UPLOAD_ERR_OK) {
                    $_FILES['file'] = [
                        'name' => $_FILES['images']['name'][$index],
                        'type' => $_FILES['images']['type'][$index],
                        'tmp_name' => $tmpName,
                        'error' => UPLOAD_ERR_OK,
                        'size' => $_FILES['images']['size'][$index],
                    ];
                    $path = upload_image('file', 'portfolio');
                    if ($path) {
                        $imgStmt = pdo()->prepare('INSERT INTO portfolio_images (project_id, path) VALUES (:project_id, :path)');
                        $imgStmt->execute(['project_id'=>$projectId,'path'=>$path]);
                    }
                }
            }
        }
        flash('Portfolio project created.', 'success');
        header('Location: ' . BASE_URL . 'admin/portfolio.php');
        exit;
        break;

    case 'update_project':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $title = clean($_POST['title'] ?? '');
        $description = clean($_POST['description'] ?? '');
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $technologies = clean($_POST['technologies'] ?? '');
        $outcome = clean($_POST['outcome'] ?? '');
        $categoryId = (int) ($_POST['category_id'] ?? 0);
        $status = $_POST['status'] === 'Published' ? 'Published' : 'Draft';
        ensure_column('portfolio_projects', 'featured_image', 'VARCHAR(255) DEFAULT NULL');
        if (!$id || !$title || !$description) {
            flash('Incomplete project details.', 'error');
            header('Location: ' . BASE_URL . 'admin/portfolio.php');
            exit;
        }
        $featuredImage = null;
        if (!empty($_FILES['featured_image']['name'])) {
            $featuredImage = upload_image('featured_image', 'portfolio');
        }
        $query = 'UPDATE portfolio_projects SET title=:title,description=:description,seo_title=:seo_title,seo_description=:seo_description,technologies=:technologies,outcome=:outcome,category_id=:category_id,status=:status';
        $params = ['title'=>$title,'description'=>$description,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'technologies'=>$technologies,'outcome'=>$outcome,'category_id'=>$categoryId,'status'=>$status,'id'=>$id];
        if ($featuredImage) {
            $query .= ',featured_image=:featured_image';
            $params['featured_image'] = $featuredImage;
        }
        $query .= ' WHERE id=:id';
        $stmt = pdo()->prepare($query);
        $stmt->execute($params);
        if (!empty($_FILES['images']['name'][0])) {
            foreach ($_FILES['images']['tmp_name'] as $index => $tmpName) {
                if ($_FILES['images']['error'][$index] === UPLOAD_ERR_OK) {
                    $_FILES['file'] = [
                        'name' => $_FILES['images']['name'][$index],
                        'type' => $_FILES['images']['type'][$index],
                        'tmp_name' => $tmpName,
                        'error' => UPLOAD_ERR_OK,
                        'size' => $_FILES['images']['size'][$index],
                    ];
                    $path = upload_image('file', 'portfolio');
                    if ($path) {
                        $imgStmt = pdo()->prepare('INSERT INTO portfolio_images (project_id, path) VALUES (:project_id, :path)');
                        $imgStmt->execute(['project_id'=>$id,'path'=>$path]);
                    }
                }
            }
        }
        flash('Project updated.', 'success');
        header('Location: ' . BASE_URL . 'admin/portfolio.php');
        exit;
        break;

    case 'delete_project':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid project id.']);
        }
        $stmt = pdo()->prepare('DELETE FROM portfolio_projects WHERE id = :id');
        $stmt->execute(['id'=>$id]);
        respond(['status' => 'success', 'message' => 'Project deleted.']);
        break;

    case 'create_blog':
        ensure_role(['Admin','Manager']);
        $title = clean($_POST['title'] ?? '');
        $content = $_POST['content'] ?? '';
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $categoryId = (int) ($_POST['category_id'] ?? 0);
        $status = $_POST['status'] === 'Published' ? 'Published' : 'Draft';
        if (!$title || !$content || !$categoryId) {
            flash('Title, content, and category are required.', 'error');
            header('Location: ' . BASE_URL . 'admin/blog.php');
            exit;
        }
        $imagePath = null;
        if (!empty($_FILES['featured_image']['name'])) {
            $imagePath = upload_image('featured_image', 'blog');
        }
        $stmt = pdo()->prepare('INSERT INTO blog_posts (title,content,category_id,featured_image,seo_title,seo_description,status) VALUES (:title,:content,:category_id,:featured_image,:seo_title,:seo_description,:status)');
        $stmt->execute(['title'=>$title,'content'=>$content,'category_id'=>$categoryId,'featured_image'=>$imagePath,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'status'=>$status]);
        flash('Blog post created.', 'success');
        header('Location: ' . BASE_URL . 'admin/blog.php');
        exit;
        break;

    case 'update_blog':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $title = clean($_POST['title'] ?? '');
        $content = $_POST['content'] ?? '';
        $seoTitle = clean($_POST['seo_title'] ?? '');
        $seoDescription = clean($_POST['seo_description'] ?? '');
        $categoryId = (int) ($_POST['category_id'] ?? 0);
        $status = $_POST['status'] === 'Published' ? 'Published' : 'Draft';
        if (!$id || !$title || !$content || !$categoryId) {
            flash('Incomplete blog details.', 'error');
            header('Location: ' . BASE_URL . 'admin/blog.php');
            exit;
        }
        $params = ['title'=>$title,'content'=>$content,'seo_title'=>$seoTitle,'seo_description'=>$seoDescription,'category_id'=>$categoryId,'status'=>$status,'id'=>$id];
        $query = 'UPDATE blog_posts SET title=:title,content=:content,seo_title=:seo_title,seo_description=:seo_description,category_id=:category_id,status=:status';
        if (!empty($_FILES['featured_image']['name'])) {
            $imagePath = upload_image('featured_image', 'blog');
            if ($imagePath) {
                $query .= ',featured_image=:featured_image';
                $params['featured_image'] = $imagePath;
            }
        }
        $query .= ' WHERE id=:id';
        $stmt = pdo()->prepare($query);
        $stmt->execute($params);
        flash('Blog post updated.', 'success');
        header('Location: ' . BASE_URL . 'admin/blog.php');
        exit;
        break;

    case 'delete_blog':
        ensure_role(['Admin']);
        $id = (int) ($_POST['id'] ?? 0);
        if (!$id) {
            respond(['status' => 'error', 'message' => 'Invalid post id.']);
        }
        $stmt = pdo()->prepare('DELETE FROM blog_posts WHERE id = :id');
        $stmt->execute(['id'=>$id]);
        respond(['status' => 'success', 'message' => 'Blog post deleted.']);
        break;

    case 'update_quote_status':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $status = in_array($_POST['status'] ?? '', ['New', 'In Progress', 'Completed'], true) ? $_POST['status'] : 'New';
        $stmt = pdo()->prepare('UPDATE quote_requests SET status=:status WHERE id=:id');
        $stmt->execute(['status'=>$status,'id'=>$id]);
        respond(['status' => 'success', 'message' => 'Quote status updated.']);
        break;

    case 'update_message_status':
        ensure_role(['Admin','Manager']);
        $id = (int) ($_POST['id'] ?? 0);
        $status = in_array($_POST['status'] ?? '', ['Unread','Read'], true) ? $_POST['status'] : 'Unread';
        $stmt = pdo()->prepare('UPDATE contact_messages SET status=:status WHERE id=:id');
        $stmt->execute(['status'=>$status,'id'=>$id]);
        respond(['status' => 'success', 'message' => 'Message status updated.']);
        break;

    default:
        respond(['status' => 'error', 'message' => 'Unknown action.']);
        break;
}
