<?php

namespace AtlasAiDev\Awfah\REST;

use WordPress\AI_Client\AI_Client;
use WordPress\AiClient\AiClient as AiClientNew;
use WordPress\AiClient\Providers\Models\DTO\ModelRequirements;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Response;

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

class Providers_Controller extends WP_REST_Controller {

    public function __construct() {
        $this->namespace = 'awfah/v1';
        $this->rest_base = 'providers';
    }

    public function register_routes(): void {
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_providers' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        // Models for a specific provider.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<provider>[a-z]+)/models',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_models' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                    'args'                => [
                        'provider' => [
                            'type'              => 'string',
                            'required'          => true,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                    ],
                ],
            ]
        );
    }

    public function permissions_check(): bool {
        return current_user_can( 'manage_options' );
    }

    public function get_providers( WP_REST_Request $request ): WP_REST_Response {
        $providers = [
            [
                'id'    => 'auto',
                'label' => __( 'Auto (any configured provider)', 'ai-workflow-automation-ai-agent-hub' ),
                'type'  => 'auto',
            ],
            [
                'id'    => 'openai',
                'label' => __( 'OpenAI', 'ai-workflow-automation-ai-agent-hub' ),
                'type'  => 'provider',
            ],
            [
                'id'    => 'google',
                'label' => __( 'Google Gemini', 'ai-workflow-automation-ai-agent-hub' ),
                'type'  => 'provider',
            ],
            [
                'id'    => 'anthropic',
                'label' => __( 'Anthropic Claude', 'ai-workflow-automation-ai-agent-hub' ),
                'type'  => 'provider',
            ],
        ];

        $configured_providers  = get_option( 'wp_ai_client_provider_credentials' );
        $final_providers       = [];
        $ai_client_is_present = class_exists( AI_Client::class );

        if ( $ai_client_is_present && is_array( $configured_providers ) ) {
            foreach ( $configured_providers as $provider => $data ) {
                $base_data = [
                    'id'        => $provider,
                    'label'     => $provider,
                    'type'      => 'provider',
                    'supported' => false,
                ];

                if ( $data ) {
                    $base_data['supported'] = true;
                }

                $final_providers[] = $base_data;
            }
        }

        // Preserve static provider list even when the AI client is unavailable.
        if ( ! $ai_client_is_present ) {
            foreach ( $providers as $provider ) {
                $provider['supported'] = false;
                $final_providers[]     = $provider;
            }
        }

        return new WP_REST_Response(
            [
                'providers' => $final_providers,
            ]
        );
    }

    /**
     * GET available models for a specific AI provider.
     */
    public function get_models( WP_REST_Request $request ): WP_REST_Response {
        $provider_id = $request->get_param( 'provider' );

        if ( 'auto' === $provider_id ) {
            return new WP_REST_Response( [ 'models' => [] ] );
        }

        // Try the newer AiClient class first, fall back to the older AI_Client.
        $registry = null;
        if ( class_exists( AiClientNew::class ) ) {
            try {
                $registry = AiClientNew::defaultRegistry();
            } catch ( \Throwable $e ) {
                // Fall through.
            }
        }

        if ( ! $registry && class_exists( AI_Client::class ) && method_exists( AI_Client::class, 'defaultRegistry' ) ) {
            try {
                $registry = AI_Client::defaultRegistry();
            } catch ( \Throwable $e ) {
                // Fall through.
            }
        }

        if ( ! $registry ) {
            return new WP_REST_Response( [ 'models' => [] ] );
        }

        try {
            $requirements  = class_exists( ModelRequirements::class ) ? new ModelRequirements() : null;
            $model_objects = [];

            if ( $requirements && method_exists( $registry, 'findProviderModelsMetadataForSupport' ) ) {
                $model_objects = $registry->findProviderModelsMetadataForSupport( $provider_id, $requirements );
            }

            $models = [];
            foreach ( $model_objects as $model ) {
                $capabilities = [];
                if ( method_exists( $model, 'getSupportedCapabilities' ) ) {
                    foreach ( $model->getSupportedCapabilities() as $cap ) {
                        $capabilities[] = method_exists( $cap, 'value' ) ? $cap->value() : (string) $cap;
                    }
                }

                $models[] = [
                    'id'           => $model->getId(),
                    'name'         => method_exists( $model, 'getName' ) ? $model->getName() : $model->getId(),
                    'capabilities' => $capabilities,
                ];
            }

            return new WP_REST_Response( [ 'models' => $models ] );
        } catch ( \Throwable $e ) {
            return new WP_REST_Response( [ 'models' => [] ] );
        }
    }
}
