<?php

namespace ZenoChatbot\Services\LLMService\AIClient\Support\Handlers;

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

/**
 * Handles inline text resources and text coercion.
 */
class TextHandler
{
    /**
     * Create a text resource from inline text
     */
    public static function fromInline(array $data, array $options = []): array
    {
        $text = (string) ($data['text'] ?? '');

        return [
            'id' => $data['id'] ?? md5($text),
            'name' => $data['name'] ?? 'inline',
            'type' => $data['type'] ?? 'text/plain',
            'text' => static::trimText($text, $options),
        ];
    }

    /**
     * Create a text resource from raw string
     */
    public static function fromRaw(string $text, array $options = []): array
    {
        return [
            'id' => md5($text),
            'name' => 'text',
            'type' => 'text/plain',
            'text' => static::trimText($text, $options),
        ];
    }

    /**
     * Coerce content to text based on MIME type
     */
    public static function coerceToText(string $raw, string $type, array $options): string
    {
        if (!empty($options['text_extractor']) && is_callable($options['text_extractor'])) {
            $out = (string) call_user_func($options['text_extractor'], $raw, $type);
            return static::trimText($out, $options);
        }

        if (static::isTextLikeType($type)) {
            if (in_array($type, ['text/html', 'text/htm', 'application/xhtml+xml'], true)) {
                $raw = static::stripHtml($raw);
            }
            return static::trimText($raw, $options);
        }

        // Unknown/binary types: skip content by default
        return '';
    }

    /**
     * Check if MIME type is text-like
     */
    public static function isTextLikeType(string $type): bool
    {
        $type = strtolower($type);

        return str_starts_with($type, 'text/')
            || $type === 'application/json'
            || $type === 'application/xml'
            || $type === 'application/xhtml+xml';
    }

    /**
     * Strip HTML tags and decode entities
     */
    private static function stripHtml(string $html): string
    {
        $text = wp_strip_all_tags($html);
        return html_entity_decode($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }

    /**
     * Trim text to max bytes
     */
    public static function trimText(string $text, array $options): string
    {
        $max = (int) ($options['max_bytes'] ?? 1024 * 512);
        if ($max > 0 && strlen($text) > $max) {
            return substr($text, 0, $max);
        }
        return $text;
    }
}

