<?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.
 * 
 * END OF HEADER
 */

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

/**
 * Menu Builder REST Controller
 * 
 * Handles CRUD for menus, menu items, and button bindings
 * Provides complete menu configuration for Roku app
 */
class CastConductor_Menu_Controller extends WP_REST_Controller {
    protected $namespace = 'castconductor/v5';

    public function register_routes() {
        // Complete menu configuration for Roku (public)
        register_rest_route($this->namespace, '/menus/config', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_menu_config'],
                'permission_callback' => '__return_true' // Public for Roku app
            ]
        ]);

        // CRUD menus (admin)
        register_rest_route($this->namespace, '/menus', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_menus'],
                'permission_callback' => [$this, 'permission_admin']
            ],
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'create_menu'],
                'permission_callback' => [$this, 'permission_admin']
            ]
        ]);

        register_rest_route($this->namespace, '/menus/(?P<id>[\d]+)', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_menu'],
                'permission_callback' => [$this, 'permission_admin']
            ],
            [
                'methods' => WP_REST_Server::EDITABLE,
                'callback' => [$this, 'update_menu'],
                'permission_callback' => [$this, 'permission_admin']
            ],
            [
                'methods' => WP_REST_Server::DELETABLE,
                'callback' => [$this, 'delete_menu'],
                'permission_callback' => [$this, 'permission_admin']
            ]
        ]);

        // Menu items
        register_rest_route($this->namespace, '/menus/(?P<menu_id>[\d]+)/items', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_menu_items'],
                'permission_callback' => [$this, 'permission_admin']
            ],
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'create_menu_item'],
                'permission_callback' => [$this, 'permission_admin']
            ]
        ]);

        register_rest_route($this->namespace, '/menus/items/(?P<id>[\d]+)', [
            [
                'methods' => WP_REST_Server::EDITABLE,
                'callback' => [$this, 'update_menu_item'],
                'permission_callback' => [$this, 'permission_admin']
            ],
            [
                'methods' => WP_REST_Server::DELETABLE,
                'callback' => [$this, 'delete_menu_item'],
                'permission_callback' => [$this, 'permission_admin']
            ]
        ]);

        // Reorder menu items
        register_rest_route($this->namespace, '/menus/(?P<menu_id>[\d]+)/reorder', [
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'reorder_menu_items'],
                'permission_callback' => [$this, 'permission_admin']
            ]
        ]);

        // Button bindings
        register_rest_route($this->namespace, '/button-bindings', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_button_bindings'],
                'permission_callback' => [$this, 'permission_admin']
            ],
            [
                'methods' => WP_REST_Server::EDITABLE,
                'callback' => [$this, 'update_button_bindings'],
                'permission_callback' => [$this, 'permission_admin']
            ]
        ]);
    }

    public function permission_admin() {
        return current_user_can('manage_options') || current_user_can('edit_posts');
    }

    /**
     * Get complete menu configuration for Roku app
     * Public endpoint - returns everything needed to render menus
     */
    public function get_menu_config($request) {
        global $wpdb;
        $db = new CastConductor_Database();

        // Get all button bindings
        $bindings_table = $db->get_table_name('button_bindings');
        $bindings = $wpdb->get_results("SELECT * FROM {$bindings_table} WHERE enabled = 1");
        
        // Format button bindings
        $button_bindings = [];
        foreach ($bindings as $binding) {
            $btn = [
                'button' => $binding->trigger_button,
                'type' => $binding->binding_type
            ];
            
            if ($binding->binding_type === 'menu' && $binding->menu_id) {
                $btn['menu_id'] = (int) $binding->menu_id;
            } elseif ($binding->binding_type === 'content_block' && $binding->content_block_id) {
                $btn['content_block_id'] = (int) $binding->content_block_id;
                $btn['position'] = $binding->overlay_position;
                $btn['animation'] = $binding->overlay_animation;
                $btn['width'] = (int) $binding->overlay_width;
                $btn['height'] = (int) $binding->overlay_height;
                $btn['background'] = $binding->overlay_background;
            }
            
            $button_bindings[] = $btn;
        }

        // Get all menus with their items
        $menus_table = $db->get_table_name('menus');
        $items_table = $db->get_table_name('menu_items');
        $blocks_table = $db->get_table_name('content_blocks');
        
        $menus_rows = $wpdb->get_results("SELECT * FROM {$menus_table} WHERE enabled = 1");
        
        $menus = [];
        foreach ($menus_rows as $menu) {
            // Get items for this menu
            $items = $wpdb->get_results($wpdb->prepare("
                SELECT mi.*, cb.name as content_block_name, cb.type as content_block_type
                FROM {$items_table} mi
                LEFT JOIN {$blocks_table} cb ON mi.content_block_id = cb.id
                WHERE mi.menu_id = %d AND mi.enabled = 1
                ORDER BY mi.sort_order ASC
            ", $menu->id));
            
            $formatted_items = [];
            foreach ($items as $item) {
                $formatted_item = [
                    'id' => (int) $item->id,
                    'label' => $item->display_label,
                    'icon' => $item->icon,
                    'type' => $item->item_type
                ];
                
                if ($item->item_type === 'content_block' && $item->content_block_id) {
                    $formatted_item['content_block_id'] = (int) $item->content_block_id;
                    $formatted_item['content_block_type'] = $item->content_block_type;
                } elseif ($item->item_type === 'submenu' && $item->submenu_id) {
                    $formatted_item['submenu_id'] = (int) $item->submenu_id;
                } elseif ($item->item_type === 'action') {
                    $formatted_item['action'] = $item->action_type;
                    if ($item->action_data) {
                        $formatted_item['action_data'] = json_decode($item->action_data, true);
                    }
                }
                
                $formatted_items[] = $formatted_item;
            }
            
            $menus[] = [
                'id' => (int) $menu->id,
                'name' => $menu->name,
                'position' => $menu->position,
                'animation' => $menu->animation,
                'width' => (int) $menu->width,
                'height' => (int) $menu->height,
                'style' => [
                    'background_color' => $menu->background_color,
                    'background_image' => $menu->background_image ?? '',
                    'overlay_opacity' => (float) ($menu->overlay_opacity ?? 0.9),
                    'overlay_enabled' => (bool) ($menu->overlay_enabled ?? 1),
                    'text_color' => $menu->text_color,
                    'accent_color' => $menu->accent_color,
                    'font_family' => $menu->font_family,
                    'font_size' => (int) ($menu->font_size ?? 18),
                    'item_padding' => (int) $menu->item_padding
                ],
                'show_live_stream_button' => (bool) ($menu->show_live_stream_button ?? 1),
                'items' => $formatted_items
            ];
        }

        return CastConductor_REST_API::format_response([
            'button_bindings' => $button_bindings,
            'menus' => $menus
        ]);
    }

    /**
     * Get all menus (admin)
     */
    public function get_menus($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menus');
        $items_table = $db->get_table_name('menu_items');
        
        $menus = $wpdb->get_results("SELECT * FROM {$table} ORDER BY id ASC");
        
        // Add item count for each menu
        foreach ($menus as &$menu) {
            $menu->item_count = (int) $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$items_table} WHERE menu_id = %d",
                $menu->id
            ));
        }
        
        return CastConductor_REST_API::format_response($menus);
    }

    /**
     * Create a new menu
     */
    public function create_menu($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menus');

        $data = [
            'name' => sanitize_text_field($request->get_param('name') ?: 'New Menu'),
            'trigger_button' => $request->get_param('trigger_button') ? sanitize_text_field($request->get_param('trigger_button')) : null,
            'position' => sanitize_text_field($request->get_param('position') ?: 'left'),
            'animation' => sanitize_text_field($request->get_param('animation') ?: 'slide'),
            'width' => (int) ($request->get_param('width') ?: 400),
            'height' => (int) ($request->get_param('height') ?: 720),
            'background_color' => sanitize_text_field($request->get_param('background_color') ?: '#1a1a1aEE'),
            'background_image' => sanitize_url($request->get_param('background_image') ?: ''),
            'text_color' => sanitize_text_field($request->get_param('text_color') ?: '#FFFFFF'),
            'accent_color' => sanitize_text_field($request->get_param('accent_color') ?: '#8b5cf6'),
            'font_family' => sanitize_text_field($request->get_param('font_family') ?: 'Lexend'),
            'item_padding' => (int) ($request->get_param('item_padding') ?: 16),
            'enabled' => 1
        ];

        $result = $wpdb->insert($table, $data);
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to create menu', ['status' => 500]);
        }

        $menu_id = $wpdb->insert_id;
        $menu = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $menu_id));
        
        return CastConductor_REST_API::format_response($menu);
    }

    /**
     * Get a single menu with its items
     */
    public function get_menu($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menus');
        $items_table = $db->get_table_name('menu_items');
        $blocks_table = $db->get_table_name('content_blocks');
        
        $menu_id = (int) $request->get_param('id');
        $menu = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $menu_id));
        
        if (!$menu) {
            return new WP_Error('not_found', 'Menu not found', ['status' => 404]);
        }

        // Get items with content block info
        $items = $wpdb->get_results($wpdb->prepare("
            SELECT mi.*, cb.name as content_block_name, cb.type as content_block_type
            FROM {$items_table} mi
            LEFT JOIN {$blocks_table} cb ON mi.content_block_id = cb.id
            WHERE mi.menu_id = %d
            ORDER BY mi.sort_order ASC
        ", $menu_id));
        
        $menu->items = $items;
        
        return CastConductor_REST_API::format_response($menu);
    }

    /**
     * Update a menu
     */
    public function update_menu($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menus');
        
        $menu_id = (int) $request->get_param('id');
        
        // Build update data from allowed fields
        $allowed_fields = ['name', 'trigger_button', 'position', 'animation', 'width', 'height', 
                          'background_color', 'background_image', 'overlay_opacity', 'overlay_enabled',
                          'text_color', 'accent_color', 'font_family', 'font_size', 'item_padding', 
                          'show_live_stream_button', 'enabled'];
        
        $data = [];
        foreach ($allowed_fields as $field) {
            $value = $request->get_param($field);
            if ($value !== null) {
                if (in_array($field, ['width', 'height', 'item_padding', 'enabled', 'overlay_enabled', 'font_size', 'show_live_stream_button'])) {
                    $data[$field] = (int) $value;
                } elseif ($field === 'overlay_opacity') {
                    $data[$field] = (float) $value;
                } elseif ($field === 'background_image') {
                    $data[$field] = sanitize_url($value);
                } else {
                    $data[$field] = sanitize_text_field($value);
                }
            }
        }
        
        if (empty($data)) {
            return new WP_Error('no_data', 'No fields to update', ['status' => 400]);
        }

        $result = $wpdb->update($table, $data, ['id' => $menu_id]);
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to update menu', ['status' => 500]);
        }

        $menu = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $menu_id));
        return CastConductor_REST_API::format_response($menu);
    }

    /**
     * Delete a menu
     */
    public function delete_menu($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menus');
        
        $menu_id = (int) $request->get_param('id');
        
        // Items will be deleted by CASCADE
        $result = $wpdb->delete($table, ['id' => $menu_id]);
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to delete menu', ['status' => 500]);
        }

        return CastConductor_REST_API::format_response(['deleted' => true, 'id' => $menu_id]);
    }

    /**
     * Get items for a menu
     */
    public function get_menu_items($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $items_table = $db->get_table_name('menu_items');
        $blocks_table = $db->get_table_name('content_blocks');
        
        $menu_id = (int) $request->get_param('menu_id');
        
        $items = $wpdb->get_results($wpdb->prepare("
            SELECT mi.*, cb.name as content_block_name, cb.type as content_block_type
            FROM {$items_table} mi
            LEFT JOIN {$blocks_table} cb ON mi.content_block_id = cb.id
            WHERE mi.menu_id = %d
            ORDER BY mi.sort_order ASC
        ", $menu_id));
        
        return CastConductor_REST_API::format_response($items);
    }

    /**
     * Create a menu item
     */
    public function create_menu_item($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menu_items');
        
        $menu_id = (int) $request->get_param('menu_id');
        
        // Get max sort_order for this menu
        $max_order = (int) $wpdb->get_var($wpdb->prepare(
            "SELECT MAX(sort_order) FROM {$table} WHERE menu_id = %d",
            $menu_id
        ));

        $data = [
            'menu_id' => $menu_id,
            'display_label' => sanitize_text_field($request->get_param('display_label') ?: 'New Item'),
            'icon' => sanitize_text_field($request->get_param('icon') ?: ''),
            'item_type' => sanitize_text_field($request->get_param('item_type') ?: 'content_block'),
            'content_block_id' => $request->get_param('content_block_id') ? (int) $request->get_param('content_block_id') : null,
            'submenu_id' => $request->get_param('submenu_id') ? (int) $request->get_param('submenu_id') : null,
            'action_type' => sanitize_text_field($request->get_param('action_type') ?: ''),
            'action_data' => $request->get_param('action_data') ? wp_json_encode($request->get_param('action_data')) : null,
            'sort_order' => $max_order + 1,
            'enabled' => 1
        ];

        $result = $wpdb->insert($table, $data);
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to create menu item', ['status' => 500]);
        }

        $item_id = $wpdb->insert_id;
        $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $item_id));
        
        return CastConductor_REST_API::format_response($item);
    }

    /**
     * Update a menu item
     */
    public function update_menu_item($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menu_items');
        
        $item_id = (int) $request->get_param('id');
        
        $allowed_fields = ['display_label', 'icon', 'item_type', 'content_block_id', 'submenu_id', 
                          'action_type', 'action_data', 'sort_order', 'enabled'];
        
        $data = [];
        foreach ($allowed_fields as $field) {
            $value = $request->get_param($field);
            if ($value !== null) {
                if (in_array($field, ['content_block_id', 'submenu_id', 'sort_order', 'enabled'])) {
                    $data[$field] = $value !== '' ? (int) $value : null;
                } elseif ($field === 'action_data') {
                    $data[$field] = is_array($value) ? wp_json_encode($value) : $value;
                } else {
                    $data[$field] = sanitize_text_field($value);
                }
            }
        }
        
        if (empty($data)) {
            return new WP_Error('no_data', 'No fields to update', ['status' => 400]);
        }

        $result = $wpdb->update($table, $data, ['id' => $item_id]);
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to update menu item', ['status' => 500]);
        }

        $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $item_id));
        return CastConductor_REST_API::format_response($item);
    }

    /**
     * Delete a menu item
     */
    public function delete_menu_item($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menu_items');
        
        $item_id = (int) $request->get_param('id');
        
        $result = $wpdb->delete($table, ['id' => $item_id]);
        
        if ($result === false) {
            return new WP_Error('db_error', 'Failed to delete menu item', ['status' => 500]);
        }

        return CastConductor_REST_API::format_response(['deleted' => true, 'id' => $item_id]);
    }

    /**
     * Reorder menu items (drag-and-drop)
     */
    public function reorder_menu_items($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('menu_items');
        
        $menu_id = (int) $request->get_param('menu_id');
        $item_ids = $request->get_param('item_ids');
        
        if (!is_array($item_ids)) {
            return new WP_Error('invalid_data', 'item_ids must be an array', ['status' => 400]);
        }

        // Update sort_order for each item
        foreach ($item_ids as $index => $item_id) {
            $wpdb->update(
                $table,
                ['sort_order' => $index],
                ['id' => (int) $item_id, 'menu_id' => $menu_id]
            );
        }

        return CastConductor_REST_API::format_response(['reordered' => true, 'menu_id' => $menu_id]);
    }

    /**
     * Get all button bindings
     */
    public function get_button_bindings($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('button_bindings');
        
        $bindings = $wpdb->get_results("SELECT * FROM {$table} ORDER BY trigger_button ASC");
        
        // If no bindings exist, return defaults for all buttons
        if (empty($bindings)) {
            $default_buttons = ['menu', 'up', 'down', 'left', 'right'];
            $bindings = [];
            foreach ($default_buttons as $btn) {
                $bindings[] = (object) [
                    'id' => null,
                    'trigger_button' => $btn,
                    'binding_type' => 'disabled',
                    'menu_id' => null,
                    'content_block_id' => null,
                    'enabled' => 1
                ];
            }
        }
        
        return CastConductor_REST_API::format_response($bindings);
    }

    /**
     * Update button bindings (batch update)
     */
    public function update_button_bindings($request) {
        global $wpdb;
        $db = new CastConductor_Database();
        $table = $db->get_table_name('button_bindings');
        
        $bindings = $request->get_param('bindings');
        
        if (!is_array($bindings)) {
            return new WP_Error('invalid_data', 'bindings must be an array', ['status' => 400]);
        }

        foreach ($bindings as $binding) {
            $trigger = sanitize_text_field($binding['trigger_button'] ?? '');
            if (!$trigger) continue;
            
            $data = [
                'trigger_button' => $trigger,
                'binding_type' => sanitize_text_field($binding['binding_type'] ?? 'disabled'),
                'menu_id' => isset($binding['menu_id']) ? (int) $binding['menu_id'] : null,
                'content_block_id' => isset($binding['content_block_id']) ? (int) $binding['content_block_id'] : null,
                'overlay_position' => sanitize_text_field($binding['overlay_position'] ?? 'bottom'),
                'overlay_animation' => sanitize_text_field($binding['overlay_animation'] ?? 'slide'),
                'overlay_width' => (int) ($binding['overlay_width'] ?? 1280),
                'overlay_height' => (int) ($binding['overlay_height'] ?? 400),
                'overlay_background' => sanitize_text_field($binding['overlay_background'] ?? '#000000CC'),
                'enabled' => 1
            ];
            
            // Upsert: try update first, insert if no rows affected
            $existing = $wpdb->get_var($wpdb->prepare(
                "SELECT id FROM {$table} WHERE trigger_button = %s",
                $trigger
            ));
            
            if ($existing) {
                $wpdb->update($table, $data, ['trigger_button' => $trigger]);
            } else {
                $wpdb->insert($table, $data);
            }
        }

        return $this->get_button_bindings($request);
    }
}
