import uuid
from datetime import datetime

from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, Uuid, Boolean, func
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.database import Base


class Document(Base):
    __tablename__ = "documents"

    id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
    slug: Mapped[str] = mapped_column(String(128), unique=True, nullable=False, index=True)
    title: Mapped[str] = mapped_column(String(256), nullable=False)
    doc_type: Mapped[str] = mapped_column(String(64), nullable=False)  # licence, engagement, reglement, constitution
    version: Mapped[str] = mapped_column(String(32), default="0.1.0")
    status: Mapped[str] = mapped_column(String(32), default="draft")  # draft, active, archived
    description: Mapped[str | None] = mapped_column(Text)
    organization_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("organizations.id"), nullable=True, index=True)
    ipfs_cid: Mapped[str | None] = mapped_column(String(128))
    chain_anchor: Mapped[str | None] = mapped_column(String(128))
    genesis_json: Mapped[str | None] = mapped_column(Text)  # JSON: source files, repos, forum URLs, formula trigger
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())

    items: Mapped[list["DocumentItem"]] = relationship(back_populates="document", cascade="all, delete-orphan", order_by="DocumentItem.sort_order")


class DocumentItem(Base):
    __tablename__ = "document_items"

    id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
    document_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("documents.id"), nullable=False)
    position: Mapped[str] = mapped_column(String(16), nullable=False)  # "1", "1.1", "3.2"
    item_type: Mapped[str] = mapped_column(String(32), default="clause")  # clause, rule, verification, preamble, section, genesis
    title: Mapped[str | None] = mapped_column(String(256))
    current_text: Mapped[str] = mapped_column(Text, nullable=False)
    voting_protocol_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("voting_protocols.id"))
    sort_order: Mapped[int] = mapped_column(Integer, default=0)
    section_tag: Mapped[str | None] = mapped_column(String(64))  # genesis, fondamental, technique, annexe, formule, inertie, ordonnancement
    inertia_preset: Mapped[str] = mapped_column(String(16), default="standard")  # low, standard, high, very_high
    is_permanent_vote: Mapped[bool] = mapped_column(default=True)  # permanent vote vs time-bounded
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())

    document: Mapped["Document"] = relationship(back_populates="items")
    versions: Mapped[list["ItemVersion"]] = relationship(back_populates="item", cascade="all, delete-orphan")


class ItemVersion(Base):
    __tablename__ = "item_versions"

    id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
    item_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("document_items.id"), nullable=False)
    proposed_text: Mapped[str] = mapped_column(Text, nullable=False)
    diff_text: Mapped[str | None] = mapped_column(Text)
    rationale: Mapped[str | None] = mapped_column(Text)
    status: Mapped[str] = mapped_column(String(32), default="proposed")  # proposed, voting, accepted, rejected
    decision_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("decisions.id"))
    proposed_by_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("duniter_identities.id"))
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())

    item: Mapped["DocumentItem"] = relationship(back_populates="versions")
