import { Notification, app } from 'electron'
import axios from 'axios'
import * as nodemailer from 'nodemailer'
import type { NotificationSettings, NotificationType } from '../../shared/types'

export class NotificationService {
  private settings: NotificationSettings
  private emailTransporter: nodemailer.Transporter | null = null

  constructor(settings: NotificationSettings) {
    this.settings = settings
    this.initializeEmailTransporter()
  }

  updateSettings(settings: NotificationSettings): void {
    this.settings = settings
    this.initializeEmailTransporter()
  }

  private initializeEmailTransporter(): void {
    if (this.settings.email.enabled && this.settings.email.smtpHost) {
      this.emailTransporter = nodemailer.createTransport({
        host: this.settings.email.smtpHost,
        port: this.settings.email.smtpPort,
        secure: this.settings.email.smtpPort === 465,
        auth: {
          user: this.settings.email.smtpUser,
          pass: this.settings.email.smtpPass,
        },
      })
    }
  }

  /**
   * Send notification through all enabled channels
   */
  async sendNotification(title: string, body: string, specificType?: NotificationType): Promise<void> {
    if (!this.settings.enabled) return

    const promises: Promise<void>[] = []

    if (specificType) {
      // Send to specific channel
      switch (specificType) {
        case 'windows':
          if (this.settings.windows.enabled) {
            promises.push(this.sendWindowsNotification(title, body))
          }
          break
        case 'telegram':
          if (this.settings.telegram.enabled) {
            promises.push(this.sendTelegramNotification(title, body))
          }
          break
        case 'email':
          if (this.settings.email.enabled) {
            promises.push(this.sendEmailNotification(title, body))
          }
          break
      }
    } else {
      // Send to all enabled channels
      if (this.settings.windows.enabled) {
        promises.push(this.sendWindowsNotification(title, body))
      }
      if (this.settings.telegram.enabled) {
        promises.push(this.sendTelegramNotification(title, body))
      }
      if (this.settings.email.enabled) {
        promises.push(this.sendEmailNotification(title, body))
      }
    }

    await Promise.allSettled(promises)
  }

  /**
   * Send Windows toast notification
   */
  async sendWindowsNotification(title: string, body: string): Promise<void> {
    if (!Notification.isSupported()) {
      console.warn('Notifications not supported on this system')
      return
    }

    const notification = new Notification({
      title,
      body,
      icon: undefined, // Will use app icon
      silent: false,
    })

    notification.show()
  }

  /**
   * Send Telegram notification
   */
  async sendTelegramNotification(title: string, body: string): Promise<void> {
    const { botToken, chatId } = this.settings.telegram
    
    if (!botToken || !chatId) {
      throw new Error('Telegram bot token or chat ID not configured')
    }

    const message = `*${this.escapeMarkdown(title)}*\n\n${this.escapeMarkdown(body)}`
    
    const url = `https://api.telegram.org/bot${botToken}/sendMessage`
    
    await axios.post(url, {
      chat_id: chatId,
      text: message,
      parse_mode: 'Markdown',
      disable_web_page_preview: true,
    }, {
      timeout: 10000
    })
  }

  /**
   * Send email notification
   */
  async sendEmailNotification(title: string, body: string): Promise<void> {
    if (!this.emailTransporter) {
      throw new Error('Email transporter not configured')
    }

    const { fromEmail, toEmail } = this.settings.email

    if (!fromEmail || !toEmail) {
      throw new Error('Email addresses not configured')
    }

    await this.emailTransporter.sendMail({
      from: fromEmail,
      to: toEmail,
      subject: `[IP Monitor] ${title}`,
      text: body,
      html: `
        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
          <h2 style="color: #e06c75; border-bottom: 2px solid #e06c75; padding-bottom: 10px;">
            ${title}
          </h2>
          <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; margin-top: 15px;">
            <pre style="white-space: pre-wrap; font-family: 'Courier New', monospace;">${body}</pre>
          </div>
          <p style="color: #888; font-size: 12px; margin-top: 20px;">
            Sent by IP Monitor at ${new Date().toLocaleString('tr-TR')}
          </p>
        </div>
      `,
    })
  }

  /**
   * Test notification for a specific channel
   */
  async testNotification(type: NotificationType): Promise<{ success: boolean; error?: string }> {
    const title = 'Test Bildirimi'
    const body = `Bu bir test bildirimidir.\nZaman: ${new Date().toLocaleString('tr-TR')}`

    try {
      switch (type) {
        case 'windows':
          await this.sendWindowsNotification(title, body)
          break
        case 'telegram':
          await this.sendTelegramNotification(title, body)
          break
        case 'email':
          await this.sendEmailNotification(title, body)
          break
      }
      return { success: true }
    } catch (error) {
      return { success: false, error: (error as Error).message }
    }
  }

  /**
   * Escape special characters for Telegram Markdown
   */
  private escapeMarkdown(text: string): string {
    return text.replace(/[_*[\]()~`>#+=|{}.!-]/g, '\\$&')
  }

  /**
   * Format error for notification
   */
  static formatErrorNotification(
    channelName: string,
    errorType: string,
    errorMessage: string,
    httpStatus?: number
  ): { title: string; body: string } {
    let statusEmoji = '🔴'
    if (errorType === 'TIMEOUT') statusEmoji = '⏱️'
    if (errorType === 'CONNRESET') statusEmoji = '🔌'
    if (httpStatus === 404) statusEmoji = '❌'

    const title = `${statusEmoji} ${channelName} - Yayın Hatası`
    
    let body = `Hata Tipi: ${errorType}\n`
    if (httpStatus) body += `HTTP Status: ${httpStatus}\n`
    body += `Detay: ${errorMessage}\n`
    body += `Zaman: ${new Date().toLocaleString('tr-TR')}`

    return { title, body }
  }
}

