"""
Agile Together — Capitulo 1: configurar o board (rode UMA VEZ — ou de novo).

O que faz (tudo idempotente — seguro re-rodar):
  1. Le TOKEN e BOARD_ID do .env
  2. Renomeia listas A Fazer -> Product Backlog, Em Progresso -> Sprint Backlog
  3. Cria as listas Daily Scrum, Eventos Scrum e Referencia (se nao existirem)
  4. Sincroniza os eventos Scrum (sem dia da semana — qualquer dia):
     N x (K+3), com N=TOTAL_SPRINTS e K=DAILIES_POR_SPRINT do .env
     (padrao 3 x 7 = 21). Migra boards antigos e nunca apaga progresso.
  5. Popula a lista Referencia com os cards de playbook (titulo + prompt)
  6. Salva todos os IDs de lista no .env

Pre-requisito: ter preenchido PROJECTADM_TOKEN e BOARD_ID no .env.
Rode pelo menu do curso (Iniciar).
"""
import re
from agile_together import (api, cfg, save_cfg, list_lists,
                            find_list_id_by_name, list_cards,
                            _is_concluido, _stamp_conclusao)
from referencia_cards import CARDS as REFERENCIA_CARDS
from idioma import T, Tf
import listas as L

# Conversao de titulos de evento do formato ANTIGO (com dia da semana) para o
# NOVO (numerado), INDEPENDENTE de TOTAL_SPRINTS. Boards criados por versoes
# antigas tinham os eventos com dia da semana no titulo. Se a turma usa MENOS
# Sprints do que o board ja tem (ex.: TOTAL_SPRINTS=2 num board que nasceu com
# 3), os eventos da Sprint extra ficavam presos no formato antigo porque a
# migracao so cobria 1..TOTAL_SPRINTS. Agora normalizamos QUALQUER
# "Sprint N - <evento> (<dia>)", para qualquer N.
_DIA_PARA_SLOT = {"Terca": 1, "Terça": 1, "Quarta": 2, "Quinta": 3, "Sexta": 4}
_RE_EVENTO_ANTIGO = re.compile(
    r'^(Sprint \d+) - (Sprint Planning|Daily Scrum|Sprint Review|Retrospectiva)'
    r' \((Segunda|Terca|Terça|Quarta|Quinta|Sexta)\)$')


def _migra_titulo_evento(titulo):
    """Devolve o titulo de evento no formato novo (numerado), ou None se o
    titulo nao estiver no formato antigo (com dia da semana)."""
    m = _RE_EVENTO_ANTIGO.match((titulo or '').strip())
    if not m:
        return None
    pref, evento, dia = m.group(1), m.group(2), m.group(3)
    if evento == "Daily Scrum":
        slot = _DIA_PARA_SLOT.get(dia)
        return f"{pref} - Daily Scrum {slot}" if slot else None
    return f"{pref} - {evento}"


c = cfg()
if c.get('PROJECTADM_TOKEN') == 'SEU_TOKEN_AQUI' or not c.get('BOARD_ID'):
    raise SystemExit(T("ERRO: feche o menu e abra o Iniciar — e' ele que pede o seu token\n"
                     "      e cria o seu quadro. Depois volte a este passo 1."))

# ─────────────────────────────────────────────────────────────────────────────
# O NOME DO SEU PROJETO — porque o quadro E' o projeto
#
# Eduardo, 31/08/2026, rodando o curso no quadro 358 ("Envelhecer bem"):
#     "Nao perguntou o nome do projeto ou produto para renomear o quadro?"
#
# O Iniciar cria o quadro ANTES de o curso saber qual e' o projeto do aluno — ele nao
# tem como saber: a unica coisa perguntada ali e' o token. Entao o quadro nasce com o
# nome generico do course.json ("Meu projeto — Agile Together") e, ate' hoje, NADA
# perguntava depois: o aluno terminava as 3 Sprints com um quadro chamado "Meu projeto".
#
# E' o mesmo defeito que o BPM Together levou em 15/08 ("nao perguntou o nome do
# processo"), e a mesma solucao dos outros cursos da casa: quem pergunta e' o passo 1,
# quem grava e' o script, e o aluno nao abre arquivo nenhum. Renomear e' CONFORTO — se
# a API recusar, o passo segue, porque o nome ja' foi salvo no .env.
# ─────────────────────────────────────────────────────────────────────────────
_PLACEHOLDERS_PROJETO = ('ESCREVA O NOME DO SEU PROJETO AQUI',
                         'WRITE YOUR PROJECT NAME HERE')


def _renomear_quadro(nome):
    """O quadro passa a se chamar como o projeto. Nunca derruba o passo."""
    from pa_client import board_name, rename_board
    alvo = f"{nome} — Agile Together"
    try:
        if (board_name() or '').strip() == alvo:
            return                               # ja' se chama assim
        rename_board(c['BOARD_ID'], alvo)
        print(Tf('  O seu quadro passa a se chamar "{0}".', alvo))
    except Exception as e:
        print(Tf("  [aviso] nao consegui renomear o quadro ({0}) - segue o jogo.", e))


_proj = (c.get('PROJECT') or c.get('PROJETO') or '').strip()
_novo_proj = (not _proj) or _proj.upper() in _PLACEHOLDERS_PROJETO
print("\n" + "=" * 66)
print(T("  O SEU PROJETO — o nome que o seu quadro vai levar"))
print("=" * 66)
print(T("  O quadro que o Iniciar criou E' o seu projeto (ou o seu produto)."))
print(T("  Ele nasceu com o nome do curso porque nos ainda nao sabiamos o seu."))
if not _novo_proj:
    print("\n  " + Tf("Hoje: {0}", _proj))
    _pergunta_proj = T("  [Enter] mantem, ou digite um novo nome: ")
else:
    print(T('  Exemplo: "Envelhecer bem", "Meu podcast", "App de habitos".\n'))
    _pergunta_proj = T("  PROJETO = ")
while True:
    try:
        _r = input(_pergunta_proj).strip()
    except (EOFError, KeyboardInterrupt):
        _r = ""
    if not _r:
        if not _novo_proj:
            _renomear_quadro(_proj)              # confere o nome do quadro assim mesmo
        break                                    # sem nome, o curso roda igual
    if len(_r) >= 3 and _r.upper() not in _PLACEHOLDERS_PROJETO:
        save_cfg({'PROJECT': _r})
        c['PROJECT'] = c['PROJETO'] = _proj = _r
        print(Tf('  Guardado: "{0}".', _r))
        _renomear_quadro(_r)
        break
    print(T("  (um nome com pelo menos 3 letras — da' para mudar depois: e' so' rodar"))
    print(T("   este passo 1 de novo)\n"))


# O OBJETIVO (o "O" do OKR) e' a primeira decisao do curso, e e' SUA: nenhuma IA escreve
# por voce. Ate' 30/08 ele so' existia como uma linha do .env que o aluno tinha que ABRIR
# E EDITAR, e o passo 2 morria com "escreva o seu OBJETIVO no .env" — logo depois de o
# Iniciar ter prometido que o token era "a unica coisa que voce precisa digitar neste
# curso". A promessa e a pratica agora batem: quem pergunta e' o passo 1, quem grava e' o
# script, e o aluno nao abre arquivo nenhum.
_obj = (c.get('OBJETIVO') or '').strip()
_novo = not _obj or _obj.upper().startswith('ESCREVA')
print("\n" + "=" * 66)
print(T("  O SEU OBJETIVO — a primeira decisao do curso"))
print("=" * 66)
print(T("  Uma frase: onde voce quer chegar neste ciclo de Sprints."))
print(T("  SEM numero — o numero vive nos Key Results, que voce define depois."))
if not _novo:
    print("\n  " + Tf("Hoje: {0}", _obj))
    _pergunta = T("  [Enter] mantem, ou digite um novo objetivo: ")
else:
    print(T('  Exemplo: "Lancar a primeira versao do meu podcast"\n'))
    _pergunta = T("  OBJETIVO = ")
while True:
    try:
        _r = input(_pergunta).strip()
    except (EOFError, KeyboardInterrupt):
        _r = ""
    if not _r and not _novo:
        break                                   # manteve o que ja' tinha
    if len(_r) >= 8 and not _r.upper().startswith('ESCREVA'):
        save_cfg({'OBJETIVO': _r})
        c['OBJETIVO'] = _r
        print(T("  Guardado. (Rode este passo 1 de novo quando quiser mudar.)"))
        break
    if _novo:
        print(T("  (uma frase, por favor — o backlog inteiro e' ordenado contra ela)"))
    else:
        break

# 1. Renomear listas existentes
#
# ⚠️ O ProjectAdm MUDOU os nomes padrao do quadro novo: hoje nasce com
# "To Do / In Progress / Done" (medido em 15/08/2026, quadro 334); antes era
# "A Fazer / Em Progresso / Concluido". Comparar o nome exato deixava as tres
# listas orfas: o curso criava Product/Sprint Backlog do lado e o passo 7 salvava
# LIST_CONCLUIDO=0, porque nenhuma lista se chamava "Concluido". Por isso o mapa
# agora e' normalizado (minusculas) e cobre as duas linguas — incluindo "Done",
# que precisa virar "Concluido": esse nome e' o que o resto do curso procura.
print(T("Configurando listas..."))
listas = list_lists()
renames = L.PADRAO_PARA_LISTA
for l in listas:
    alvo = renames.get((l.get("nome") or "").strip().lower())
    # So renomeia se o destino ainda NAO existe — senao um board ja configurado
    # ganharia uma segunda "Product Backlog" a cada rodada.
    if alvo and not find_list_id_by_name(alvo, listas):
        api("PUT", f"/listas/{l['id']}", {"titulo": alvo})
        print(f"  {l['nome']} -> {alvo}")
        l["nome"] = alvo

# 1b. GARANTIR as tres listas do ciclo. O bloco acima so' RENOMEIA o que ja'
#     existe — e um quadro criado pela API (o caminho do Iniciar) nasce VAZIO.
#     Sem isto, o .env ficava com LIST_PRODUCT_BACKLOG/SPRINT_BACKLOG/CONCLUIDO
#     em 0 e o curso travava no primeiro passo que grava cartao.
print("")
for _nome in L.CICLO:
    listas = list_lists()
    if find_list_id_by_name(_nome, listas):
        continue
    api("POST", "/listas", {"quadro_id": c['BOARD_ID'], "titulo": _nome})
    print(Tf("  lista criada: {0}", _nome))

# 2. Criar lista Daily Scrum (foco do dia) - idempotente
print(T("\nCriando lista Daily Scrum..."))
listas = list_lists()
daily_id = find_list_id_by_name(L.DAILY_SCRUM, listas)
if daily_id:
    print(Tf("  Ja existe (ID={0})", daily_id))
else:
    r = api("POST", "/listas", {"quadro_id": c['BOARD_ID'], "titulo": L.DAILY_SCRUM})
    daily_id = r["dados"]["id"]
    print(Tf("  Lista criada (ID={0})", daily_id))

# 3. Criar lista Eventos Scrum (se ainda nao existir)
print(T("\nCriando lista Eventos Scrum..."))
listas = list_lists()
eventos_id = find_list_id_by_name(L.EVENTOS, listas)
if eventos_id:
    print(Tf("  Ja existe (ID={0})", eventos_id))
else:
    r = api("POST", "/listas", {"quadro_id": c['BOARD_ID'], "titulo": L.EVENTOS})
    eventos_id = r["dados"]["id"]
    print(Tf("  Lista criada (ID={0})", eventos_id))

# 4. Sincronizar os eventos Scrum da cadencia, em QUATRO partes:
#    (a) MIGRAR titulos antigos (com dia da semana) para o formato novo
#        (sem dia) — renomeia preservando id/status/datas, sem recriar.
#    (b) DEDUPLICAR copias do mesmo evento em duas listas (bug historico).
#    (c) CRIAR os eventos que ainda nao existem em lista NENHUMA.
#    (d) AVISAR sobre Dailies acima da cadencia atual (K reduzido).
#    Cadencia FIXA: K = DAILIES_POR_SPRINT (.env). Eventos/Sprint = K + 3
#    (1 Planning + K Dailies + 1 Review + 1 Retrospectiva). Os eventos NAO
#    tem mais dia da semana no titulo — podem ser feitos em QUALQUER dia.
TOTAL_SPRINTS = c.get('TOTAL_SPRINTS', 3)
K = c.get('DAILIES_POR_SPRINT', 4)
EVENTOS_POR_SPRINT = K + 3
print(Tf('\n Sincronizando {0} eventos Scrum ({1} Sprint(s) x {2} = 1 Planning + {3} Daily + '
         'Review + Retro)...', TOTAL_SPRINTS * EVENTOS_POR_SPRINT, TOTAL_SPRINTS, EVENTOS_POR_SPRINT, K))

# Titulos canonicos — SEM dia da semana (qualquer evento, qualquer dia).
titulos_eventos = []
for sprint in range(1, TOTAL_SPRINTS + 1):
    titulos_eventos.append(f"Sprint {sprint} - Sprint Planning")
    for d in range(1, K + 1):
        titulos_eventos.append(f"Sprint {sprint} - Daily Scrum {d}")
    titulos_eventos.append(f"Sprint {sprint} - Sprint Review")
    titulos_eventos.append(f"Sprint {sprint} - Retrospectiva")
titulos_eventos_set = set(titulos_eventos)

# (a) MIGRACAO de boards antigos: renomeia o formato com dia da semana para o
#     novo (ver _migra_titulo_evento). Renomear PRESERVA id, status concluido
#     e datas — o aluno em curso nao perde progresso e o KR3 nao infla.
#     Idempotente: na 2a rodada os titulos antigos ja nao existem. INDEPENDE
#     de TOTAL_SPRINTS: normaliza eventos de QUALQUER Sprint presente no board
#     (corrige a Sprint extra que ficava presa no formato antigo quando a
#     turma usa menos Sprints do que o board ja tinha).
_board = [(cd, lt['nome']) for lt in list_lists() for cd in list_cards(lt['id'])]
_titulos_no_board = {(cd.get('titulo') or '') for cd, _ in _board}
migrados = 0
for cd, _ in _board:
    t = cd.get('titulo', '') or ''
    novo = _migra_titulo_evento(t)
    if novo and novo != t and novo not in _titulos_no_board:
        api("PUT", f"/cartoes/{cd['id']}", {"titulo": novo})
        print(Tf("  [migrado] {0}  ->  {1}", t, novo))
        _titulos_no_board.discard(t)
        _titulos_no_board.add(novo)
        migrados += 1

# Mapa: titulo do evento -> lista de (card, nome_da_lista) onde ele aparece.
# IMPORTANTE: list_cards e paginado — api() direto so traria a 1a pagina (20
# cards), o que escondia eventos ja concluidos e gerava duplicatas.
ocorrencias = {}
for _lista in list_lists():
    for _card in list_cards(_lista['id']):
        t = _card.get('titulo', '')
        if t in titulos_eventos_set:
            ocorrencias.setdefault(t, []).append((_card, _lista['nome']))

# (b) Remover duplicatas, priorizando a copia que esta em Concluido.
dups = 0
for t, ocs in ocorrencias.items():
    if len(ocs) <= 1:
        continue
    # Principal a preservar: a copia em Concluido, se houver; senao a 1a.
    principal = next((oc for oc in ocs
                      if 'conclu' in (oc[1] or '').lower()), ocs[0])
    for card, nome_lista in ocs:
        if card is principal[0]:
            continue
        # So apagamos copias que estao na lista Eventos Scrum — nunca tocamos
        # em outras listas (Sprint Backlog, Daily Scrum, etc.).
        if 'eventos scrum' in (nome_lista or '').lower():
            try:
                api("DELETE", f"/cartoes/{card['id']}")
                print(Tf("  [duplicata removida de Eventos Scrum] {0}", t))
                dups += 1
            except Exception as e:
                print(Tf("  [AVISO] nao removeu duplicata de {0}: {1}", t, e))

# (c) Criar os eventos que nao existem em lista nenhuma. A dedup acima nunca
#     remove TODAS as copias (sempre preserva a principal), entao um titulo
#     presente em 'ocorrencias' continua existindo no board apos a limpeza.
criados = pulados = 0
for t in titulos_eventos:
    if t in ocorrencias:
        pulados += 1
    else:
        api("POST", "/cartoes", {"lista_id": eventos_id, "titulo": t})
        print(Tf("  [criado] {0}", t))
        criados += 1
print(Tf("  Resumo: {0} criados, {1} ja existiam, {2} duplicata(s) removida(s), {3} migrado(s).", criados, pulados, dups, migrados))

# (d) AVISO: Dailies acima da cadencia atual (ex.: DAILIES_POR_SPRINT foi
#     REDUZIDO num board ja existente). NAO apagamos dados do aluno — apenas
#     avisamos, para o professor decidir.
extras = []
for _lista in list_lists():
    for _card in list_cards(_lista['id']):
        m = re.match(r'^Sprint (\d+) - Daily Scrum (\d+)$',
                     _card.get('titulo', '') or '')
        if m and int(m.group(2)) > K:
            extras.append(_card.get('titulo'))
if extras:
    print(Tf("  [AVISO] {0} Daily(s) ACIMA da cadencia atual (DAILIES_POR_SPRINT={1}) "
             "continuam no board (nao apagados):", len(extras), K))
    for t in sorted(set(extras))[:8]:
        print(f"    . {t}")
    print(T("    Se reduziu a cadencia de proposito, apague-os manualmente no "
          "ProjectAdm; caso contrario, aumente DAILIES_POR_SPRINT no .env."))

# 4b. SAUDE DO BOARD: cards na lista 'Concluido' SEM o status concluido=true.
#     Acontece quando um card e ARRASTADO manualmente para a coluna Concluido
#     (na UI) em vez de concluido pelos scripts do curso: ele muda de lista,
#     mas o FLAG de status nao e marcado. Como os KRs contam pelo STATUS (nao
#     pela coluna), esses cards sao silenciosamente ignorados — foi exatamente
#     o que derrubou a contagem de eventos. Detectamos e OFERECEMOS corrigir.
print(T("\nVerificando saude da lista 'Concluido' (status concluido=true)..."))
listas = list_lists()
concluido_id = (find_list_id_by_name(L.CONCLUIDO, listas)
                or find_list_id_by_name("Concluído", listas))
sem_status = [cd for cd in list_cards(concluido_id)
              if not _is_concluido(cd)] if concluido_id else []
if sem_status:
    print(Tf("  ATENCAO: {0} card(s) na lista 'Concluido' SEM status concluido=true "
             "(provavelmente arrastados na UI):", len(sem_status)))
    for cd in sem_status[:12]:
        print(f"    - {(cd.get('titulo') or '')[:68]}")
    if len(sem_status) > 12:
        print(Tf("    ... e mais {0}", len(sem_status) - 12))
    resp = input(
        Tf('\n Marcar esses {0} card(s) como concluido=true agora? (datas de conclusao '
           'existentes sao preservadas) [s/N]', len(sem_status))
    ).strip().lower()
    if resp in ('s', 'sim', 'y', 'yes'):
        ok = 0
        for cd in sem_status:
            try:
                _stamp_conclusao(cd['id'])  # preserva data existente; so
                ok += 1                      # carimba 'agora' se nao houver
            except Exception as e:
                print(f"  [ERRO] {(cd.get('titulo') or '')[:50]}: {e}")
        print(Tf("  [OK] {0}/{1} card(s) marcado(s) como concluido.", ok, len(sem_status)))
    else:
        print(T("  Nada alterado. (Os KRs continuarao ignorando esses cards "
              "ate que tenham status concluido=true.)"))
else:
    print(T("  OK — todos os cards de 'Concluido' tem status concluido=true."))

# 5. Criar lista Referencia (playbook do curso) - idempotente
print(T("\nCriando lista Referencia..."))
listas = list_lists()
referencia_id = next((find_list_id_by_name(n, listas)
                      for n in L.REFERENCIA_ALTERNATIVAS
                      if find_list_id_by_name(n, listas)), None)
if referencia_id:
    print(Tf("  Ja existe (ID={0})", referencia_id))
else:
    r = api("POST", "/listas", {"quadro_id": c['BOARD_ID'], "titulo": L.REFERENCIA})
    referencia_id = r["dados"]["id"]
    print(Tf("  Lista criada (ID={0})", referencia_id))

# 6. Popular Referencia (UPSERT robusto: procura o card em TODAS as listas
#    do board — nao so na Referencia. Se um card de playbook foi movido para
#    Concluido ou outra lista, ele e ATUALIZADO e MOVIDO de volta para a
#    Referencia, em vez de recriado (evita duplicatas). Ao final, remove
#    cards orfaos (na Referencia mas fora de referencia_cards.py).
print(Tf('\nPopulando lista Referencia com {0} cards de playbook...', len(REFERENCIA_CARDS)))
todos_por_titulo = {}
for _lista in list_lists():
    for card in list_cards(_lista['id']):
        todos_por_titulo.setdefault(card.get('titulo', ''), []).append(
            (card, _lista['id']))

ref_criados = ref_atualizados = ref_movidos = ref_dups = 0
for titulo, descricao in REFERENCIA_CARDS:
    ocorrencias = todos_por_titulo.get(titulo, [])
    if ocorrencias:
        principal, principal_lista = ocorrencias[0]
        api("PUT", f"/cartoes/{principal['id']}", {"descricao": descricao})
        if str(principal_lista) != str(referencia_id):
            api("PUT", f"/cartoes/{principal['id']}/mover",
                {"lista_id": referencia_id})
            print(Tf("  [movido+atualizado] {0} (estava fora da Referencia)", titulo[:55]))
            ref_movidos += 1
        else:
            print(Tf("  [atualizado] {0}", titulo))
            ref_atualizados += 1
        for dup, _ in ocorrencias[1:]:
            try:
                api("DELETE", f"/cartoes/{dup['id']}")
                print(Tf("     [removida duplicata] {0}", titulo))
                ref_dups += 1
            except Exception as e:
                print(Tf("     [AVISO] nao removeu duplicata de {0}: {1}", titulo, e))
    else:
        api("POST", "/cartoes", {
            "lista_id": referencia_id, "titulo": titulo, "descricao": descricao})
        print(Tf("  [criado] {0}", titulo))
        ref_criados += 1

# Remove orfaos: cards ATUALMENTE na Referencia cujo titulo nao consta em
# referencia_cards.py (tipicamente versoes antigas com titulo diferente).
#
# ⚠️ A CAIXA DE ENTRADA E' A EXCECAO. Desde 31/08/2026 ela vive AQUI, como primeiro
# cartao da Referencia — e ela nao esta' (nem pode estar) em referencia_cards.py:
# a descricao dela e' o que o ALUNO cola, e este bloco reescreve a descricao de todo
# cartao do playbook. Sem esta excecao, rodar o passo 1 apagaria a caixa — junto com
# a resposta que o aluno tivesse acabado de colar nela.
import caixa
titulos_esperados = {t for t, _ in REFERENCIA_CARDS} | {caixa.CARTAO}
ref_orfaos = 0
for card in list_cards(referencia_id):
    if caixa._e_a_caixa(card):
        continue
    if card.get('titulo', '') not in titulos_esperados:
        try:
            api("DELETE", f"/cartoes/{card['id']}")
            print(Tf("  [orfao removido] {0}", card.get('titulo', '')[:55]))
            ref_orfaos += 1
        except Exception as e:
            print(Tf("  [AVISO] nao removeu orfao {0}: {1}", card.get('titulo', '')[:40], e))
print(Tf("  Resumo: {0} criados, {1} atualizados, {2} movidos, {3} duplicata(s), {4} orfao(s) "
         "removido(s).", ref_criados, ref_atualizados, ref_movidos, ref_dups, ref_orfaos))

# 7. Salvar IDs no .env (busca pelo nome final apos renomeacoes)
print(T("\nSalvando IDs no .env..."))
listas = list_lists()
ids = {
    'LIST_PRODUCT_BACKLOG': find_list_id_by_name("Product Backlog", listas) or 0,
    'LIST_SPRINT_BACKLOG':  find_list_id_by_name("Sprint Backlog", listas) or 0,
    'LIST_DAILY_SCRUM':     daily_id or 0,
    'LIST_CONCLUIDO':       find_list_id_by_name(L.CONCLUIDO, listas)
                            or find_list_id_by_name("Concluído", listas) or 0,
    'LIST_EVENTOS_SCRUM':   eventos_id or 0,
    'LIST_REFERENCIA':      referencia_id or 0,
}
save_cfg(ids)
for k, v in ids.items():
    print(f"  {k}={v}")

# 8. A Caixa de entrada: o cartao por onde a resposta da sua IA entra no quadro.
#    E' ele que substituiu a "ZONA DE EDICAO" dentro dos scripts (30/08/2026):
#    o aluno nunca mais abre um arquivo .py para colar resposta de IA.
#
#    Desde 31/08/2026 ele e' o PRIMEIRO cartao da Referencia, e nao mais uma lista
#    so' para si (Eduardo, quadro 358: "que o card caixa de entrada seja o primeiro
#    da lista de referencia e nao exista a lista Caixa de entrada"). Um quadro que
#    nasceu na versao anterior e' migrado aqui: o cartao MUDA de lista (preservando
#    o que estiver escrito nele) e a lista antiga, se ficar vazia, e' apagada.
print(T("\nPreparando a Caixa de entrada..."))
_caixa_card = caixa.garantir(log=lambda m: print(f"  {m}"))
print(Tf('  Cartao "{0}" pronto na lista "{1}".', caixa.CARTAO, caixa.LISTA))

# 8b. A ORDEM VISIVEL da Referencia: a Caixa primeiro, depois o playbook 00..10.
#     Um cartao MOVIDO de volta (ou criado agora) entra no fim da lista — e o aluno
#     via o playbook fora de ordem, com o 07 antes do 03. Cartao que o ALUNO criou
#     nesta lista vai para o fim, na ordem em que ele os criou: nao some, nao se mistura.
_atual = list_cards(referencia_id)
_por_titulo = {(cd.get('titulo') or ''): cd for cd in _atual}
_ordem = [_caixa_card['id']]
_ordem += [_por_titulo[t]['id'] for t, _d in REFERENCIA_CARDS if t in _por_titulo]
_nossos = set(_ordem)
_ordem += [cd['id'] for cd in _atual if cd['id'] not in _nossos]
if _ordem != [cd['id'] for cd in _atual]:
    try:
        from pa_client import ordenar_cartoes
        ordenar_cartoes(referencia_id, _ordem)
        print(T("  Referencia reordenada: a Caixa de entrada e o primeiro cartao."))
    except Exception as e:
        print(Tf("  [aviso] nao consegui reordenar a Referencia ({0}) - segue o jogo.", e))

print(T("\nPronto! Quadro configurado e .env atualizado."))
print(T("Como funciona daqui em diante:"))
print(T("  o passo entrega o prompt -> voce cola na sua IA -> cola a resposta no"))
print(Tf('  cartao "{0}" -> roda o mesmo passo de novo.', caixa.CARTAO))
print(T("Proximo passo do menu: 2. Meta do Produto + Product Backlog."))
