/**
 * Serviço centralizado de envio de e-mails
 * Sistema de Chamados Raven
 */

import { sendSmtpMail } from "../email-smtp"
import { renderTemplate, type TemplateData, type TemplateName } from "./email-templates"

// ============================================
// Tipos
// ============================================

export type NotificationType =
  // Ciclo de vida do ticket
  | "ticket_created"
  | "ticket_assigned"
  | "ticket_resolved"
  | "ticket_reopened"
  | "ticket_status_changed"
  | "ticket_priority_changed"
  // Comunicação
  | "comment_public"
  | "comment_response"
  | "comment_mention"
  // SLA
  | "sla_at_risk"
  | "sla_breached"
  | "sla_daily_digest"
  // Autenticação
  | "security_password_reset"
  | "security_email_verify"
  | "security_email_change"
  | "security_new_login"
  | "security_invite"

export interface NotificationConfig {
  label: string
  defaultEnabled: boolean
  staffOnly?: boolean
  required?: boolean
  collaboratorCanDisable?: boolean
}

export const NOTIFICATION_TYPES: Record<NotificationType, NotificationConfig> = {
  // Ciclo de vida do ticket
  ticket_created: {
    label: "Abertura de chamado",
    defaultEnabled: true,
    required: true,
  },
  ticket_assigned: {
    label: "Atribuição de chamado",
    defaultEnabled: true,
    collaboratorCanDisable: false,
  },
  ticket_resolved: {
    label: "Resolução de chamado",
    defaultEnabled: true,
    required: true,
  },
  ticket_reopened: {
    label: "Reabertura de chamado",
    defaultEnabled: true,
    collaboratorCanDisable: true,
  },
  ticket_status_changed: {
    label: "Mudança de status",
    defaultEnabled: false,
    collaboratorCanDisable: true,
  },
  ticket_priority_changed: {
    label: "Mudança de prioridade",
    defaultEnabled: true,
    collaboratorCanDisable: true,
  },
  // Comunicação
  comment_public: {
    label: "Comentários públicos",
    defaultEnabled: true,
    collaboratorCanDisable: true,
  },
  comment_response: {
    label: "Resposta do solicitante",
    defaultEnabled: true,
    staffOnly: true,
  },
  comment_mention: {
    label: "Menções em comentários",
    defaultEnabled: true,
    staffOnly: true,
  },
  // SLA
  sla_at_risk: {
    label: "SLA em risco",
    defaultEnabled: true,
    staffOnly: true,
  },
  sla_breached: {
    label: "SLA violado",
    defaultEnabled: true,
    staffOnly: true,
  },
  sla_daily_digest: {
    label: "Resumo diário de SLA",
    defaultEnabled: false,
    staffOnly: true,
  },
  // Autenticação
  security_password_reset: {
    label: "Redefinição de senha",
    defaultEnabled: true,
    required: true,
  },
  security_email_verify: {
    label: "Verificação de e-mail",
    defaultEnabled: true,
    required: true,
  },
  security_email_change: {
    label: "Alteração de e-mail",
    defaultEnabled: true,
    required: true,
  },
  security_new_login: {
    label: "Novo login detectado",
    defaultEnabled: true,
    collaboratorCanDisable: false,
  },
  security_invite: {
    label: "Convite de usuário",
    defaultEnabled: true,
    required: true,
  },
}

export interface EmailRecipient {
  email: string
  name?: string
  userId?: string
  role?: "ADMIN" | "MANAGER" | "AGENT" | "COLLABORATOR"
}

export interface SendEmailOptions {
  to: EmailRecipient | EmailRecipient[]
  subject: string
  template: TemplateName
  data: TemplateData
  notificationType?: NotificationType
  tenantId?: string
  skipPreferenceCheck?: boolean
}

export interface SendEmailResult {
  success: boolean
  skipped?: boolean
  reason?: string
  recipientCount?: number
}

// ============================================
// Configuração SMTP
// ============================================

function getSmtpConfig() {
  const host = process.env.SMTP_HOST
  const port = process.env.SMTP_PORT
  const username = process.env.SMTP_USER
  const password = process.env.SMTP_PASS
  const fromEmail = process.env.SMTP_FROM_EMAIL
  const fromName = process.env.SMTP_FROM_NAME ?? "Sistema de Chamados"

  if (!host || !port || !username || !password || !fromEmail) {
    return null
  }

  return {
    host,
    port: parseInt(port, 10),
    username,
    password,
    from: `"${fromName}" <${fromEmail}>`,
    tls: process.env.SMTP_SECURE === "true",
    rejectUnauthorized: false,
    timeoutMs: 15000,
  }
}

// ============================================
// Serviço de E-mail
// ============================================

/**
 * Envia um e-mail usando o sistema de templates
 */
export async function sendEmail(options: SendEmailOptions): Promise<SendEmailResult> {
  const config = getSmtpConfig()

  if (!config) {
    console.warn("[EmailService] SMTP não configurado, e-mail ignorado")
    return { success: false, skipped: true, reason: "smtp_not_configured" }
  }

  const recipients = Array.isArray(options.to) ? options.to : [options.to]

  if (recipients.length === 0) {
    return { success: false, skipped: true, reason: "no_recipients" }
  }

  // Renderiza o template
  const html = renderTemplate(options.template, options.data)

  // Extrai apenas os e-mails
  const emailAddresses = recipients.map((r) => r.email)

  try {
    await sendSmtpMail(config, emailAddresses, options.subject, html)

    console.log(`[EmailService] E-mail enviado para ${emailAddresses.length} destinatário(s)`)

    return {
      success: true,
      recipientCount: emailAddresses.length,
    }
  } catch (error) {
    console.error("[EmailService] Erro ao enviar e-mail:", error)
    return {
      success: false,
      reason: error instanceof Error ? error.message : "unknown_error",
    }
  }
}

/**
 * Verifica se um tipo de notificação é obrigatório
 */
export function isRequiredNotification(type: NotificationType): boolean {
  return NOTIFICATION_TYPES[type]?.required === true
}

/**
 * Verifica se um tipo de notificação é apenas para staff
 */
export function isStaffOnlyNotification(type: NotificationType): boolean {
  return NOTIFICATION_TYPES[type]?.staffOnly === true
}

/**
 * Verifica se um colaborador pode desativar um tipo de notificação
 */
export function canCollaboratorDisable(type: NotificationType): boolean {
  return NOTIFICATION_TYPES[type]?.collaboratorCanDisable === true
}

/**
 * Retorna o label de um tipo de notificação
 */
export function getNotificationLabel(type: NotificationType): string {
  return NOTIFICATION_TYPES[type]?.label ?? type
}

/**
 * Retorna todos os tipos de notificação disponíveis para um role
 */
export function getAvailableNotificationTypes(role: "ADMIN" | "MANAGER" | "AGENT" | "COLLABORATOR"): NotificationType[] {
  const isStaff = ["ADMIN", "MANAGER", "AGENT"].includes(role)

  return (Object.entries(NOTIFICATION_TYPES) as [NotificationType, NotificationConfig][])
    .filter(([, config]) => {
      if (config.staffOnly && !isStaff) return false
      return true
    })
    .map(([type]) => type)
}

/**
 * Retorna os tipos de notificação que um colaborador pode desativar
 */
export function getCollaboratorDisableableTypes(): NotificationType[] {
  return (Object.entries(NOTIFICATION_TYPES) as [NotificationType, NotificationConfig][])
    .filter(([, config]) => config.collaboratorCanDisable === true)
    .map(([type]) => type)
}

// ============================================
// E-mail de Teste
// ============================================

const TEST_EMAIL_RECIPIENT = process.env.TEST_EMAIL_RECIPIENT ?? "monkeyesdras@gmail.com"

/**
 * Envia um e-mail de teste
 */
export async function sendTestEmail(to?: string): Promise<SendEmailResult> {
  return sendEmail({
    to: { email: to ?? TEST_EMAIL_RECIPIENT },
    subject: "Teste - Sistema de Chamados Raven",
    template: "test",
    data: {
      title: "E-mail de Teste",
      message: "Este é um e-mail de teste do Sistema de Chamados Raven.",
      timestamp: new Date().toLocaleString("pt-BR", { timeZone: "America/Sao_Paulo" }),
    },
    skipPreferenceCheck: true,
  })
}
