<?php

/**
 * Changelog REST API Controller
 *
 * Handles changelog data retrieval
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   3.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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


/**
 * Changelog controller class
 */


class ChangelogController extends BaseController {
    
    /**
     * Rest base
     *
     * @var string
     */
    protected $rest_base = 'changelog';
    
    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Get changelog
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            [
                [
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => [$this, 'get_changelog'],
                    'permission_callback' => [$this, 'check_permission'],
                ],
            ]
        );
    }
    
    /**
     * Get changelog data
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_changelog(WP_REST_Request $request) {
        // Try to get cached changelog
        $cached_changelog = get_transient('prorank_seo_changelog');
        
        if ($cached_changelog !== false) {
            return new WP_REST_Response($cached_changelog, 200);
        }
        
        // Fetch from remote API or local file
        $changelog = $this->fetch_changelog();
        
        if (is_wp_error($changelog)) {
            // Return hardcoded recent releases as fallback
            $changelog = $this->get_fallback_changelog();
        }
        
        // Cache for 24 hours
        set_transient('prorank_seo_changelog', $changelog, DAY_IN_SECONDS);
        
        return new WP_REST_Response($changelog, 200);
    }
    
    /**
     * Fetch changelog from remote API
     *
     * @return array|WP_Error
     */
    private function fetch_changelog() {
        $response = wp_remote_get('https://prorank.io/api/changelog', [
            'timeout' => 10,
            'headers' => [
                'Accept' => 'application/json',
            ],
        ]);
        
        if (is_wp_error($response)) {
            return $response;
        }
        
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        
        if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) {
            return new WP_Error('invalid_response', 'Invalid changelog data received');
        }
        
        return [
            'success'         => true,
            'current_version' => PRORANK_SEO_VERSION,
            'releases'        => $data['releases'] ?? $this->get_fallback_releases(),
        ];
    }
    
    /**
     * Get fallback changelog data
     *
     * @return array
     */
    private function get_fallback_changelog(): array {
        return [
            'success'         => true,
            'current_version' => PRORANK_SEO_VERSION,
            'releases'        => $this->get_fallback_releases(),
        ];
    }
    
    /**
     * Get fallback releases
     *
     * @return array
     */
    private function get_fallback_releases(): array {
        return [
            [
                'version'    => PRORANK_SEO_VERSION,
                'date'       => gmdate('Y-m-d'),
                'type'       => 'current',
                'breaking'   => false,
                'highlights' => [
                    __('Current installed ProRank SEO release', 'prorank-seo'),
                ],
                'changes'    => [
                    'improved' => [
                        __('If the remote changelog is unavailable, view the published release notes on prorank.io/changelog.', 'prorank-seo'),
                    ],
                    'fixed' => [
                        __('Remote changelog feed unavailable.', 'prorank-seo'),
                    ],
                    'added' => [
                        __('See the live public changelog for verified release notes.', 'prorank-seo'),
                    ],
                    'removed' => [],
                    'security' => [],
                ],
            ],
        ];
    }
}
