from __future__ import annotations

import uuid
from datetime import datetime
from typing import Any, Literal

from pydantic import BaseModel, Field


class EdgeWriteEvidence(BaseModel):
    id: str
    status: str = "queued"
    source_host: str | None = None
    path: str | None = None


class RepositoryRenamePreflightRequest(BaseModel):
    new_slug: str = Field(min_length=1, max_length=100, pattern=r"^[a-z0-9][a-z0-9-]*$")
    queued_edge_writes: list[EdgeWriteEvidence] = Field(default_factory=list)


class RepositoryRenamePreflightRead(BaseModel):
    schema_version: Literal["state-hub.repository-rename-preflight.v1"]
    repo_id: uuid.UUID
    old_slug: str
    new_slug: str
    safe_to_apply: bool
    blockers: list[dict[str, Any]]
    warnings: list[dict[str, Any]]
    current: dict[str, Any]
    target: dict[str, Any]
    baselines: dict[str, Any]
    active_work: dict[str, Any]
    affected: dict[str, Any]
    queued_edge_writes: list[dict[str, Any]]
    proposed_mutations: list[dict[str, Any]]
    retained_history: list[dict[str, Any]]
    report_checksum: str
    preflight_token: str | None
    preflighted_at: datetime
    expires_at: datetime | None


class ForgeIdentityVerifyRequest(BaseModel):
    provider: Literal["forgejo"] = "forgejo"
    forge_instance: str
    forge_owner: str
    forge_repository_id: int = Field(gt=0)
    verified_by: str = Field(min_length=1, max_length=160)


class RepositoryRenameOperationCreate(BaseModel):
    operation_id: uuid.UUID | None = None
    new_slug: str = Field(min_length=1, max_length=100, pattern=r"^[a-z0-9][a-z0-9-]*$")
    preflight_token: str
    confirmation: str
    actor: str = Field(min_length=1, max_length=160)
    queued_edge_writes: list[EdgeWriteEvidence] = Field(default_factory=list)


class RepositoryRenamePhaseApply(BaseModel):
    expected_phase: str
    confirmation: str
    checks: dict[str, bool] = Field(default_factory=dict)
    evidence: dict[str, Any] = Field(default_factory=dict)


class RepositoryRenameRollbackRequest(BaseModel):
    expected_phase: str
    confirmation: str


class RepositoryRenameOperationRead(BaseModel):
    id: uuid.UUID
    repo_id: uuid.UUID
    phase: str
    old_slug: str
    new_slug: str
    expected_forge_repository_id: int
    expected_source_commit: str
    expected_default_branch: str
    actor: str
    phase_changed_at: datetime
    preflighted_at: datetime | None
    preflight_expires_at: datetime | None
    completed_at: datetime | None
    rolled_back_at: datetime | None
    evidence: dict[str, Any]
    error_code: str | None
    error_message: str | None
    error_details: dict[str, Any] | None
    error_at: datetime | None
    no_op: bool = False


class RepositoryRenameVerificationRead(BaseModel):
    operation_id: uuid.UUID
    repo_id: uuid.UUID
    phase: str
    ok: bool
    checks: list[dict[str, Any]]
    baseline_checksum: str
    current_checksum: str


class RepositoryRenameRollbackPreflightRead(BaseModel):
    operation_id: uuid.UUID
    repo_id: uuid.UUID
    rollback_from_phase: str
    safe_to_rollback: bool
    blockers: list[dict[str, Any]]
    irreversible: list[dict[str, Any]]
    operation: RepositoryRenameOperationRead
