<?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',
            ],
        ];

        $final_providers = [];

        // Friendly labels for known provider ids.
        $labels = [];
        foreach ( $providers as $p ) {
            $labels[ $p['id'] ] = $p['label'];
        }

        // Detect configured providers from the AI Client registry. Credentials now
        // live in the core "Connectors" system (options-connectors.php), not the
        // legacy wp_ai_client_provider_credentials option, so we ask the registry
        // directly — the same source WordPress core's connectors.php uses.
        $registry = null;
        if ( class_exists( AiClientNew::class ) ) {
            try {
                $registry = AiClientNew::defaultRegistry();
            } catch ( \Throwable $e ) {
                $registry = null;
            }
        }

        if ( $registry && method_exists( $registry, 'getRegisteredProviderIds' ) ) {
            foreach ( array_filter( (array) $registry->getRegisteredProviderIds() ) as $provider_id ) {
                $supported = false;
                if ( method_exists( AiClientNew::class, 'isConfigured' ) ) {
                    try {
                        $supported = (bool) AiClientNew::isConfigured( $provider_id );
                    } catch ( \Throwable $e ) {
                        $supported = false;
                    }
                }

                // Prefer a known friendly label, else the provider's own metadata name.
                $label = $labels[ $provider_id ] ?? $provider_id;
                if ( ! isset( $labels[ $provider_id ] ) && method_exists( $registry, 'getProviderClassName' ) ) {
                    try {
                        $class = $registry->getProviderClassName( $provider_id );
                        if ( $class && method_exists( $class, 'metadata' ) ) {
                            $meta = $class::metadata();
                            if ( method_exists( $meta, 'getName' ) ) {
                                $label = $meta->getName();
                            }
                        }
                    } catch ( \Throwable $e ) {
                        $label = $provider_id;
                    }
                }

                $final_providers[] = [
                    'id'        => $provider_id,
                    'label'     => $label,
                    'type'      => 'provider',
                    'supported' => $supported,
                ];
            }
        }

        // Fallback: legacy credentials option, then the static list, so the panel is
        // never empty on environments without the new registry.
        if ( empty( $final_providers ) ) {
            $configured_providers = get_option( 'wp_ai_client_provider_credentials' );
            if ( is_array( $configured_providers ) && ! empty( $configured_providers ) ) {
                foreach ( $configured_providers as $provider => $data ) {
                    $final_providers[] = [
                        'id'        => $provider,
                        'label'     => $labels[ $provider ] ?? $provider,
                        'type'      => 'provider',
                        'supported' => (bool) $data,
                    ];
                }
            } else {
                foreach ( $providers as $provider ) {
                    if ( 'auto' === $provider['id'] ) {
                        continue;
                    }
                    $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' => [] ] );
        }
    }
}
