// bot/src/commands/aproved.ts — Handler do subcomando /bot aproved <card-id>
//
// Segurança:
//   S-02: assertOwner obrigatório antes de qualquer mutação
//   S-04: erros são redactSecrets antes de logar/enviar ao Slack

import { cardRepository, AccessDeniedError, CardNotFoundError } from '../db/cardRepository'
import type { WorkTrackerProvider } from '../providers/contracts'
import { redactSecrets } from './bot'

const CARD_ID_REGEX = /^(?:[A-Z][A-Z0-9]+-\d+|GH-\d+|[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+#\d+|https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/issues\/\d+(?:[?#].*)?)$/

export async function handleAproved(
  args: string,
  command: any,
  respond: any,
  _client: any,
  workTrackerProvider: WorkTrackerProvider,
): Promise<void> {
  const userId: string = command.user_id
  const cardId = args.trim().split(/\s+/)[0] ?? ''

  // 1. Validar card_id
  if (!CARD_ID_REGEX.test(cardId) || !workTrackerProvider.isValidCardId(cardId)) {
    await respond({
      text: `❌ ID de card inválido: \`${cardId}\`. Use *PROJ-123* para Jira ou *GH-123* para GitHub.`,
      response_type: 'ephemeral',
    })
    return
  }
  const localCardId = workTrackerProvider.normalizeCardId(cardId)

  // 2. S-02: assertOwner OBRIGATÓRIO
  try {
    cardRepository.assertOwner(localCardId, userId)
  } catch (err) {
    if (err instanceof CardNotFoundError) {
      await respond({ text: `❌ Card \`${localCardId}\` não encontrado.`, response_type: 'ephemeral' })
    } else if (err instanceof AccessDeniedError) {
      await respond({ text: `❌ Você não tem permissão para aprovar o card \`${localCardId}\`.`, response_type: 'ephemeral' })
    } else {
      const msg = redactSecrets(String(err instanceof Error ? err.message : err))
      console.error(`[aproved] assertOwner error:`, msg)
      await respond({ text: `❌ Erro ao verificar acesso ao card: ${msg}`, response_type: 'ephemeral' })
    }
    return
  }

  // 3. Feedback imediato
  await respond({ text: `⏳ Aprovando card \`${localCardId}\`...`, response_type: 'ephemeral' })

  try {
    // 4. Adicionar comentário /aprovado no work tracker
    await workTrackerProvider.addComment(localCardId, '/aprovado')

    // 5. Atualizar status no banco
    cardRepository.updateStatus(localCardId, 'aprovado')

    // 6. Feedback final
    await respond({
      text: `✅ Card \`${localCardId}\` aprovado e liberado para o time de desenvolvimento.`,
      response_type: 'ephemeral',
    })
  } catch (err) {
    const msg = redactSecrets(String(err instanceof Error ? err.message : err))
    console.error(`[aproved] erro ao aprovar card ${localCardId}:`, msg)
    await respond({ text: `❌ Erro ao aprovar card \`${localCardId}\`: ${msg}`, response_type: 'ephemeral' })
  }
}
