# -*- coding: utf-8 -*-
"""
Nom du fichier : groups.py
Chemin : /var/www/html/gitlab-bridge/app/api/v1/groups.py
Description : Endpoints API de recherche de groupes GitLab compatibles OpenWebUI.
Options éventuelles :
    - POST /api/v1/groups/search
Exemples d'utilisation :
    - curl -X POST "https://gitlab-bridge.tarbouriech.tech/api/v1/groups/search" \
      -H "Content-Type: application/json" \
      -d '{
            "query": "developpements",
            "root_hint": "si",
            "limit": 10
          }'
Auteur : Sylvain SCATTOLINI
Date de création / modification : 2026-03-26
Version : 1.2
"""

from __future__ import annotations

import json
import logging

from difflib import SequenceMatcher
from fastapi import APIRouter, HTTPException, status

from app.clients.gitlab_client import GitLabClient
from app.core.exceptions import GitLabApiError
from app.schemas.groups import GroupMatch, GroupSearchRequest, GroupSearchResponse
from app.utils.helpers import normalize_text

router = APIRouter(prefix="/api/v1/groups", tags=["groups"])

logger = logging.getLogger(__name__)


def _compute_score(query: str, group_name: str, full_path: str) -> int:
    normalized_query = normalize_text(query)
    normalized_name = normalize_text(group_name)
    normalized_path = normalize_text(full_path)

    if normalized_query == normalized_name:
        return 100
    if normalized_query in normalized_name:
        return 95
    if normalized_query in normalized_path:
        return 90

    ratio_name = SequenceMatcher(None, normalized_query, normalized_name).ratio()
    ratio_path = SequenceMatcher(None, normalized_query, normalized_path).ratio()
    return int(max(ratio_name, ratio_path) * 100)


def _list_groups(root_hint: str) -> list[dict]:
    """Retourne tous les groupes accessibles (toutes pages), filtrés par root_hint."""
    client = GitLabClient()
    try:
        groups = client.list_groups(all_available=True)
    except GitLabApiError as exc:
        raise HTTPException(status_code=502, detail=str(exc)) from exc

    if not root_hint:
        return [g for g in groups if isinstance(g, dict)]

    normalized_root = normalize_text(root_hint)
    return [
        g for g in groups
        if isinstance(g, dict)
        and normalize_text(str(g.get("full_path", ""))).startswith(normalized_root)
    ]


@router.post(
    "/search",
    operation_id="search_groups",
    summary="Rechercher des groupes GitLab",
    description="Recherche des groupes GitLab pertinents à partir d'un libellé naturel.",
    response_model=GroupSearchResponse,
)
def search_groups(payload: GroupSearchRequest) -> GroupSearchResponse:
    try:
        safe_query = payload.query.strip()
        safe_root_hint = payload.root_hint.strip().strip("/")
        safe_limit = int(payload.limit)

        logger.info(
            "Payload reçu sur /api/v1/groups/search : %s",
            json.dumps(
                {"query": safe_query, "root_hint": safe_root_hint, "limit": safe_limit},
                ensure_ascii=False,
            ),
        )

        groups = _list_groups(safe_root_hint)

        scored_matches: list[GroupMatch] = []
        for group in groups:
            score = _compute_score(
                safe_query,
                str(group.get("name", "")),
                str(group.get("full_path", "")),
            )
            if score < 40:
                continue
            scored_matches.append(
                GroupMatch(
                    id=int(group["id"]),
                    name=str(group["name"]),
                    full_path=str(group["full_path"]),
                    score=score,
                )
            )

        scored_matches.sort(key=lambda item: (-item.score, item.full_path))

        return GroupSearchResponse(
            success=True,
            query=safe_query,
            matches=scored_matches[:safe_limit],
        )

    except HTTPException:
        raise
    except Exception as exc:
        logger.exception("Erreur inattendue dans search_groups : %s", str(exc))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Erreur interne lors de la recherche de groupes.",
        ) from exc
