from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field, HttpUrl

from app.schemas.changeset import ChangeItem
from app.schemas.common import ErrorPayload


class AttachmentType(str, Enum):
    CONFLUENCE_URL = "confluence_url"


class ChatMode(str, Enum):
    AUTO = "auto"
    PROJECT_QA = "project_qa"
    PROJECT_EDITS = "project_edits"
    DOCS_GENERATION = "docs_generation"
    # Legacy alias preserved for backward compatibility.
    CODE_CHANGE = "code_change"
    # Legacy alias preserved for backward compatibility.
    ANALYTICS_REVIEW = "analytics_review"
    QA = "qa"


class Attachment(BaseModel):
    type: AttachmentType
    url: HttpUrl


class ChatFileContext(BaseModel):
    path: str = Field(min_length=1)
    content: str
    content_hash: str = Field(min_length=1)


class ChatMessageRequest(BaseModel):
    mode: ChatMode = ChatMode.AUTO
    dialog_session_id: str | None = Field(default=None, min_length=1)
    rag_session_id: str | None = Field(default=None, min_length=1)
    session_id: str | None = Field(default=None, min_length=1)
    project_id: str | None = Field(default=None, min_length=1)
    message: str = Field(min_length=1)
    attachments: list[Attachment] = Field(default_factory=list)
    files: list[ChatFileContext] = Field(default_factory=list)


class TaskQueuedResponse(BaseModel):
    task_id: str
    status: str


class TaskStatus(str, Enum):
    QUEUED = "queued"
    RUNNING = "running"
    DONE = "done"
    ERROR = "error"


class TaskResultType(str, Enum):
    ANSWER = "answer"
    CHANGESET = "changeset"


class TaskResultResponse(BaseModel):
    task_id: str
    status: TaskStatus
    result_type: Optional[TaskResultType] = None
    answer: Optional[str] = None
    changeset: list[ChangeItem] = Field(default_factory=list)
    error: Optional[ErrorPayload] = None


class DialogCreateRequest(BaseModel):
    rag_session_id: str = Field(min_length=1)


class DialogCreateResponse(BaseModel):
    dialog_session_id: str
    rag_session_id: str
