# -*- coding: utf-8 -*-
"""
Nom du fichier : projects.py
Chemin : /var/www/html/gitlab-bridge/app/schemas/projects.py
Description : Schémas Pydantic liés aux projets GitLab pour le bridge OpenWebUI.
              Ce fichier contient les schémas de résumé, création, pré-vérification
              et orchestration conversationnelle de création de projet.
Options éventuelles :
    - Aucun
Exemples d'utilisation :
    - Import dans app/api/v1/projects.py
Prérequis :
    - Python 3.11+
    - Pydantic v2
Auteur : Sylvain SCATTOLINI
Date de création / modification : 2026-03-26
Version : 1.7
"""

from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field


class ProjectInfo(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: int
    name: str
    path_with_namespace: str


class SummaryPayload(BaseModel):
    model_config = ConfigDict(extra="forbid")

    open_issues: int
    closed_issues_period: int
    markdown: str


class ProjectSummaryResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    project: ProjectInfo
    summary: SummaryPayload


class ProjectCreatePayload(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: int
    name: str
    path_with_namespace: str
    web_url: str


class ProjectCreateResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    project: ProjectCreatePayload


class ProjectCreateRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    name: str = Field(..., min_length=1, max_length=255)
    path: str = Field(..., min_length=1, max_length=255)
    namespace_path: str = Field(..., min_length=1, max_length=255)
    description: str = Field(default="", max_length=5000)
    visibility: str = Field(default="private", pattern="^(private|internal|public)$")
    initialize_with_readme: bool = Field(default=True)


class SimilarProject(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: int
    name: str
    path_with_namespace: str
    web_url: str
    score: int


class CandidateGroup(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: int
    name: str
    full_path: str
    score: int


class ProjectCheckCreateRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_name: str = Field(..., min_length=1, max_length=255)
    target_group_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    limit: int = Field(default=10, ge=1, le=50)


class ProjectCheckCreateResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    status: str
    suggested_project_path: str
    resolved_group: str | None = None
    candidate_groups: list[CandidateGroup] = Field(default_factory=list)
    similar_projects: list[SimilarProject] = Field(default_factory=list)
    message: str


class ProjectAssistantCreateRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_name: str = Field(..., min_length=1, max_length=255)
    target_group_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    description: str = Field(default="", max_length=5000)
    visibility: str = Field(default="private", pattern="^(private|internal|public)$")
    initialize_with_readme: bool = Field(default=True)
    confirm: bool = Field(default=False)
    resolved_group: str = Field(default="", max_length=255)
    limit: int = Field(default=10, ge=1, le=50)


class ProjectAssistantCreateResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    status: str
    message: str
    project: ProjectCreatePayload | None = None
    suggested_project_path: str | None = None
    resolved_group: str | None = None
    candidate_groups: list[CandidateGroup] = Field(default_factory=list)
    similar_projects: list[SimilarProject] = Field(default_factory=list)

class ProjectTasksResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    project: ProjectInfo
    open_issues: list[str]
    closed_issues: list[str]


class ProjectProgressResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    project: ProjectInfo
    total: int
    closed: int
    progress_percent: int

class ProjectTasksRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_hint: str
    root_hint: str = ""


class ProjectProgressRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_hint: str
    root_hint: str = ""

class ProjectAssistantTasksRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)


class ProjectAssistantTasksResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    status: str
    message: str
    project: ProjectInfo | None = None
    open_issues: list[str] = Field(default_factory=list)
    closed_issues: list[str] = Field(default_factory=list)
    candidate_projects: list[SimilarProject] = Field(default_factory=list)


class ProjectAssistantProgressRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)


class ProjectAssistantProgressResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    status: str
    message: str
    project: ProjectInfo | None = None
    total: int = 0
    closed: int = 0
    progress_percent: int = 0
    candidate_projects: list[SimilarProject] = Field(default_factory=list)

class ProjectAssistantListRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    group_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    confirm: bool = Field(default=False)
    resolved_group_path: str = Field(default="", max_length=255)
    limit: int = Field(default=50, ge=1, le=200)


class ProjectListItem(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: int
    name: str
    path_with_namespace: str
    web_url: str
    visibility: str
    open_issues_count: int = 0


class ProjectAssistantListResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    status: str
    message: str
    resolved_group: str | None = None
    candidate_groups: list[CandidateGroup] = Field(default_factory=list)
    projects: list[ProjectListItem] = Field(default_factory=list)


# ---------------------------------------------------------------------------
# Schémas pour la liste des membres d'un projet (assistant-members)
# ---------------------------------------------------------------------------

ACCESS_LEVEL_NAMES = {
    10: "Guest",
    20: "Reporter",
    30: "Developer",
    40: "Maintainer",
    50: "Owner",
}


class ProjectMemberItem(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: int
    username: str
    name: str
    access_level: int
    access_level_name: str
    state: str


class ProjectAssistantMembersRequest(BaseModel):
    model_config = ConfigDict(extra="forbid")

    project_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)
    min_access_level: int = Field(default=0, ge=0, le=50,
                                  description="Filtrer par niveau d'accès minimum (10=Guest, 30=Developer, 40=Maintainer).")


class ProjectAssistantMembersResponse(BaseModel):
    model_config = ConfigDict(extra="forbid")

    success: bool = True
    status: str
    message: str
    project: dict | None = None
    members: list[ProjectMemberItem] = Field(default_factory=list)
    candidate_projects: list[dict] = Field(default_factory=list)
