"""Add status + accepted_at to heap_shares and folder_shares

Revision ID: 0014_share_status
Revises: 0013_drop_old_ct
Create Date: 2026-04-21

Shares used to activate instantly on the owner's side. We now want a
pending/accepted lifecycle so the recipient gets a notification bell and
chooses to accept or decline before the shared item shows up in their
sidebar.

Backfill note: every pre-existing row is treated as `accepted` with
accepted_at = created_at. This is a pragmatic fiction — it keeps the
sidebar populated after the migration without anyone having to click
accept on shares that were already live. Any future "accepted X ago" UI
inheriting this backfilled timestamp should be aware it's not a real
user-action moment.

The one-migration trick: we add `status` with `server_default="accepted"`
so the backfill happens in-place, then drop the default so new inserts
fall through to the Python-side model default ("pending").
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

revision: str = "0014_share_status"
down_revision: Union[str, None] = "0013_drop_old_ct"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    for table in ("heap_shares", "folder_shares"):
        op.add_column(
            table,
            sa.Column(
                "status",
                sa.String(),
                nullable=False,
                server_default="accepted",
            ),
        )
        op.add_column(
            table,
            sa.Column("accepted_at", sa.DateTime(), nullable=True),
        )
        op.execute(
            f"UPDATE {table} SET accepted_at = created_at "
            "WHERE accepted_at IS NULL"
        )
        # Drop the DB default so new rows inherit the Python-side
        # model default ("pending") instead of silently auto-accepting.
        op.alter_column(table, "status", server_default=None)
        op.create_index(
            f"ix_{table}_shared_with_status",
            table,
            ["shared_with_id", "status"],
        )


def downgrade() -> None:
    for table in ("heap_shares", "folder_shares"):
        op.drop_index(f"ix_{table}_shared_with_status", table_name=table)
        op.drop_column(table, "accepted_at")
        op.drop_column(table, "status")
