<?php

/**
 * Software Distribution API Controller
 *
 * REST API endpoints for software update checking and downloads.
 *
 * @package WooNooW\Api
 */

namespace WooNooW\Api;

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

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use WooNooW\Core\ModuleRegistry;
use WooNooW\Modules\Software\SoftwareManager;
use WooNooW\Modules\Licensing\LicenseManager;

class SoftwareController
{
    /**
     * Register REST routes
     */
    public static function register_routes()
    {
        $namespace = 'woonoow/v1';

        // Public endpoints (authenticated via license key)

        // Check for updates
        register_rest_route($namespace, '/software/check', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'check_update'],
            'permission_callback' => '__return_true',
            'args' => [
                'license_key' => ['required' => true, 'type' => 'string'],
                'slug' => ['required' => true, 'type' => 'string'],
                'version' => ['required' => true, 'type' => 'string'],
                'site_url' => ['required' => false, 'type' => 'string'],
            ],
        ]);

        // Also support POST for update check (some clients prefer this)
        register_rest_route($namespace, '/software/check', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'check_update'],
            'permission_callback' => '__return_true',
        ]);

        // Download file
        register_rest_route($namespace, '/software/download', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'download'],
            'permission_callback' => '__return_true',
            'args' => [
                'token' => ['required' => true, 'type' => 'string'],
            ],
        ]);

        // Get changelog
        register_rest_route($namespace, '/software/changelog', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_changelog'],
            'permission_callback' => '__return_true',
            'args' => [
                'slug' => ['required' => true, 'type' => 'string'],
                'version' => ['required' => false, 'type' => 'string'],
            ],
        ]);

        // Admin endpoints (requires manage_woocommerce)

        // Get all versions for a product
        register_rest_route($namespace, '/software/products/(?P<product_id>\d+)/versions', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_versions'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        // Add new version
        register_rest_route($namespace, '/software/products/(?P<product_id>\d+)/versions', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'add_version'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);
    }

    /**
     * Check for updates
     */
    public static function check_update(WP_REST_Request $request)
    {
        // Check if module is enabled
        if (!ModuleRegistry::is_enabled('software')) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'module_disabled',
                'message' => __('Software distribution module is not enabled', 'woonoow'),
            ], 503);
        }

        // Get parameters from GET or POST body
        $params = $request->get_method() === 'POST'
            ? $request->get_json_params()
            : $request->get_query_params();

        $license_key = sanitize_text_field($params['license_key'] ?? '');
        $slug = sanitize_text_field($params['slug'] ?? '');
        $current_version = sanitize_text_field($params['version'] ?? '');
        $site_url = esc_url_raw($params['site_url'] ?? '');

        if (empty($license_key) || empty($slug) || empty($current_version)) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'missing_params',
                'message' => __('Missing required parameters: license_key, slug, version', 'woonoow'),
            ], 400);
        }

        // Log the check (optional - for analytics)
        do_action('woonoow/software/update_check', $slug, $current_version, $site_url, $license_key);

        $result = SoftwareManager::check_update($license_key, $slug, $current_version);

        $status_code = isset($result['success']) && $result['success'] === false ? 400 : 200;

        return new WP_REST_Response($result, $status_code);
    }

    /**
     * Download file
     */
    public static function download(WP_REST_Request $request)
    {
        // Check if module is enabled
        if (!ModuleRegistry::is_enabled('software')) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'module_disabled',
                'message' => __('Software distribution module is not enabled', 'woonoow'),
            ], 503);
        }

        $token = sanitize_text_field($request->get_param('token'));

        if (empty($token)) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'missing_token',
                'message' => __('Download token is required', 'woonoow'),
            ], 400);
        }

        // Validate token
        $download = SoftwareManager::validate_download_token($token);

        if (is_wp_error($download)) {
            return new WP_REST_Response([
                'success' => false,
                'error' => $download->get_error_code(),
                'message' => $download->get_error_message(),
            ], 403);
        }

        // Validate license is still active
        $license = LicenseManager::get_license($download['license_id']);
        if (!$license || $license['status'] !== 'active') {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'license_inactive',
                'message' => __('License is no longer active', 'woonoow'),
            ], 403);
        }

        // Serve the file
        SoftwareManager::serve_file($download['product_id']);

        // Note: serve_file calls exit, so this won't be reached
        return new WP_REST_Response(['success' => true], 200);
    }

    /**
     * Get changelog
     */
    public static function get_changelog(WP_REST_Request $request)
    {
        $slug = sanitize_text_field($request->get_param('slug'));
        $version = sanitize_text_field($request->get_param('version'));

        if (empty($slug)) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'missing_slug',
                'message' => __('Software slug is required', 'woonoow'),
            ], 400);
        }

        // Get product by slug
        $product = SoftwareManager::get_product_by_slug($slug);

        if (!$product) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'product_not_found',
                'message' => __('Software product not found', 'woonoow'),
            ], 404);
        }

        // Get all versions or specific version
        if ($version) {
            $changelog = SoftwareManager::get_version_changelog($product->get_id(), $version);

            if (!$changelog) {
                return new WP_REST_Response([
                    'success' => false,
                    'error' => 'version_not_found',
                    'message' => __('Version not found', 'woonoow'),
                ], 404);
            }

            return new WP_REST_Response([
                'slug' => $slug,
                'version' => $changelog['version'],
                'release_date' => $changelog['release_date'],
                'changelog' => $changelog['changelog'],
            ], 200);
        }

        // Get all versions
        $versions = SoftwareManager::get_all_versions($product->get_id());

        return new WP_REST_Response([
            'slug' => $slug,
            'versions' => array_map(function ($v) {
                return [
                    'version' => $v['version'],
                    'release_date' => $v['release_date'],
                    'changelog' => $v['changelog'],
                    'download_count' => (int) $v['download_count'],
                ];
            }, $versions),
        ], 200);
    }

    /**
     * Get versions for a product (admin)
     */
    public static function get_versions(WP_REST_Request $request)
    {
        $product_id = (int) $request->get_param('product_id');

        $product = wc_get_product($product_id);
        if (!$product) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'product_not_found',
            ], 404);
        }

        $versions = SoftwareManager::get_all_versions($product_id);
        $config = SoftwareManager::get_product_config($product_id);

        return new WP_REST_Response([
            'product_id' => $product_id,
            'config' => $config,
            'versions' => $versions,
        ], 200);
    }

    /**
     * Add new version (admin)
     */
    public static function add_version(WP_REST_Request $request)
    {
        $product_id = (int) $request->get_param('product_id');
        $params = $request->get_json_params();

        $version = sanitize_text_field($params['version'] ?? '');
        $changelog = wp_kses_post($params['changelog'] ?? '');
        $set_current = (bool) ($params['set_current'] ?? true);

        if (empty($version)) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'missing_version',
                'message' => __('Version number is required', 'woonoow'),
            ], 400);
        }

        $product = wc_get_product($product_id);
        if (!$product) {
            return new WP_REST_Response([
                'success' => false,
                'error' => 'product_not_found',
            ], 404);
        }

        $result = SoftwareManager::add_version($product_id, $version, $changelog, $set_current);

        if (is_wp_error($result)) {
            return new WP_REST_Response([
                'success' => false,
                'error' => $result->get_error_code(),
                'message' => $result->get_error_message(),
            ], 400);
        }

        return new WP_REST_Response([
            'success' => true,
            'version_id' => $result,
            'message' => __('Version added successfully', 'woonoow'),
        ], 201);
    }
}
