/**
 * Workflow: Gestão de Reputação de Contato
 *
 * Regra de negócio:
 *   - Cada falta/infração reduz o score_reputacao do contato.
 *   - Score ≤ 20 → contato entra em flag_restricao = true.
 *   - Agendamentos automáticos são bloqueados para contatos RESTRITOS.
 *   - Score é recuperável manualmente pelo agente (fora deste workflow).
 */
import {
  proxyActivities,
  defineSignal,
  setHandler,
  condition,
  log,
} from '@temporalio/workflow'
import type * as acts from '../activities'

const {
  decrementarScore,
  bloquearAgendamentosAutomaticos,
  buscarScoreContato,
} = proxyActivities<typeof acts>({
  startToCloseTimeout: '30 seconds',
  retry: { maximumAttempts: 3 },
})

// Signal para registrar uma nova infração
export const registrarInfracaoSignal = defineSignal<[{
  motivo: string
  pontos: number
}]>('registrarInfracao')

// Signal para encerrar o monitoramento (contato reabilitado manualmente)
export const encerrarMonitoramentoSignal = defineSignal('encerrarMonitoramento')

export interface ReputacaoInput {
  contactId: string
  tenantId: string
}

export async function reputacaoWorkflow(input: ReputacaoInput): Promise<void> {
  let encerrado = false
  const infracoesPendentes: Array<{ motivo: string; pontos: number }> = []

  setHandler(registrarInfracaoSignal, (payload) => {
    log.info('Infração registrada via signal', payload)
    infracoesPendentes.push(payload)
  })

  setHandler(encerrarMonitoramentoSignal, () => {
    encerrado = true
  })

  // Loop durável — o Temporal mantém o estado mesmo após reinícios
  while (!encerrado) {
    // Aguarda próxima infração ou encerramento
    await condition(() => infracoesPendentes.length > 0 || encerrado)

    if (encerrado) break

    const infracao = infracoesPendentes.shift()!

    const { novoScore, restrito } = await decrementarScore({
      contactId: input.contactId,
      motivo: infracao.motivo,
      pontos: infracao.pontos,
    })

    log.info('Score atualizado', { novoScore, restrito, contactId: input.contactId })

    if (restrito) {
      await bloquearAgendamentosAutomaticos({ contactId: input.contactId })
      log.warn('Contato RESTRITO — agendamentos automáticos bloqueados', {
        contactId: input.contactId,
        scoreAtual: novoScore,
      })
      // Continua monitorando (restrição é revertida manualmente pelo agente)
    }
  }

  log.info('Monitoramento de reputação encerrado', { contactId: input.contactId })
}
