<?php
/**
 * Cast Conductor Proprietary License v5
 * SPDX-License-Identifier: LicenseRef-CastConductor-Proprietary-v5
 * 
 * Copyright (c) 2025 CastConductor.com. All Rights Reserved.
 * 
 * This file is part of Cast Conductor ("Software"). The Software and its source
 * code constitute proprietary, confidential, and trade secret information of
 * CastConductor.com ("Company"). Any access or use is governed strictly by the
 * Cast Conductor Proprietary License v5 ("License"). By installing, copying,
 * accessing, compiling, or otherwise using the Software you agree to be bound by
 * all terms of the License. If you do not agree, you must cease use immediately.
 * 
 * Key Terms (Summary – see full License for binding terms):
 *  1. No Redistribution: You may not publish, distribute, sublicense, rent,
 *     lease, transfer, sell, or otherwise make the Software (or any derivative)
 *     available to any third party without prior written consent of Company.
 *  2. No Modification: Modification, reverse engineering, decompilation, or
 *     disassembly is prohibited except to the limited extent expressly permitted
 *     by applicable law that cannot be contractually waived.
 *  3. Confidentiality: Treat all source code and related artifacts as Company
 *     Confidential Information. Maintain at least the same degree of care as for
 *     your own confidential materials, and not less than reasonable care.
 *  4. No Patent License: No express or implied patent rights are granted. Future
 *     patents (if any) are fully reserved.
 *  5. No Trademark License: Company names, marks, and logos may not be used
 *     without prior written permission.
 *  6. Limited Internal Use: Use is limited solely to internal evaluation and
 *     operation of licensed Cast Conductor deployments. Commercial hosting or
 *     resale as a service requires a separate written agreement.
 *  7. Telemetry & License Validation: The Software may periodically transmit a
 *     hashed installation identifier, domain (or site ID), plugin/app version,
 *     and a truncated (non-reversible) fragment of the license key solely to
 *     validate activation status and enforce licensing. This minimal "phone home"
 *     check contains no personal or content data. If optional telemetry is later
 *     introduced it will be limited to aggregate operational metrics (no PII),
 *     fully documented, and optionally disableable per published instructions.
 *  8. Third-Party Components: The Software may include open source components
 *     covered by their own licenses. See THIRD-PARTY-NOTICES.md. Those licenses
 *     govern their respective components; this License governs all remaining code.
 *  9. Export Compliance: You are responsible for compliance with all applicable
 *     export control and sanctions laws.
 * 10. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF
 *     ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY,
 *     FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
 * 11. Limitation of Liability: IN NO EVENT WILL COMPANY OR AUTHORS BE LIABLE FOR
 *     ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE
 *     DAMAGES, OR LOST PROFITS, EVEN IF ADVISED OF THE POSSIBILITY.
 * 12. Acceptance: Use of the Software constitutes acceptance of the License.
 * 13. Enforcement: Unauthorized reproduction or distribution may result in civil
 *     and criminal penalties and will be prosecuted to the maximum extent allowed
 *     by law.
 * 
 * Authoritative EULA: EULA-v5.1.md (repository root – private) and https://castconductor.com/eula
 * Precedence: If this summary conflicts with the EULA, the EULA governs.
 * Revision: Current EULA revision v5.1 (subject to update; check EULA for current enterprise thresholds).
 * 
 * Full License text available from: licensing@castconductor.com
 * Security reports: security@castconductor.com
 * Commercial inquiries: licensing@castconductor.com
 * 
 * END OF HEADER
 */

/**
 * Background Layer API Controller - Phase 3 Priority 1
 * 
 * Handles background layer CRUD operations for 1920x1080 display architecture
 * Supports static, rotating, video, and color backgrounds with Z-index layering
 */

if (!defined('ABSPATH')) {
    exit;
}

class CastConductor_Background_Controller extends WP_REST_Controller {
    
    protected $namespace = 'castconductor/v5';
    protected $rest_base = 'backgrounds';
    
    public function register_routes() {
        // List all backgrounds
        register_rest_route($this->namespace, '/' . $this->rest_base, [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_items'],
                'permission_callback' => [$this, 'get_items_permissions_check']
            ],
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'create_item'],
                'permission_callback' => [$this, 'create_item_permissions_check'],
                'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE)
            ]
        ]);
        
        // Single background operations
        register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_item'],
                'permission_callback' => [$this, 'get_item_permissions_check']
            ],
            [
                'methods' => WP_REST_Server::EDITABLE,
                'callback' => [$this, 'update_item'],
                'permission_callback' => [$this, 'update_item_permissions_check'],
                'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::EDITABLE)
            ],
            [
                'methods' => WP_REST_Server::DELETABLE,
                'callback' => [$this, 'delete_item'],
                'permission_callback' => [$this, 'delete_item_permissions_check']
            ]
        ]);
        
        // Get active background
        register_rest_route($this->namespace, '/' . $this->rest_base . '/active', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_active_background'],
                'permission_callback' => [$this, 'get_items_permissions_check']
            ]
        ]);
        
        // Activate background
        register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)/activate', [
            [
                'methods' => WP_REST_Server::EDITABLE,
                'callback' => [$this, 'activate_background'],
                'permission_callback' => [$this, 'update_item_permissions_check']
            ]
        ]);
    }
    
    /**
     * Get all backgrounds
     */
    public function get_items($request) {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        $backgrounds = $wpdb->get_results("SELECT * FROM {$table_name} ORDER BY created_at DESC");
        
        if ($wpdb->last_error) {
            return new WP_Error('database_error', 'Failed to retrieve backgrounds: ' . $wpdb->last_error, ['status' => 500]);
        }
        
        $formatted_backgrounds = array_map([$this, 'format_background_response'], $backgrounds);
        
        return rest_ensure_response($formatted_backgrounds);
    }
    
    /**
     * Create a new background
     */
    public function create_item($request) {
        global $wpdb;
        
        $params = $request->get_params();
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        
        // Validate required fields
        $required_fields = ['name', 'type'];
        foreach ($required_fields as $field) {
            if (empty($params[$field])) {
                return new WP_Error('missing_field', "Field '{$field}' is required", ['status' => 400]);
            }
        }
        
        // Validate background type
        $valid_types = ['static', 'rotating', 'video', 'color'];
        if (!in_array($params['type'], $valid_types)) {
            return new WP_Error('invalid_type', 'Background type must be one of: ' . implode(', ', $valid_types), ['status' => 400]);
        }
        
        $background_data = [
            'name' => sanitize_text_field($params['name']),
            'type' => sanitize_text_field($params['type']),
            'config' => wp_json_encode($this->build_background_config($params)),
            'z_index' => isset($params['z_index']) ? intval($params['z_index']) : 0,
            'enabled' => isset($params['enabled']) ? intval($params['enabled']) : 1,
            'is_active' => 0, // New backgrounds are not active by default
            'created_at' => current_time('mysql')
        ];
        
        $result = $wpdb->insert($table_name, $background_data);
        
        if ($result === false) {
            return new WP_Error('creation_failed', 'Failed to create background: ' . $wpdb->last_error, ['status' => 500]);
        }
        
        $background_id = $wpdb->insert_id;
        $created_background = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        
        return rest_ensure_response($this->format_background_response($created_background));
    }
    
    /**
     * Get single background
     */
    public function get_item($request) {
        global $wpdb;
        
        $background_id = $request->get_param('id');
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        
        $background = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        
        if (!$background) {
            return new WP_Error('background_not_found', 'Background not found', ['status' => 404]);
        }
        
        return rest_ensure_response($this->format_background_response($background));
    }
    
    /**
     * Update background
     */
    public function update_item($request) {
        global $wpdb;
        
        $background_id = $request->get_param('id');
        $params = $request->get_params();
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        
        // Check if background exists
        $existing = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        if (!$existing) {
            return new WP_Error('background_not_found', 'Background not found', ['status' => 404]);
        }
        
        $update_data = [];
        
        if (isset($params['name'])) {
            $update_data['name'] = sanitize_text_field($params['name']);
        }
        
        if (isset($params['type'])) {
            $valid_types = ['static', 'rotating', 'video', 'color'];
            if (!in_array($params['type'], $valid_types)) {
                return new WP_Error('invalid_type', 'Background type must be one of: ' . implode(', ', $valid_types), ['status' => 400]);
            }
            $update_data['type'] = sanitize_text_field($params['type']);
        }
        
        if (isset($params['config']) || isset($params['type'])) {
            $update_data['config'] = wp_json_encode($this->build_background_config($params));
        }
        
        if (isset($params['z_index'])) {
            $update_data['z_index'] = intval($params['z_index']);
        }
        
        if (isset($params['enabled'])) {
            $update_data['enabled'] = intval($params['enabled']);
        }
        
        $update_data['updated_at'] = current_time('mysql');
        
        $result = $wpdb->update($table_name, $update_data, ['id' => $background_id]);
        
        if ($result === false) {
            return new WP_Error('update_failed', 'Failed to update background: ' . $wpdb->last_error, ['status' => 500]);
        }
        
        $updated_background = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        
        return rest_ensure_response($this->format_background_response($updated_background));
    }
    
    /**
     * Delete background
     */
    public function delete_item($request) {
        global $wpdb;
        
        $background_id = $request->get_param('id');
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        
        // Check if background exists
        $existing = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        if (!$existing) {
            return new WP_Error('background_not_found', 'Background not found', ['status' => 404]);
        }
        
        // Don't allow deletion of active background
        if ($existing->is_active) {
            return new WP_Error('cannot_delete_active', 'Cannot delete the active background', ['status' => 400]);
        }
        
        $result = $wpdb->delete($table_name, ['id' => $background_id]);
        
        if ($result === false) {
            return new WP_Error('deletion_failed', 'Failed to delete background: ' . $wpdb->last_error, ['status' => 500]);
        }
        
        return rest_ensure_response(['deleted' => true, 'id' => $background_id]);
    }
    
    /**
     * Get active background
     */
    public function get_active_background($request) {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        $active_background = $wpdb->get_row("SELECT * FROM {$table_name} WHERE is_active = 1 AND enabled = 1 LIMIT 1");
        
        if (!$active_background) {
            // Return default background if none active
            return rest_ensure_response([
                'id' => 0,
                'name' => 'Default Background',
                'type' => 'color',
                'config' => [
                    'color' => '#1e3c72',
                    'gradient' => true,
                    'gradient_colors' => ['#1e3c72', '#2a5298']
                ],
                'z_index' => 0,
                'enabled' => true,
                'is_active' => true
            ]);
        }
        
        return rest_ensure_response($this->format_background_response($active_background));
    }
    
    /**
     * Activate a background (deactivates others)
     */
    public function activate_background($request) {
        global $wpdb;
        
        $background_id = $request->get_param('id');
        $table_name = $wpdb->prefix . 'castconductor_backgrounds';
        
        // Check if background exists
        $background = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        if (!$background) {
            return new WP_Error('background_not_found', 'Background not found', ['status' => 404]);
        }
        
        // Start transaction
        $wpdb->query('START TRANSACTION');
        
        // Deactivate all backgrounds
        $deactivate_result = $wpdb->update($table_name, ['is_active' => 0], ['is_active' => 1]);
        
        if ($deactivate_result === false) {
            $wpdb->query('ROLLBACK');
            return new WP_Error('activation_failed', 'Failed to deactivate existing backgrounds: ' . $wpdb->last_error, ['status' => 500]);
        }
        
        // Activate selected background
        $activate_result = $wpdb->update($table_name, ['is_active' => 1, 'enabled' => 1], ['id' => $background_id]);
        
        if ($activate_result === false) {
            $wpdb->query('ROLLBACK');
            return new WP_Error('activation_failed', 'Failed to activate background: ' . $wpdb->last_error, ['status' => 500]);
        }
        
        $wpdb->query('COMMIT');
        
        $activated_background = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table_name} WHERE id = %d", $background_id));
        
        return rest_ensure_response($this->format_background_response($activated_background));
    }
    
    /**
     * Build background configuration from request parameters
     */
    private function build_background_config($params) {
        $config = [];
        
        switch ($params['type']) {
            case 'static':
                $config['image_url'] = isset($params['image_url']) ? esc_url($params['image_url']) : '';
                $config['fit'] = isset($params['fit']) ? sanitize_text_field($params['fit']) : 'cover';
                break;
                
            case 'rotating':
                $config['rotation_interval'] = isset($params['rotation_interval']) ? intval($params['rotation_interval']) : 30;
                $config['images'] = isset($params['images']) ? $params['images'] : [];
                $config['fit'] = isset($params['fit']) ? sanitize_text_field($params['fit']) : 'cover';
                break;
                
            case 'video':
                $config['video_url'] = isset($params['video_url']) ? esc_url($params['video_url']) : '';
                $config['loop'] = isset($params['loop']) ? (bool)$params['loop'] : true;
                $config['muted'] = isset($params['muted']) ? (bool)$params['muted'] : true;
                $config['fit'] = isset($params['fit']) ? sanitize_text_field($params['fit']) : 'cover';
                break;
                
            case 'color':
                $config['color'] = isset($params['color']) ? sanitize_hex_color($params['color']) : '#1e1e1e';
                $config['gradient'] = isset($params['gradient']) ? (bool)$params['gradient'] : false;
                if ($config['gradient']) {
                    $config['gradient_colors'] = isset($params['gradient_colors']) ? $params['gradient_colors'] : [$config['color'], '#333'];
                    $config['gradient_direction'] = isset($params['gradient_direction']) ? sanitize_text_field($params['gradient_direction']) : '135deg';
                }
                break;
        }
        
        return $config;
    }
    
    /**
     * Format background response
     */
    private function format_background_response($background) {
        if (!$background) return null;
        
        return [
            'id' => intval($background->id),
            'name' => $background->name,
            'type' => $background->type,
            'config' => json_decode($background->config, true),
            'z_index' => intval($background->z_index),
            'enabled' => (bool)$background->enabled,
            'is_active' => (bool)$background->is_active,
            'created_at' => $background->created_at,
            'updated_at' => $background->updated_at
        ];
    }
    
    /**
     * Permission callback for GET requests
     * Allows: Administrators and Editors (edit_posts)
     */
    public function get_items_permissions_check($request) {
        return current_user_can('manage_options') || current_user_can('edit_posts');
    }
    
    /**
     * Permission callback for single item GET requests
     */
    public function get_item_permissions_check($request) {
        return current_user_can('manage_options') || current_user_can('edit_posts');
    }
    
    /**
     * Permission callback for CREATE requests
     */
    public function create_item_permissions_check($request) {
        return current_user_can('manage_options') || current_user_can('edit_posts');
    }
    
    /**
     * Permission callback for UPDATE requests
     */
    public function update_item_permissions_check($request) {
        return current_user_can('manage_options') || current_user_can('edit_posts');
    }
    
    /**
     * Permission callback for DELETE requests
     */
    public function delete_item_permissions_check($request) {
        return current_user_can('manage_options') || current_user_can('edit_posts');
    }
}
