#!/usr/bin/env python3
"""
Генерация эмбеддинга по JSON шага 5 через Ollama (шаг 6).
Текст для эмбеддинга собирается из framework, insights, application по embed_input_spec.txt.
Вход по умолчанию: merged_with_tags.json (5). Выход по умолчанию: embedding.json (вектор).
"""

import argparse
import json
import sys
import time
import urllib.error
import urllib.request
from pathlib import Path
from typing import Any

DIR = Path(__file__).resolve().parent
DEFAULT_MERGED = DIR.parent / "5_мерж_анализа_и_тегов" / "merged_with_tags.json"
DEFAULT_OUTPUT = DIR / "embedding.json"

OLLAMA_URL = "http://localhost:11434"
EMBED_MODEL = "bge-m3"


def get_embedding_ollama(base_url: str, model: str, text: str) -> list[float]:
    """
    Запрашивает эмбеддинг текста у Ollama API (POST /api/embed).

    Args:
        base_url: Базовый URL Ollama (например http://localhost:11434).
        model: Имя модели эмбеддингов (например bge-m3).
        text: Текст для эмбеддинга.

    Returns:
        Вектор эмбеддинга (список float).

    Raises:
        urllib.error.HTTPError: При ошибке HTTP.
        ValueError: Если в ответе нет ожидаемой структуры.
    """
    url = f"{base_url.rstrip('/')}/api/embed"
    payload = {"model": model, "input": text}
    body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
    req = urllib.request.Request(
        url,
        data=body,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(req, timeout=120) as resp:
        data: dict[str, Any] = json.loads(resp.read().decode("utf-8"))
    if "embeddings" not in data or not data["embeddings"]:
        raise ValueError("В ответе Ollama нет поля embeddings")
    embedding = data["embeddings"][0]
    if not isinstance(embedding, list):
        raise ValueError("embeddings[0] не является массивом")
    return [float(x) for x in embedding]


def main() -> int:
    """Собирает текст из merged JSON, вызывает Ollama /api/embed, пишет вектор в файл."""
    from embed_cli import merged_json_to_embed_text

    parser = argparse.ArgumentParser(
        description="Эмбеддинг по JSON шага 5 через Ollama (шаг 6). На выход — вектор (JSON).",
    )
    parser.add_argument(
        "--merged",
        type=Path,
        default=DEFAULT_MERGED,
        help=f"Путь к merged_with_tags.json (по умолчанию: {DEFAULT_MERGED})",
    )
    parser.add_argument(
        "--model",
        default=EMBED_MODEL,
        help=f"Модель эмбеддингов в Ollama (по умолчанию: {EMBED_MODEL})",
    )
    parser.add_argument(
        "--ollama-url",
        default=OLLAMA_URL,
        help=f"URL Ollama (по умолчанию: {OLLAMA_URL})",
    )
    parser.add_argument(
        "-o",
        "--output",
        type=Path,
        default=DEFAULT_OUTPUT,
        help=f"Путь к выходному JSON с вектором (по умолчанию: {DEFAULT_OUTPUT})",
    )
    args = parser.parse_args()

    if not args.merged.is_file():
        print(f"Файл не найден: {args.merged}", file=sys.stderr)
        return 1

    print("Загрузка merged_with_tags.json...")
    try:
        with open(args.merged, encoding="utf-8") as f:
            merged = json.load(f)
    except json.JSONDecodeError as e:
        print(f"Ошибка разбора JSON: {e}", file=sys.stderr)
        return 1

    text = merged_json_to_embed_text(merged)
    if not text:
        print(
            "Ошибка: текст для эмбеддинга пуст (нет framework/insights/application).",
            file=sys.stderr,
        )
        return 1

    print(f"Вызов Ollama {args.model} — генерация эмбеддинга...")
    t0 = time.monotonic()
    try:
        vector = get_embedding_ollama(args.ollama_url, args.model, text)
    except urllib.error.HTTPError as e:
        print(f"Ошибка HTTP {e.code}: {e.reason}", file=sys.stderr)
        if e.fp:
            try:
                body = e.fp.read().decode("utf-8")
                print(body[:500], file=sys.stderr)
            except Exception:
                pass
        return 1
    except urllib.error.URLError as e:
        print(f"Ошибка запроса: {e.reason}", file=sys.stderr)
        return 1
    except ValueError as e:
        print(f"Ошибка: {e}", file=sys.stderr)
        return 1
    elapsed = time.monotonic() - t0
    print(f"Эмбеддинг получен за {elapsed:.1f} сек, размерность {len(vector)}")

    args.output.parent.mkdir(parents=True, exist_ok=True)
    with open(args.output, "w", encoding="utf-8") as f:
        json.dump(vector, f, ensure_ascii=False)
    print(f"Записано: {args.output}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
