"""Settings and preferences models."""

from __future__ import annotations

from datetime import datetime
from typing import TYPE_CHECKING
from uuid import UUID as PyUUID
from uuid import uuid4

from sqlalchemy import CheckConstraint, DateTime, ForeignKey, String, Text, UniqueConstraint
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship

from noteflow.domain.utils.time import utc_now

from .._base import Base

if TYPE_CHECKING:
    from noteflow.infrastructure.persistence.models.identity.identity import (
        UserModel,
        WorkspaceModel,
    )


class SettingsModel(Base):
    """Represent scoped settings (system, workspace, or user level)."""

    __tablename__ = "settings"
    __table_args__: tuple[UniqueConstraint, CheckConstraint, dict[str, str]] = (
        UniqueConstraint(
            "scope",
            "workspace_id",
            "user_id",
            "key",
            name="settings_unique_scope_key",
        ),
        CheckConstraint(
            "scope IN ('system', 'workspace', 'user')",
            name="settings_scope_chk",
        ),
        {"schema": "noteflow"},
    )

    id: Mapped[PyUUID] = mapped_column(
        UUID(as_uuid=True),
        primary_key=True,
        default=uuid4,
    )
    scope: Mapped[str] = mapped_column(Text, nullable=False)
    workspace_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.workspaces.id", ondelete="CASCADE"),
        nullable=True,
    )
    user_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.users.id", ondelete="CASCADE"),
        nullable=True,
    )
    key: Mapped[str] = mapped_column(Text, nullable=False)
    value: Mapped[dict[str, object]] = mapped_column(
        JSONB,
        nullable=False,
        default=dict,
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
        onupdate=utc_now,
    )

    # Relationships
    workspace: Mapped[WorkspaceModel | None] = relationship("WorkspaceModel")
    user: Mapped[UserModel | None] = relationship("UserModel")


class UserPreferencesModel(Base):
    """Store key-value user preferences for persistence across server restarts.

    Simple KV store compatible with current codebase pattern.
    Currently used for cloud consent and other settings.
    """

    __tablename__ = "user_preferences"
    __table_args__: dict[str, str] = {"schema": "noteflow"}

    # Using key as primary key (matching schema.sql design for KV store simplicity)
    key: Mapped[str] = mapped_column(String(64), primary_key=True)
    value: Mapped[dict[str, object]] = mapped_column(JSONB, nullable=False, default=dict)
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
        onupdate=utc_now,
    )
