"""Schemas for Forgejo repository CRUD API payloads."""

from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import field_validator
from sqlmodel import Field, SQLModel

RUNTIME_ANNOTATION_TYPES = (datetime, UUID)


class ForgejoRepositoryBase(SQLModel):
    """Shared repository fields used across create/read payloads."""

    owner: str
    repo: str
    display_name: str = ""
    default_branch: str = "main"
    active: bool = True

    @field_validator("owner", "repo", mode="before")
    @classmethod
    def normalize_strings(cls, value: object) -> str | None | object:
        """Normalize whitespace in owner and repo."""
        if value is None:
            return None
        if isinstance(value, str):
            value = value.strip()
            if not value:
                return None
            return value
        return value


class ForgejoRepositoryCreate(ForgejoRepositoryBase):
    """Payload for creating a Forgejo repository tracked configuration."""

    connection_id: UUID
    webhook_secret: str | None = None

    @field_validator("webhook_secret", mode="before")
    @classmethod
    def normalize_webhook_secret(cls, value: object) -> str | None | object:
        """Normalize empty webhook secrets to null."""
        if value is None:
            return None
        if isinstance(value, str):
            value = value.strip()
            return value or None
        return value


class ForgejoRepositoryUpdate(SQLModel):
    """Payload for partial Forgejo repository updates."""

    connection_id: UUID | None = None
    owner: str | None = None
    repo: str | None = None
    display_name: str | None = None
    default_branch: str | None = None
    active: bool | None = None
    webhook_secret: str | None = None

    @field_validator("owner", "repo", mode="before")
    @classmethod
    def normalize_strings(cls, value: object) -> str | None | object:
        """Normalize whitespace in owner and repo."""
        if value is None:
            return None
        if isinstance(value, str):
            value = value.strip()
            if not value:
                return None
            return value
        return value

    @field_validator("webhook_secret", mode="before")
    @classmethod
    def normalize_webhook_secret(cls, value: object) -> str | None | object:
        """Normalize empty webhook secrets to null."""
        if value is None:
            return None
        if isinstance(value, str):
            value = value.strip()
            return value or None
        return value


class ForgejoRepositoryConnectionInfo(SQLModel):
    """Safe connection metadata included in repository read responses."""

    id: UUID
    organization_id: UUID
    name: str
    base_url: str
    has_token: bool
    token_last_eight: str | None
    active: bool


class ForgejoRepositoryRead(ForgejoRepositoryBase):
    """Repository payload returned from read endpoints."""

    id: UUID
    organization_id: UUID
    connection_id: UUID
    connection: ForgejoRepositoryConnectionInfo
    has_webhook_secret: bool = False
    description: str | None = None
    open_issues_count: int = 0
    is_archived: bool = False
    topics: list[str] = Field(default_factory=list)
    labels: list[dict[str, object]] = Field(default_factory=list)
    last_sync_at: datetime | None
    last_sync_error: str | None
    created_at: datetime
    updated_at: datetime
