# Eventos de notificação + assinatura por grupo.
#
# O ADM cadastra quantos eventos quiser, mas o GATILHO sai de uma lista fixa:
# gatilho é código. `manual` cobre o aviso pontual (botão "disparar agora") e
# `agendado` cobre o resumo periódico; os demais são pontos que o sistema já
# conhece (consolidação finalizada, pagamento efetuado, valor alterado, dados da
# operação mudaram).
#
# `sistema: true` marca os eventos que nascem com o app: podem ser editados e
# desligados, mas não apagados — apagar deixaria o código disparando no vazio.
class CreateNotificacaoEventos < ActiveRecord::Migration[7.1]
  GATILHOS = %w[manual consolidacao_finalizada pagamento_efetuado
                valor_alterado operacao_alterada agendado].freeze

  def up
    create_table :eventos_notificacao do |t|
      t.string  :nome,     null: false
      t.string  :chave,    null: false          # slug estável usado pelo código
      t.string  :gatilho,  null: false
      t.string  :descricao
      t.boolean :ativo,    null: false, default: true
      t.boolean :sistema,  null: false, default: false

      # Avisar também a pessoa diretamente envolvida no fato (o motorista do
      # pagamento), além dos grupos assinantes. É o comportamento de hoje.
      t.boolean :notificar_envolvido, null: false, default: true

      # Só para gatilho `agendado`.
      t.string  :frequencia            # diaria | semanal
      t.integer :hora,      default: 8 # 0..23
      t.integer :dia_semana            # 0..6 (domingo=0), só na semanal
      t.datetime :ultimo_disparo_em

      t.timestamps
    end
    add_index :eventos_notificacao, :chave, unique: true

    create_table :grupo_evento_assinaturas do |t|
      # ⚠️ `to_table:` é OBRIGATÓRIO aqui. Com `foreign_key: true` o Rails
      # PLURALIZA o nome da referência para achar a tabela alvo, e o Inflector
      # não fala português: `grupo_contato` → "grupo_contatos" e
      # `evento_notificacao` → "evento_notificacaos". As tabelas reais são
      # `grupos_contato` e `eventos_notificacao` (plural no primeiro termo).
      t.references :grupo_contato,      null: false, foreign_key: { to_table: :grupos_contato }
      t.references :evento_notificacao, null: false, foreign_key: { to_table: :eventos_notificacao }
      t.string  :canal, null: false, default: 'ambos'  # ambos | whatsapp | email
      t.boolean :ativo, null: false, default: true
      t.timestamps
    end
    add_index :grupo_evento_assinaturas, %i[grupo_contato_id evento_notificacao_id],
              unique: true, name: 'index_assinatura_grupo_evento_unico'

    # Os dois eventos que o código JÁ dispara hoje, para nada parar de funcionar
    # no deploy. SQL cru de propósito: migration não deve depender de model.
    agora = 'NOW()'
    [
      ['Pagamento fechado',  'consolidacao_finalizada', 'consolidacao_finalizada',
       'Disparado quando uma consolidação é finalizada.'],
      ['Pagamento efetuado', 'pagamento_efetuado', 'pagamento_efetuado',
       'Disparado quando o pagamento de um motorista é marcado como pago.']
    ].each do |nome, chave, gatilho, descricao|
      execute(<<~SQL.squish)
        INSERT INTO eventos_notificacao
          (nome, chave, gatilho, descricao, ativo, sistema, notificar_envolvido, hora, created_at, updated_at)
        VALUES (#{quote(nome)}, #{quote(chave)}, #{quote(gatilho)}, #{quote(descricao)},
                true, true, true, 8, #{agora}, #{agora})
      SQL
    end
  end

  def down
    drop_table :grupo_evento_assinaturas
    drop_table :eventos_notificacao
  end
end
