// bot/src/commands/view.ts — Handler do subcomando /bot view <card-id>
//
// RF-15: lê apenas do SQLite, sem chamar IA.
// S-02: assertOwner obrigatório antes de qualquer leitura sensível.
// 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+(?:[?#].*)?)$/
const MAX_INLINE_CHARS = 3000

export async function handleView(
  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 antes de leitura sensível
  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 visualizar o card \`${localCardId}\`.`, response_type: 'ephemeral' })
    } else {
      const msg = redactSecrets(String(err instanceof Error ? err.message : err))
      console.error(`[view] assertOwner error:`, msg)
      await respond({ text: `❌ Erro ao verificar acesso ao card: ${msg}`, response_type: 'ephemeral' })
    }
    return
  }

  try {
    // 3. Buscar estágios do SQLite (RF-15: apenas leitura local, sem IA)
    const stages = cardRepository.getStages(localCardId)

    // 4. Nenhuma etapa gerada ainda
    if (stages.length === 0) {
      await respond({
        text: `Nenhum documento gerado ainda para \`${localCardId}\`.`,
        response_type: 'ephemeral',
      })
      return
    }

    // 5. Exibir cada etapa
    for (const stage of stages) {
      const header = `*Etapa: ${stage.stage}* (gerado em ${stage.gerado_em})\n`
      const conteudo = stage.conteudo ?? ''
      const bloco = header + conteudo

      if (bloco.length > MAX_INLINE_CHARS) {
        // Upload como arquivo
        await client.files.uploadV2({
          channel_id: command.channel_id,
          content: conteudo,
          filename: `${localCardId}-${stage.stage}.md`,
          title: `${localCardId} — ${stage.stage}`,
        })
      } else {
        await respond({ text: bloco, response_type: 'ephemeral' })
      }
    }
  } catch (err) {
    const msg = redactSecrets(String(err instanceof Error ? err.message : err))
    console.error(`[view] erro ao exibir card ${localCardId}:`, msg)
    await respond({ text: `❌ Erro ao exibir card \`${localCardId}\`: ${msg}`, response_type: 'ephemeral' })
  }
}
