<?php
defined( 'ABSPATH' ) || exit;

/**
 * AI provider abstraction layer.
 * Supports: Claude (Anthropic), OpenAI GPT-4o.
 * Swap providers without changing any other code.
 */
class PIPEBU_AI {

    /**
     * Send images + prompt to the configured AI provider.
     * Returns the raw text response or WP_Error.
     *
     * @param string[] $image_paths  Absolute server paths to image files.
     * @param string   $prompt       Text prompt.
     * @return string|WP_Error
     */
    public static function analyze( array $image_paths, string $prompt ) {
        $provider = PIPEBU_Settings::provider();
        $api_key  = PIPEBU_Settings::api_key();
        $model    = PIPEBU_Settings::model();

        if ( ! $api_key ) {
            return new WP_Error( 'pb_no_key', __( 'No API key configured. Go to Pipeline Buster → Settings.', 'pipeline-buster' ) );
        }

        switch ( $provider ) {
            case 'openai':
                return self::call_openai( $api_key, $model, $image_paths, $prompt );
            case 'claude':
            default:
                return self::call_claude( $api_key, $model, $image_paths, $prompt );
        }
    }

    // -------------------------------------------------------------------------
    // Claude (Anthropic Messages API)
    // -------------------------------------------------------------------------

    private static function call_claude( string $api_key, string $model, array $image_paths, string $prompt ) {
        $content = [];

        foreach ( $image_paths as $path ) {
            $encoded = self::encode_image( $path );
            if ( is_wp_error( $encoded ) ) {
                return $encoded;
            }
            $content[] = [
                'type'   => 'image',
                'source' => [
                    'type'       => 'base64',
                    'media_type' => $encoded['mime'],
                    'data'       => $encoded['data'],
                ],
            ];
        }

        $content[] = [ 'type' => 'text', 'text' => $prompt ];

        $body = [
            'model'      => $model,
            'max_tokens' => 8192,
            'messages'   => [
                [ 'role' => 'user', 'content' => $content ],
            ],
        ];

        $response = wp_remote_post(
            'https://api.anthropic.com/v1/messages',
            [
                'headers' => [
                    'x-api-key'         => $api_key,
                    'anthropic-version' => '2023-06-01',
                    'content-type'      => 'application/json',
                ],
                'body'    => wp_json_encode( $body ),
                'timeout' => 300,
            ]
        );

        return self::parse_response( $response, 'claude' );
    }

    // -------------------------------------------------------------------------
    // OpenAI (Chat Completions API with vision)
    // -------------------------------------------------------------------------

    private static function call_openai( string $api_key, string $model, array $image_paths, string $prompt ) {
        $content = [];

        foreach ( $image_paths as $path ) {
            $encoded = self::encode_image( $path );
            if ( is_wp_error( $encoded ) ) {
                return $encoded;
            }
            $content[] = [
                'type'      => 'image_url',
                'image_url' => [
                    'url'    => 'data:' . $encoded['mime'] . ';base64,' . $encoded['data'],
                    'detail' => 'high',
                ],
            ];
        }

        $content[] = [ 'type' => 'text', 'text' => $prompt ];

        $body = [
            'model'      => $model,
            'max_tokens' => 8192,
            'messages'   => [
                [ 'role' => 'user', 'content' => $content ],
            ],
        ];

        $response = wp_remote_post(
            'https://api.openai.com/v1/chat/completions',
            [
                'headers' => [
                    'Authorization' => 'Bearer ' . $api_key,
                    'content-type'  => 'application/json',
                ],
                'body'    => wp_json_encode( $body ),
                'timeout' => 300,
            ]
        );

        return self::parse_response( $response, 'openai' );
    }

    // -------------------------------------------------------------------------
    // Shared helpers
    // -------------------------------------------------------------------------

    private static function encode_image( string $path ): array|WP_Error {
        if ( ! file_exists( $path ) || ! is_readable( $path ) ) {
            /* translators: %s: image file name */
            return new WP_Error( 'pb_file', sprintf( __( 'Image file not readable: %s', 'pipeline-buster' ), basename( $path ) ) );
        }

        $mime_map = [
            'jpg'  => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'png'  => 'image/png',
            'gif'  => 'image/gif',
            'webp' => 'image/webp',
        ];

        $ext  = strtolower( pathinfo( $path, PATHINFO_EXTENSION ) );
        $mime = $mime_map[ $ext ] ?? 'image/jpeg';

        return [
            'mime' => $mime,
            'data' => base64_encode( file_get_contents( $path ) ), // phpcs:ignore WordPress.WP.AlternativeFunctions
        ];
    }

    private static function parse_response( $response, string $provider ): string|WP_Error {
        if ( is_wp_error( $response ) ) {
            return $response;
        }

        $code = wp_remote_retrieve_response_code( $response );
        $body = json_decode( wp_remote_retrieve_body( $response ), true );

        if ( $code !== 200 ) {
            $msg = $body['error']['message'] ?? sprintf( 'HTTP %d', $code );
            return new WP_Error( 'pipebu_api_error', $msg, [
                'status' => $code,
                'detail' => substr( $msg, 0, 200 ),
            ] );
        }

        if ( $provider === 'claude' ) {
            return $body['content'][0]['text'] ?? '';
        }

        // OpenAI
        return $body['choices'][0]['message']['content'] ?? '';
    }
}
