# -*- coding: utf-8 -*-
"""
Nom du fichier : milestones.py
Chemin : /var/www/html/gitlab-bridge/app/schemas/milestones.py
Description : Schémas Pydantic liés aux milestones GitLab pour le bridge OpenWebUI.
Auteur : Sylvain SCATTOLINI
Date de création / modification : 2026-04-02
Version : 1.1
"""

from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field


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

    id: int
    iid: int | None = None
    title: str
    description: str | None = None
    state: str
    due_date: str | None = None
    web_url: str | None = None


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

    project_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    state: str = Field(default="all", pattern="^(all|active|closed)$")
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)
    limit: int = Field(default=100, ge=1, le=200)


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

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


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

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


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

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


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

    project_hint: str = Field(..., min_length=1, max_length=255)
    issue_hint: str = Field(..., min_length=1, max_length=255)
    milestone_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)
    resolved_issue_iid: int = Field(default=0, ge=0)
    resolved_milestone_id: int = Field(default=0, ge=0)
    limit: int = Field(default=20, ge=1, le=100)


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

    id: int
    iid: int | None = None
    title: str
    state: str
    due_date: str | None = None
    web_url: str | None = None
    score: int


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

    success: bool = True
    status: str
    message: str
    project: dict | None = None
    issue: dict | None = None
    milestone: MilestoneItem | None = None
    candidate_projects: list[dict] = Field(default_factory=list)
    candidate_issues: list[dict] = Field(default_factory=list)
    candidate_milestones: list[MilestoneCandidateItem] = Field(default_factory=list)

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

    project_hint: str = Field(..., min_length=1, max_length=255)
    milestone_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    state: str = Field(default="all", pattern="^(all|opened|closed)$")
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)
    resolved_milestone_id: int = Field(default=0, ge=0)
    limit: int = Field(default=100, ge=1, le=200)


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

    success: bool = True
    status: str
    message: str
    project: dict | None = None
    milestone: MilestoneItem | None = None
    issues: list[dict] = Field(default_factory=list)
    candidate_projects: list[dict] = Field(default_factory=list)
    candidate_milestones: list[MilestoneCandidateItem] = Field(default_factory=list)

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

    project_hint: str = Field(..., min_length=1, max_length=255)
    milestone_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)
    resolved_milestone_id: int = Field(default=0, ge=0)
    limit: int = Field(default=200, ge=1, le=500)


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

    success: bool = True
    status: str
    message: str
    project: dict | None = None
    milestone: MilestoneItem | None = None
    total: int = 0
    opened: int = 0
    closed: int = 0
    progress_percent: int = 0
    candidate_projects: list[dict] = Field(default_factory=list)
    candidate_milestones: list[MilestoneCandidateItem] = Field(default_factory=list)


# ---------------------------------------------------------------------------
# Schémas pour la clôture/réouverture d'une milestone (assistant-close)
# ---------------------------------------------------------------------------

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

    project_hint: str = Field(..., min_length=1, max_length=255)
    milestone_hint: str = Field(..., min_length=1, max_length=255)
    action: str = Field(default="close", pattern="^(close|reopen)$",
                        description="'close' pour fermer, 'reopen' pour rouvrir.")
    root_hint: str = Field(default="", max_length=255)
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)
    resolved_milestone_id: int = Field(default=0, ge=0)


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

    success: bool = True
    status: str
    message: str
    project: dict | None = None
    milestone: MilestoneItem | None = None
    candidate_projects: list[dict] = Field(default_factory=list)
    candidate_milestones: list[MilestoneCandidateItem] = Field(default_factory=list)


# ---------------------------------------------------------------------------
# Schémas pour la mise à jour d'une milestone (assistant-update)
# ---------------------------------------------------------------------------

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

    project_hint: str = Field(..., min_length=1, max_length=255)
    milestone_hint: str = Field(..., min_length=1, max_length=255)
    root_hint: str = Field(default="", max_length=255)
    new_title: str = Field(default="", max_length=255,
                           description="Nouveau titre. Laissez vide pour ne pas modifier.")
    new_description: str = Field(default="", max_length=10000,
                                 description="Nouvelle description. Laissez vide pour ne pas modifier.")
    due_date: str = Field(default="", max_length=10,
                          description="Date d'échéance YYYY-MM-DD. Vide = ne pas modifier.")
    confirm: bool = Field(default=False)
    resolved_project_path: str = Field(default="", max_length=255)
    resolved_milestone_id: int = Field(default=0, ge=0)


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

    success: bool = True
    status: str
    message: str
    project: dict | None = None
    milestone: MilestoneItem | None = None
    candidate_projects: list[dict] = Field(default_factory=list)
    candidate_milestones: list[MilestoneCandidateItem] = Field(default_factory=list)

