<?php
/**
 * =====================================================================
 *  WordAI Agent — Anthropic Embeddings via Voyage AI
 *  -------------------------------------------------------------------
 *  - Anthropic chat provider uses Voyage AI for embeddings
 *  - Stores vectors under provider = 'anthropic' in shared embeddings DB
 *  - Supports provider-specific indexing and RAG retrieval
 * =====================================================================
 */

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

class SftcyWordaiAgentAnthropic {

    const PROVIDER                = 'anthropic';
    const SETTINGS_OPTION         = 'sc_wordai_agent_anthropic_embedding_settings';
    const DEFAULT_EMBEDDING_MODEL = 'voyage-4-lite';
    const EMBEDDING_ENDPOINT      = 'https://api.voyageai.com/v1/embeddings';

    public static function get_default_settings() {
        return [
            'voyage_api_key' => '',
        ];
    }

    public static function get_settings() {
        $saved = get_option( self::SETTINGS_OPTION, [] );
        $saved = is_array( $saved ) ? $saved : [];
        return wp_parse_args( $saved, self::get_default_settings() );
    }

    public static function save_settings( array $settings ) {
        $current = self::get_settings();
        $merged  = wp_parse_args( $settings, $current );

        $merged['voyage_api_key'] = isset( $merged['voyage_api_key'] )
            ? trim( sanitize_text_field( $merged['voyage_api_key'] ) )
            : '';

        update_option( self::SETTINGS_OPTION, $merged );

        return $merged;
    }

    public static function get_voyage_api_key() {
        $settings = self::get_settings();
        return isset( $settings['voyage_api_key'] ) ? trim( (string) $settings['voyage_api_key'] ) : '';
    }

    public static function get_voyage_api_key_mask() {
        $key = self::get_voyage_api_key();
        if ( $key === '' ) {
            return 'pa-xxxxxxxxxxxxxxxxxxxxxxxx';
        }

        if ( class_exists( 'SftcyWordaiBase' ) && method_exists( 'SftcyWordaiBase', 'license_key_mask_format' ) ) {
            return SftcyWordaiBase::license_key_mask_format( $key );
        }

        return substr( $key, 0, 4 ) . str_repeat( '*', max( 0, strlen( $key ) - 8 ) ) . substr( $key, -4 );
    }

    public static function is_configured() {
        return self::get_voyage_api_key() !== '';
    }

    public static function voyage_models() {
        return [
            'Voyage 4' => [
                'voyage-4-lite'  => __( 'voyage-4-lite (Recommended: fastest + lowest cost)', 'wordai-pro' ),
                'voyage-4'       => __( 'voyage-4 (balanced quality + cost)', 'wordai-pro' ),
                'voyage-4-large' => __( 'voyage-4-large (highest retrieval quality)', 'wordai-pro' ),
            ],
            'Older General Models' => [
                'voyage-3.5-lite' => __( 'voyage-3.5-lite', 'wordai-pro' ),
                'voyage-3.5'      => __( 'voyage-3.5', 'wordai-pro' ),
                'voyage-3-large'  => __( 'voyage-3-large', 'wordai-pro' ),
            ],
        ];
    }

    public static function create_embeddings( $texts = [], $model = self::DEFAULT_EMBEDDING_MODEL, $input_type = 'document' ) {

        $texts = array_values(
            array_filter(
                array_map(
                    static function( $text ) {
                        return trim( wp_strip_all_tags( (string) $text ) );
                    },
                    (array) $texts
                ),
                static function( $text ) {
                    return $text !== '';
                }
            )
        );

        if ( empty( $texts ) ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => __( 'No valid text provided for Anthropic embedding.', 'wordai-pro' ),
            ];
        }

        $api_key = self::get_voyage_api_key();
        if ( $api_key === '' ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => __( 'Voyage API key is missing. Save it under AI Agent > Contents Embedding before indexing Anthropic content.', 'wordai-pro' ),
            ];
        }

        if ( $model === '' ) {
            $model = self::DEFAULT_EMBEDDING_MODEL;
        }

        $payload = [
            'input'      => $texts,
            'model'      => $model,
            'input_type' => in_array( $input_type, [ 'document', 'query' ], true ) ? $input_type : 'document',
            'truncation' => true,
        ];

        $response = wp_remote_post(
            self::EMBEDDING_ENDPOINT,
            [
                'headers'   => [
                    'Authorization' => 'Bearer ' . $api_key,
                    'Content-Type'  => 'application/json',
                ],
                'body'      => wp_json_encode( $payload ),
                'timeout'   => 90,
                'sslverify' => self::should_verify_ssl(),
            ]
        );

        if ( is_wp_error( $response ) ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => $response->get_error_message(),
            ];
        }

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

        if ( $code < 200 || $code >= 300 || ! is_array( $json ) ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => __( 'Voyage embedding request failed.', 'wordai-pro' ),
            ];
        }

        if ( ! empty( $json['detail'] ) && is_string( $json['detail'] ) ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => $json['detail'],
            ];
        }

        $vectors = [];

        if ( isset( $json['data'] ) && is_array( $json['data'] ) ) {
            foreach ( $json['data'] as $item ) {
                if ( isset( $item['embedding'] ) && is_array( $item['embedding'] ) ) {
                    $vectors[] = $item['embedding'];
                }
            }
        }

        if ( empty( $vectors ) && isset( $json['embeddings'] ) && is_array( $json['embeddings'] ) ) {
            $vectors = $json['embeddings'];
        }

        if ( empty( $vectors ) ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => __( 'Voyage API returned no embeddings.', 'wordai-pro' ),
            ];
        }

        return [
            'status'       => 'success',
            'feedbackMsg'  => __( 'Anthropic embeddings created successfully.', 'wordai-pro' ),
            'embeddings'   => $vectors,
            'provider'     => self::PROVIDER,
            'model'        => $model,
            'total_tokens' => isset( $json['usage']['total_tokens'] ) ? (int) $json['usage']['total_tokens'] : 0,
        ];
    }

    public static function chunk_text( $text = '', $chunk_size = 500 ) {
        return SftcyWordaiAgentOpenai::chunk_text( $text, $chunk_size );
    }

    public static function estimate_cost( $total_words = 0, $model = self::DEFAULT_EMBEDDING_MODEL ) {
        if ( $total_words <= 0 ) {
            return [
                'status'      => 'fail',
                'feedbackMsg' => __( 'No valid words provided for Anthropic embedding estimation.', 'wordai-pro' ),
            ];
        }

        if ( $model === '' ) {
            $model = self::DEFAULT_EMBEDDING_MODEL;
        }

        $tokens = (int) ceil( $total_words / 0.75 );

        $rate_per_million = 0.02;
        switch ( $model ) {
            case 'voyage-4-large':
            case 'voyage-3-large':
                $rate_per_million = 0.12;
                break;
            case 'voyage-4':
            case 'voyage-3.5':
                $rate_per_million = 0.06;
                break;
            case 'voyage-4-lite':
            case 'voyage-3.5-lite':
            default:
                $rate_per_million = 0.02;
                break;
        }

        $cost = round( ( $tokens / 1_000_000 ) * $rate_per_million, 6 );

        return [
            'status'         => 'success',
            'total_tokens'   => $tokens,
            'estimated_cost' => '$' . $cost,
            'provider'       => self::PROVIDER,
            'model'          => $model,
            'feedbackMsg'    => __( 'Anthropic embedding cost estimated successfully.', 'wordai-pro' ),
        ];
    }

    public static function compute_chunk_hash( $chunk_text ) {
        return SftcyWordaiAgentOpenai::compute_chunk_hash( $chunk_text );
    }

    public static function store_embedding( $source_id, $chunk_text, $embedding, $model = self::DEFAULT_EMBEDDING_MODEL ) {
        global $wpdb;

        if ( $model === '' ) {
            $model = self::DEFAULT_EMBEDDING_MODEL;
        }

        $table      = $wpdb->prefix . 'wordai_agent_embeddings';
        $provider   = self::PROVIDER;
        $chunk_hash = self::compute_chunk_hash( $chunk_text );

        $exists = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT id FROM {$table}
                 WHERE source_id=%d AND provider=%s AND model=%s AND chunk_hash=%s
                 LIMIT 1",
                $source_id,
                $provider,
                $model,
                $chunk_hash
            )
        );

        if ( $exists ) {
            return;
        }

        $wpdb->insert(
            $table,
            [
                'source_id'  => $source_id,
                'chunk_text' => maybe_serialize( $chunk_text ),
                'embedding'  => maybe_serialize( $embedding ),
                'model'      => $model,
                'provider'   => $provider,
                'chunk_hash' => $chunk_hash,
                'created_at' => current_time( 'mysql' ),
            ],
            [ '%d', '%s', '%s', '%s', '%s', '%s', '%s' ]
        );
    }

    private static function should_verify_ssl() {
        if ( class_exists( 'SftcyWordaiBase' ) && method_exists( 'SftcyWordaiBase', 'sc_wordai_should_verify_ssl' ) ) {
            return (bool) SftcyWordaiBase::sc_wordai_should_verify_ssl();
        }

        return true;
    }
}
