<?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
 */

/**
 * Artwork API Controller - Enhanced Album Artwork Discovery Endpoint
 * 
 * Provides the /wp-json/castconductor/v5/artwork/search endpoint
 * for the proven V4 breakthrough artwork system.
 */

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

class CastConductor_Artwork_Controller extends WP_REST_Controller {
    
    protected $namespace = 'castconductor/v5';
    protected $rest_base = 'artwork';
    
    public function register_routes() {
        // Main artwork search endpoint
        register_rest_route($this->namespace, '/' . $this->rest_base . '/search', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'search_artwork'],
                'permission_callback' => '__return_true', // Public endpoint for Roku app
                'args' => [
                    'artist' => [
                        'required' => true,
                        'type' => 'string',
                        'description' => 'Artist name',
                        'sanitize_callback' => 'sanitize_text_field'
                    ],
                    'title' => [
                        'required' => true,
                        'type' => 'string', 
                        'description' => 'Track title',
                        'sanitize_callback' => 'sanitize_text_field'
                    ],
                    'album' => [
                        'required' => false,
                        'type' => 'string',
                        'description' => 'Album name (optional)',
                        'sanitize_callback' => 'sanitize_text_field'
                    ],
                    'size' => [
                        'required' => false,
                        'type' => 'string',
                        'default' => '600x600',
                        'description' => 'Target artwork size (600x600, 800x800, 200x200)',
                        'enum' => ['600x600', '800x800', '200x200', '400x400'],
                        'sanitize_callback' => 'sanitize_text_field'
                    ]
                ]
            ]
        ]);
        
        // Artwork configuration endpoint (admin only)
        register_rest_route($this->namespace, '/' . $this->rest_base . '/config', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_artwork_config'],
                'permission_callback' => [$this, 'check_admin_permission']
            ],
            [
                'methods' => WP_REST_Server::EDITABLE,
                'callback' => [$this, 'update_artwork_config'],
                'permission_callback' => [$this, 'check_admin_permission'],
                'args' => [
                    'enabled' => [
                        'type' => 'boolean',
                        'description' => 'Enable/disable artwork discovery'
                    ],
                    'apis' => [
                        'type' => 'array',
                        'description' => 'Active API sources',
                        'items' => [
                            'type' => 'string',
                            'enum' => ['itunes', 'musicbrainz', 'deezer']
                        ]
                    ],
                    'cache_duration' => [
                        'type' => 'integer',
                        'minimum' => 300,
                        'maximum' => 86400,
                        'description' => 'Cache duration in seconds'
                    ],
                    'search_timeout' => [
                        'type' => 'integer',
                        'minimum' => 5,
                        'maximum' => 30,
                        'description' => 'API search timeout in seconds'
                    ],
                    'fallback_image' => [
                        'type' => 'string',
                        'description' => 'Fallback image URL',
                        'format' => 'uri'
                    ]
                ]
            ]
        ]);
        
        // Clear artwork cache endpoint (admin only)
        register_rest_route($this->namespace, '/' . $this->rest_base . '/cache/clear', [
            [
                'methods' => WP_REST_Server::DELETABLE,
                'callback' => [$this, 'clear_artwork_cache'],
                'permission_callback' => [$this, 'check_admin_permission']
            ]
        ]);
    }
    
    /**
     * Main artwork search endpoint handler
     * 
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function search_artwork($request) {
        $artist = $request->get_param('artist');
        $title = $request->get_param('title');
        $album = $request->get_param('album') ?: '';
        $size = $request->get_param('size') ?: '600x600';
        
        // Validate artwork discovery is enabled
        if (!get_option('castconductor_artwork_enabled', true)) {
            return rest_ensure_response([
                'success' => false,
                'error' => 'artwork_disabled',
                'message' => 'Artwork discovery is disabled',
                'data' => $this->get_fallback_response($size),
                'timestamp' => current_time('c'),
                'version' => '5.0.0'
            ]);
        }
        
        // Perform artwork search
        $artwork_search = new CastConductor_Artwork_Search();
        $artwork_result = $artwork_search->search_artwork($artist, $title, $album, $size);
        
        if ($artwork_result) {
            return rest_ensure_response([
                'success' => true,
                'data' => [
                    'artwork_url' => $artwork_result['url'],
                    'source' => $artwork_result['source'],
                    'original_size' => $artwork_result['original_size'],
                    'roku_optimized' => $artwork_result['roku_optimized'],
                    'metadata' => [
                        'artist' => $artwork_result['artist'] ?? $artist,
                        'title' => $artwork_result['title'] ?? $title,
                        'album' => $artwork_result['album'] ?? $album
                    ],
                    'search_info' => [
                        'query_artist' => $artist,
                        'query_title' => $title,
                        'query_album' => $album,
                        'target_size' => $size
                    ]
                ],
                'timestamp' => current_time('c'),
                'version' => '5.0.0'
            ]);
        }
        
        // Return error response if no artwork found
        return rest_ensure_response([
            'success' => false,
            'error' => 'no_artwork_found',
            'message' => 'No artwork found after searching all available APIs',
            'data' => $this->get_fallback_response($size),
            'search_info' => [
                'query_artist' => $artist,
                'query_title' => $title,
                'query_album' => $album,
                'target_size' => $size,
                'apis_searched' => ['itunes', 'musicbrainz', 'deezer']
            ],
            'timestamp' => current_time('c'),
            'version' => '5.0.0'
        ]);
    }
    
    /**
     * Get artwork configuration
     */
    public function get_artwork_config($request) {
        return rest_ensure_response([
            'success' => true,
            'data' => [
                'enabled' => get_option('castconductor_artwork_enabled', true),
                'apis' => get_option('castconductor_artwork_apis', ['itunes', 'musicbrainz', 'deezer']),
                'cache_duration' => get_option('castconductor_artwork_cache_duration', 3600),
                'search_timeout' => get_option('castconductor_artwork_search_timeout', 10),
                'fallback_image' => get_option('castconductor_artwork_default_image', ''),
                'max_resolution' => '1280x720', // Roku limit
                'available_sizes' => ['600x600', '800x800', '200x200', '400x400'],
                'resize_methods' => ['smart_crop', 'letterbox']
            ],
            'timestamp' => current_time('c'),
            'version' => '5.0.0'
        ]);
    }
    
    /**
     * Update artwork configuration
     */
    public function update_artwork_config($request) {
        $updated_settings = [];
        
        // Update enabled status
        if ($request->has_param('enabled')) {
            update_option('castconductor_artwork_enabled', $request->get_param('enabled'));
            $updated_settings['enabled'] = $request->get_param('enabled');
        }
        
        // Update active APIs
        if ($request->has_param('apis')) {
            $apis = $request->get_param('apis');
            update_option('castconductor_artwork_apis', $apis);
            $updated_settings['apis'] = $apis;
        }
        
        // Update cache duration
        if ($request->has_param('cache_duration')) {
            $cache_duration = $request->get_param('cache_duration');
            update_option('castconductor_artwork_cache_duration', $cache_duration);
            $updated_settings['cache_duration'] = $cache_duration;
        }
        
        // Update search timeout
        if ($request->has_param('search_timeout')) {
            $search_timeout = $request->get_param('search_timeout');
            update_option('castconductor_artwork_search_timeout', $search_timeout);
            $updated_settings['search_timeout'] = $search_timeout;
        }
        
        // Update fallback image
        if ($request->has_param('fallback_image')) {
            $fallback_image = $request->get_param('fallback_image');
            update_option('castconductor_artwork_default_image', $fallback_image);
            $updated_settings['fallback_image'] = $fallback_image;
        }
        
        return rest_ensure_response([
            'success' => true,
            'message' => 'Artwork configuration updated successfully',
            'data' => $updated_settings,
            'timestamp' => current_time('c'),
            'version' => '5.0.0'
        ]);
    }
    
    /**
     * Clear artwork cache
     */
    public function clear_artwork_cache($request) {
        global $wpdb;
        
        // Delete all artwork-related transients
        $deleted = $wpdb->query(
            "DELETE FROM {$wpdb->options} 
             WHERE option_name LIKE '_transient_cc_artwork_%' 
             OR option_name LIKE '_transient_timeout_cc_artwork_%'"
        );
        
        return rest_ensure_response([
            'success' => true,
            'message' => 'Artwork cache cleared successfully',
            'data' => [
                'cache_entries_deleted' => $deleted / 2, // Each transient has a timeout entry
                'cleared_at' => current_time('c')
            ],
            'timestamp' => current_time('c'),
            'version' => '5.0.0'
        ]);
    }
    
    /**
     * Get fallback response when artwork not found
     */
    private function get_fallback_response($size) {
        $fallback_url = get_option('castconductor_artwork_default_image', '');
        
        if (empty($fallback_url)) {
            $fallback_url = plugin_dir_url(__FILE__) . '../../wizard-content/default-square-logo-600x600.png';
        }
        
        return [
            'artwork_url' => $fallback_url,
            'source' => 'fallback',
            'original_size' => $size,
            'roku_optimized' => [
                'target_size' => $size,
                'roku_compliant' => true,
                'processed_at' => current_time('c')
            ]
        ];
    }
    
    /**
     * Check admin permission for protected endpoints
     * Allows: Administrators, castconductor_admin role, and Editors (edit_posts)
     */
    public function check_admin_permission() {
        return current_user_can('manage_options') || current_user_can('castconductor_admin') || current_user_can('edit_posts');
    }
}
