"""여러 편 처리 — 신원 장부 · 화별 자리 · 아웃룩 관계의 화 범위.

세 가지를 더한다. ★전부 **additive** 다 — 기존 행을 안 지우고 안 덮는다.

1. `project_short_id_counter` — `short_id` 를 프로젝트가 발급하기 위한
   **줄지 않는 장부**. 화마다 `01` 부터 다시 매기다 2화가 1화 행을 덮던 것을
   막는다 (실측: 골목 끝 `da049582`).
2. `entity_episode_link.presence_status` / `episode_notes_json` —
   「이 화에서 저빈도라 보류」는 **화마다 다른 상태**지 프로젝트 전역 상태가
   아니다. 이번 화의 묘사도 여기 둔다(canon 의 안정 칸을 덮지 않으려고).
3. `character_outlook.episode_id` — 지금은 화 범위가 없어서, 같은 인물이
   다음 화에 다른 옷을 입으면 **앞 화 관계가 지워진다**.
   ★기존 행은 `NULL`(= 어느 화 것인지 모르는 legacy)로 남긴다. 지우지도
    추측해 채우지도 않는다 — 코드가 쓰면서 제 화로 이어받는다.

Revision ID: 014_multi_episode_identity
Revises: 013_grounding_ref_selection
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

revision: str = "014_multi_episode_identity"
down_revision: Union[str, None] = "013_grounding_ref_selection"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ── 1. short_id 발급 장부 ────────────────────────────────────────────
    op.create_table(
        "project_short_id_counter",
        sa.Column("project_id", sa.Text(),
                  sa.ForeignKey("project_registry.id"), primary_key=True),
        # 갈래 이름(character/location/prop/location_part/outlook). 접두 글자가
        # 아니라 갈래를 키로 쓴다 — 접두표가 prefix-free 가 아니다(L 과 LP).
        sa.Column("owner", sa.Text(), primary_key=True),
        # ★「이미 쓴 최대 번호」다. 절대 줄지 않는다 — 줄면 지워진 번호를
        #  다시 발급해 옛 체크포인트와 충돌한다.
        sa.Column("high_water", sa.Integer(), nullable=False, server_default="0"),
    )

    # ── 2. 링크에 「이 화에서의 자리」 ───────────────────────────────────
    op.add_column("entity_episode_link",
                  sa.Column("presence_status", sa.Text(), nullable=False,
                            server_default="active"))
    op.add_column("entity_episode_link",
                  sa.Column("episode_notes_json", sa.Text(), nullable=True))
    op.create_index("ix_entity_episode_link_presence", "entity_episode_link",
                    ["project_id", "episode_id", "presence_status"])

    # ── 3. 아웃룩 관계의 화 범위 ─────────────────────────────────────────
    #  ★기존 유일성 `(character_id, outlook_id)` 는 **안 지운다**. 그것을
    #   지우면 legacy 행의 중복 방지가 사라진다. 화 범위 유일성을 **더한다**.
    #   PostgreSQL 은 NULL 을 서로 다르게 보므로 legacy(NULL) 행은 새 제약에
    #   안 걸린다.
    op.add_column("character_outlook",
                  sa.Column("episode_id", sa.Text(), nullable=True))
    op.create_index("ix_character_outlook_episode", "character_outlook",
                    ["project_id", "episode_id"])


def downgrade() -> None:
    op.drop_index("ix_character_outlook_episode", table_name="character_outlook")
    op.drop_column("character_outlook", "episode_id")
    op.drop_index("ix_entity_episode_link_presence",
                  table_name="entity_episode_link")
    op.drop_column("entity_episode_link", "episode_notes_json")
    op.drop_column("entity_episode_link", "presence_status")
    op.drop_table("project_short_id_counter")
