<?php
namespace EasyChat\Library\Ai;

use EasyChat\Library\AttachmentStorage;
use EasyChat\Library\ImageVariantService;
use EasyChat\Library\SafeRuntime;








class VisualContextBuilder {
    private const MAX_IMAGE_MESSAGES = 3;
    private const MAX_IMAGES = 10;
    private const MAX_TOTAL_BYTES = 7340032;

    private $storage;
    private $variants;

    public function __construct($registry) {
        $this->storage = new AttachmentStorage($registry);
        $this->variants = new ImageVariantService();
    }

    public function buildForRows(int $chat_id, array $rows, int $target_message_id): array {
        $message_ids = [];
        $rows_by_id = [];
        foreach ($rows as $row) {
            $message_id = (int)($row['message_id'] ?? 0);
            if ($message_id <= 0 || (int)($row['chat_id'] ?? $chat_id) !== $chat_id) {
                continue;
            }
            $message_ids[] = $message_id;
            $rows_by_id[$message_id] = $row;
        }

        $attachments = $this->storage->getAttachmentsByMessageIds($message_ids);
        $candidates_by_message = [];
        foreach ($rows_by_id as $message_id => $row) {
            if ((int)($row['author'] ?? 0) !== 1) {
                continue;
            }
            $candidates = $this->imageCandidates(
                $chat_id,
                $row,
                isset($attachments[$message_id]) ? (array)$attachments[$message_id] : []
            );
            if ($candidates) {
                $candidates_by_message[$message_id] = $candidates;
            }
        }

        $target_expected = isset($candidates_by_message[$target_message_id])
            ? count($candidates_by_message[$target_message_id])
            : 0;
        $selected_ids = [];
        if ($target_expected > 0) {
            $selected_ids[] = $target_message_id;
        }
        foreach (array_reverse($message_ids) as $message_id) {
            if (
                $message_id === $target_message_id
                || !isset($candidates_by_message[$message_id])
                || count($selected_ids) >= self::MAX_IMAGE_MESSAGES
            ) {
                continue;
            }
            $selected_ids[] = $message_id;
        }
        $selected_ids = array_reverse($selected_ids);

        $images_by_message = [];
        $fingerprints = [];
        $total_bytes = 0;
        $skipped = 0;
        foreach ($selected_ids as $message_id) {
            foreach ($candidates_by_message[$message_id] as $candidate) {
                if (count($fingerprints) >= self::MAX_IMAGES) {
                    $skipped++;
                    continue;
                }
                $prepared = $this->variants->ensureAiVariantForFile(
                    $chat_id,
                    (string)$candidate['file_name']
                );
                if (empty($prepared['success'])) {
                    $skipped++;
                    continue;
                }
                $size = (int)($prepared['size'] ?? 0);
                if ($size <= 0 || ($total_bytes + $size) > self::MAX_TOTAL_BYTES) {
                    $skipped++;
                    continue;
                }
                $bytes = SafeRuntime::readFile((string)$prepared['path']);
                if (!is_string($bytes) || strlen($bytes) !== $size) {
                    $skipped++;
                    continue;
                }

                if (!isset($images_by_message[$message_id])) {
                    $images_by_message[$message_id] = [];
                }
                $fingerprint = (string)$prepared['fingerprint'];
                $images_by_message[$message_id][] = [
                    'type' => 'image_url',
                    'image_url' => [
                        'url' => 'data:image/jpeg;base64,' . base64_encode($bytes),
                        'detail' => 'auto',
                    ],
                    'fingerprint' => $fingerprint,
                ];
                $fingerprints[] = $fingerprint;
                $total_bytes += $size;
            }
        }

        return [
            'images_by_message_id' => $images_by_message,
            'image_count' => count($fingerprints),
            'target_image_expected' => $target_expected,
            'target_image_count' => isset($images_by_message[$target_message_id])
                ? count($images_by_message[$target_message_id])
                : 0,
            'skipped_image_count' => $skipped,
            'total_bytes' => $total_bytes,
            'fingerprints' => $fingerprints,
        ];
    }

    private function imageCandidates(int $chat_id, array $row, array $attachments): array {
        $result = [];
        $seen = [];
        foreach ($attachments as $attachment) {
            if ((int)($attachment['chat_id'] ?? 0) !== $chat_id) {
                continue;
            }
            $file = basename((string)($attachment['file_name'] ?? ''));
            $mime = strtolower((string)($attachment['mime_type'] ?? ''));
            $meta = json_decode((string)($attachment['meta_json'] ?? ''), true);
            $kind = is_array($meta) ? strtolower((string)($meta['kind'] ?? '')) : '';
            if ($file === '' || ($kind !== 'image' && strpos($mime, 'image/') !== 0)) {
                continue;
            }
            $seen[$file] = true;
            $result[] = ['file_name' => $file];
        }

         
         
        $legacy = basename((string)($row['image'] ?? ''));
        if ($legacy !== '' && !isset($seen[$legacy])) {
            $result[] = ['file_name' => $legacy];
        }

        return $result;
    }
}
