"""
Project Together — powered by AI: PASSO 10 — Encerrar (o projeto ou uma fase) e verificar o valor.

Encerrar não é 'acabou': é provar se o VALOR prometido chegou. Você pode encerrar o
PROJETO inteiro ou apenas uma FASE dele (o Guia PMBOK 8 trata os dois no mesmo processo,
"Encerrar o Projeto ou Fase"). No projeto, você compara o realizado com os Key Results do
Passo 1; na fase, valida as entregas dela e recomenda seguir ou não para a próxima. Em
qualquer caso, registra as lições que levaria adiante. Projeto que entrega produto mas
não entrega valor não acabou, só parou.

Este passo escreve na lista Concluído:
  • um cartão "🎯 Resultado do OKR" — cada Key Result: meta × realizado × atingido;
  • um cartão "📚 Lições aprendidas" — o que repetir e o que mudar.

NO ÁGIL este passo é a SPRINT RETROSPECTIVE — o evento que CONCLUI a Sprint. A Review
(Passo 8) inspecionou o PRODUTO; a Retrospectiva olha o COMO o time trabalhou: pessoas,
relações, processo e ferramentas. E ela não termina em desabafo: termina em ATÉ 3 ações
de melhoria, que entram no Sprint Backlog da próxima Sprint como qualquer outro
trabalho. Fechada a Retrospectiva, o contador da Sprint avança no .env e o ciclo volta
ao Passo 5 (a Sprint Planning seguinte) — até que o produto entregue o valor prometido,
quando este mesmo passo encerra o PROJETO (realizado × Key Results do Passo 1).

O RITMO (modo CHAT): prompt do Passo 10 (traz o seu OKR e a foto do quadro) → IA →
resposta ([P10]) na Caixa de entrada → rode este passo.
"""
import re
from datetime import date

import entradas
import passos
import team_check
from env import get_int, save_cfg
from runner import ok, step, warn
from idioma import T, Tf

N = 10
c, ids, abordagem = passos.abrir(N)
bloco = passos.ler_bloco(ids, N, T("nenhum encerramento"))

# Os rótulos das seções vêm da RESPOSTA da IA, que responde no idioma do prompt: o pacote
# EN pede CLOSING / RESULT / LESSONS / ACTIONS. Aceitar os dois conjuntos é o que faz o
# passo enxergar a resposta do aluno de língua inglesa (antes ele não achava seção nenhuma).
secs = entradas.secoes(bloco, ["ENCERRANDO", "RESULTADO", "RESULTADO_OKR", "LICOES",
                               "LIÇÕES", "LICOES APRENDIDAS", "ACOES", "AÇÕES",
                               "CLOSING", "RESULT", "OKR_RESULT", "LESSONS",
                               "LESSONS LEARNED", "ACTIONS"])
resultado = entradas.itens(secs.get("resultado", "") or secs.get("resultado_okr", "")
                           or secs.get("result", "") or secs.get("okr_result", ""))
licoes = entradas.itens(secs.get("licoes", "") or secs.get("lições", "")
                        or secs.get("licoes aprendidas", "")
                        or secs.get("lessons", "") or secs.get("lessons learned", ""))
acoes = entradas.itens(secs.get("acoes", "") or secs.get("ações", "")
                       or secs.get("actions", ""))
if not resultado and not licoes:
    raise SystemExit(T("Não achei RESULTADO nem LIÇÕES no bloco [P10]. Confira o formato "
                     "e cole de novo."))

# A ação de melhoria da Retrospectiva entra na próxima Sprint COMO TRABALHO — logo, o
# dono dela sai da mesma lista fechada de todo o resto (team_check).
team_check.conferir(acoes, ids, campo="dono", o_que=T("ação(ões) de melhoria"))

hoje = date.today().isoformat()

# ── O QUE ESTÁ SENDO FECHADO: a Sprint (e o ciclo recomeça) ou o PROJETO? ────
# No ágil o mesmo passo serve aos dois — a pergunta é a mesma em escalas diferentes. Quem
# decide é a linha ENCERRANDO da resposta; sem ela, o padrão no ágil é a Sprint (o caso
# comum: fecha uma, abre a próxima) e na preditiva é o projeto/fase, como sempre foi.
sprint = max(1, get_int(c, "CURRENT_SPRINT", 1)) if abordagem == "AGIL" else 0
# A linha ENCERRANDO é lida por REGEX, não pelo secoes(): o entradas.secoes só aceita um
# cabeçalho com menos de 60 caracteres (para não confundir uma frase que cite um rótulo
# com uma seção de verdade), e o prompt pede que esta linha traga o porquê junto — o que
# facilmente passa dos 60. Sem isto, "ENCERRANDO: PROJETO — os KRs foram atingidos e o
# produto já entrega o valor" era ignorado e o passo fechava uma SPRINT, avançando o
# contador, quando o aluno estava encerrando o PROJETO. (Pego no teste de 2026-07-27.)
# O rótulo e a palavra saem no idioma do prompt: ENCERRANDO/PROJETO no pacote PT,
# CLOSING/PROJECT no EN. Procurar só o português fazia o pacote inglês fechar SEMPRE uma
# Sprint — o aluno dizia "CLOSING: PROJECT" e o contador avançava para a Sprint seguinte.
_m_enc = re.search(r"(?im)^\s*(?:ENCERRANDO|CLOSING)\s*[:：]\s*(.+)$", bloco)
_encerrando = entradas._sem_acento(_m_enc.group(1) if _m_enc else
                                   (secs.get("encerrando", "") or secs.get("closing", "")))
fecha_projeto = abordagem != "AGIL" or "projeto" in _encerrando or "project" in _encerrando
fecha_sprint = abordagem == "AGIL" and not fecha_projeto
cartoes = []

if resultado:
    linhas = [Tf("Verificação de valor — {0}", hoje), ""]
    atingidos = parciais = nao = 0
    for r in resultado:
        estado = entradas._sem_acento(r.get("atingido", ""))
        marca = {"sim": "✅", "parcial": "🟡", "nao": "❌"}.get(estado, "•")
        atingidos += estado == "sim"
        parciais += estado == "parcial"
        nao += estado == "nao"
        linhas.append(f"{marca} {r.get('_','')}")
        det = " · ".join(f"{passos.rotulo_de_campo(k)}: {r[k]}"
                         for k in ("meta", "realizado", "por que") if r.get(k))
        if det:
            linhas.append(f"    {det}")
    placar = Tf("{0} atingido(s), {1} parcial(is), {2} não atingido(s)",
                atingidos, parciais, nao)
    linhas += ["", Tf("PLACAR: {0}", placar)]
    # Cada Sprint tem a SUA retrospectiva: o título leva o número, senão a Sprint 2
    # sobrescreveria o registro da Sprint 1 (escrever_cartoes casa pelo título).
    titulo_res = (Tf("🔄 Retrospectiva — Sprint {0} · a Meta foi atingida?", sprint)
                  if fecha_sprint else T("🎯 Resultado do OKR — o valor entregou?"))
    cartoes.append((titulo_res, "\n".join(linhas), None))

if licoes:
    linhas = [Tf("Lições aprendidas — {0}", hoje), ""]
    for l in licoes:
        linhas.append(f"• {l.get('_','')}")
        for k, rot in (("o que aconteceu", T("o que aconteceu")),
                       ("o que eu faria diferente", T("o que eu faria diferente")),
                       ("serve para", T("serve para"))):
            if l.get(k):
                linhas.append(f"    {rot}: {l[k]}")
    titulo_lic = (Tf("📚 Lições aprendidas — Sprint {0}", sprint) if fecha_sprint
                  else T("📚 Lições aprendidas"))
    cartoes.append((titulo_lic, "\n".join(linhas), None))

n = passos.escrever_cartoes(ids, "CONCLUIDO", cartoes, log=step)
ok(Tf("Encerramento no quadro: {0} resultado(s) verificado(s), {1} lição(ões) registrada(s).", len(resultado), len(licoes)))

# ── AS AÇÕES DE MELHORIA (só no ágil): retrospectiva que não vira trabalho é desabafo ──
# O Guia Scrum é explícito: as melhorias mais impactantes podem ser adicionadas ao Sprint
# Backlog da PRÓXIMA Sprint. Então elas não ficam num relatório — viram cartão de
# trabalho, com dono, na lista em que o time olha todo dia.
n_acoes = 0
if acoes and abordagem == "AGIL":
    cartoes_acao = []
    for a in acoes[:3]:                       # no máximo 3: quem promete dez não faz nenhuma
        texto = (a.get("_", "") or "").strip()
        if not texto:
            continue
        desc = Tf("Ação de melhoria da Retrospectiva da Sprint {0} ({1}).\n"
                  "Dono: {2}\n"
                  "Como saberei que funcionou: {3}\n\n"
                  "Melhoria é trabalho: ela entra na próxima Sprint como qualquer outro item "
                  "e é inspecionada na próxima Retrospectiva.",
                  sprint, hoje, a.get('dono', '?'),
                  a.get('como saberei que funcionou', '?'))
        cartoes_acao.append((f"🔧 Melhoria (Retro Sprint {sprint}): {texto[:80]}", desc, None))
    if cartoes_acao:
        n_acoes = passos.escrever_cartoes(ids, "EXECUCAO", cartoes_acao, log=step)
        ok(Tf("{0} ação(ões) de melhoria 🔧 no Sprint Backlog — elas entram na Sprint {1} como "
              "trabalho, com dono e com o sinal de que funcionaram.", n_acoes, sprint + 1))

# Artefato do Passo 10: o documento de Lições Aprendidas (.docx), lido do quadro.
try:
    import artefatos
    cam, _av = artefatos.gerar_licoes_aprendidas(ids, abordagem=abordagem, log=step)
    if cam:
        ok(T("Lições Aprendidas geradas em _saida/documentos/ (.docx) — objetivos × realizado "
           "e as recomendações para o próximo projeto."))
except Exception as e:
    warn(Tf("não consegui gerar o documento de Lições Aprendidas agora: {0}", e))

if fecha_sprint:
    # A Retrospectiva CONCLUI a Sprint — é ela que avança o contador (a mesma regra do
    # Agile Together: sprint_retrospective.py incrementa SPRINT_ATUAL, a Review não).
    proxima = sprint + 1
    try:
        save_cfg({"CURRENT_SPRINT": proxima})
        ok(Tf("Sprint {0} concluída. O contador avançou: você está agora na Sprint {1} "
              "(SPRINT_ATUAL no .env).", sprint, proxima))
    except Exception as e:
        warn(Tf("não consegui avançar SPRINT_ATUAL no .env: {0}. Ajuste na mão para {1} antes "
                "da próxima Sprint Planning.", e, proxima))
    resumo = Tf("Retrospectiva da Sprint {0}: {1} lição(ões), {2} ação(ões) de melhoria. "
                "Próxima: Sprint {3}.", sprint, len(licoes), n_acoes, proxima)
    conclusao = Tf("Passo 10 concluído — a Sprint {0} está fechada. O ciclo recomeça: "
                   "volte ao PASSO 5 para a Sprint Planning da Sprint {1}. As ações de "
                   "melhoria já estão no Sprint Backlog esperando por ela. Quando o produto "
                   "entregar o valor prometido, rode este passo de novo escrevendo "
                   "'ENCERRANDO: PROJETO' — aí ele encerra o projeto e verifica os seus Key "
                   "Results.", sprint, proxima)
else:
    resumo = Tf("Encerramento: {0} resultado(s) verificado(s), {1} lição(ões).",
                len(resultado), len(licoes))
    conclusao = T("Passo 10 concluído — você provou (ou não) que o valor chegou "
                  "e guardou as lições para a próxima fase ou o próximo projeto.")

passos.finalizar(N, ids, resumo=resumo, mensagem_conclusao=conclusao,
                 proximo=5 if fecha_sprint else None)
