import { app, BrowserWindow, ipcMain, Tray, Menu, nativeImage } from 'electron'
import * as path from 'path'
import { 
  getStore, 
  getSettings, 
  saveSettings, 
  getChannels, 
  saveChannels,
  getErrorLog,
  addErrorLog,
  clearErrorLog,
  getWindowBounds,
  saveWindowBounds,
  defaultSettings,
  isPortableMode
} from './store'
import { IpService } from './services/IpService'
import { PingService } from './services/PingService'
import { StreamChecker } from './services/StreamChecker'
import { NotificationService } from './services/NotificationService'
import { PanelService } from './services/PanelService'
import { M3u8Parser } from './services/M3u8Parser'
import { IPC_CHANNELS } from '../shared/types'
import type { AppSettings, Channel, ErrorLogEntry, HeartbeatStats } from '../shared/types'

// App quitting flag
let isAppQuitting = false

// Services
let ipService: IpService
let pingService: PingService
let streamChecker: StreamChecker
let notificationService: NotificationService
let panelService: PanelService
let m3u8Parser: M3u8Parser

// Heartbeat timer
let heartbeatInterval: NodeJS.Timeout | null = null
let checksLastMinute = 0

// Window and tray
let mainWindow: BrowserWindow | null = null
let tray: Tray | null = null

function createWindow() {
  const bounds = getWindowBounds()
  
  mainWindow = new BrowserWindow({
    width: bounds.width,
    height: bounds.height,
    x: bounds.x,
    y: bounds.y,
    minWidth: 1200,
    minHeight: 700,
    frame: false,
    backgroundColor: '#0f0f12',
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false,
    },
    icon: path.join(__dirname, '../../../assets/icon.png'),
  })

  // Save window bounds on resize/move
  mainWindow.on('resize', () => {
    if (mainWindow && !mainWindow.isMaximized()) {
      const bounds = mainWindow.getBounds()
      saveWindowBounds(bounds)
    }
  })

  mainWindow.on('move', () => {
    if (mainWindow && !mainWindow.isMaximized()) {
      const bounds = mainWindow.getBounds()
      saveWindowBounds(bounds)
    }
  })

  // Load the app
  if (process.env.NODE_ENV === 'development') {
    mainWindow.loadURL('http://localhost:5173')
    mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadFile(path.join(__dirname, '../../renderer/index.html'))
  }

  mainWindow.on('close', (event) => {
    const settings = getSettings()
    if (settings.general.minimizeToTray && !isAppQuitting) {
      event.preventDefault()
      mainWindow?.hide()
    }
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

function createTray() {
  // Create a simple tray icon
  const iconPath = path.join(__dirname, '../../../assets/tray-icon.png')
  let icon: Electron.NativeImage
  
  try {
    icon = nativeImage.createFromPath(iconPath)
    if (icon.isEmpty()) {
      icon = nativeImage.createEmpty()
    }
  } catch {
    icon = nativeImage.createEmpty()
  }
  
  tray = new Tray(icon)
  
  const contextMenu = Menu.buildFromTemplate([
    {
      label: 'Göster',
      click: () => {
        mainWindow?.show()
        mainWindow?.focus()
      },
    },
    {
      label: 'İzlemeyi Başlat',
      click: () => {
        streamChecker?.start()
      },
    },
    {
      label: 'İzlemeyi Durdur',
      click: () => {
        streamChecker?.stop()
      },
    },
    { type: 'separator' },
    {
      label: isPortableMode() ? 'Portable Mod ✓' : 'Normal Mod',
      enabled: false,
    },
    { type: 'separator' },
    {
      label: 'Çıkış',
      click: () => {
        isAppQuitting = true
        app.quit()
      },
    },
  ])

  tray.setToolTip('IP Monitor')
  tray.setContextMenu(contextMenu)
  
  tray.on('double-click', () => {
    mainWindow?.show()
    mainWindow?.focus()
  })
}

function initializeServices() {
  const settings = getSettings()
  
  ipService = new IpService()
  pingService = new PingService(settings.monitoring.timeout)
  m3u8Parser = new M3u8Parser()
  notificationService = new NotificationService(settings.notifications)
  panelService = new PanelService(settings.panel)
  
  streamChecker = new StreamChecker(
    settings.monitoring,
    (result) => {
      // Increment checks counter for heartbeat stats
      incrementChecksCounter()
      
      // Send result to renderer
      mainWindow?.webContents.send(IPC_CHANNELS.MONITORING_UPDATE, result)
      
      // Auto notify on error
      if (settings.notifications.autoNotify && result.status === 'error') {
        const channels = getChannels()
        const channel = channels.find(c => c.id === result.channelId)
        if (channel) {
          // Add to error log
          const errorEntry: ErrorLogEntry = {
            id: Date.now().toString(),
            timestamp: Date.now(),
            channelName: channel.name,
            channelId: channel.id,
            errorType: result.errorType || 'UNKNOWN',
            errorMessage: result.error || 'Bilinmeyen hata',
            httpStatus: result.httpStatus,
            notified: true,
          }
          addErrorLog(errorEntry)
          
          // Send notification
          notificationService.sendNotification(
            `🔴 ${channel.name} - Yayın Hatası`,
            result.error || 'Bilinmeyen hata'
          )
        }
      }
    }
  )
  
  console.log('[App] Services initialized')
  console.log('[App] Portable mode:', isPortableMode())
}

/**
 * Start heartbeat timer - sends heartbeat every 60 seconds
 * API v1.1: New heartbeat endpoint for monitor liveness
 */
function startHeartbeat(): void {
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval)
  }

  const settings = getSettings()
  if (!settings.panel.enabled) {
    console.log('[Heartbeat] Panel not enabled, skipping heartbeat')
    return
  }

  // Send heartbeat every 60 seconds
  heartbeatInterval = setInterval(async () => {
    if (!panelService.isEnabled()) return

    const channels = getChannels()
    const monitoredChannels = channels.filter(c => c.isMonitored)

    const stats: HeartbeatStats = {
      active_checks: monitoredChannels.length,
      checks_last_minute: checksLastMinute,
      cpu_usage_percent: process.cpuUsage().user / 1000000, // Convert to percent
      memory_usage_mb: Math.round(process.memoryUsage().heapUsed / 1024 / 1024)
    }

    const result = await panelService.sendHeartbeat(stats)
    if (result.success) {
      console.log('[Heartbeat] Sent successfully')
    } else {
      console.warn('[Heartbeat] Failed:', result.message)
    }

    // Reset checks counter
    checksLastMinute = 0
  }, 60000) // 60 seconds

  console.log('[Heartbeat] Timer started (60s interval)')
}

/**
 * Stop heartbeat timer
 */
function stopHeartbeat(): void {
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval)
    heartbeatInterval = null
    console.log('[Heartbeat] Timer stopped')
  }
}

/**
 * Increment checks counter for heartbeat stats
 */
function incrementChecksCounter(): void {
  checksLastMinute++
}

function setupIpcHandlers() {
  // Window controls
  ipcMain.on('window:minimize', () => mainWindow?.minimize())
  ipcMain.on('window:maximize', () => {
    if (mainWindow?.isMaximized()) {
      mainWindow.unmaximize()
    } else {
      mainWindow?.maximize()
    }
  })
  ipcMain.on('window:close', () => {
    // Çarpı butonuna basınca uygulamayı tamamen kapat
    isAppQuitting = true
    app.quit()
  })

  // IP Service
  ipcMain.handle(IPC_CHANNELS.GET_IP_INFO, async () => {
    return await ipService.getIpInfo()
  })

  // Channel Management
  ipcMain.handle(IPC_CHANNELS.PARSE_M3U8, async (_, url: string) => {
    const newChannels = await m3u8Parser.parse(url)
    const existingChannels = getChannels()
    saveChannels([...existingChannels, ...newChannels])
    return newChannels
  })

  ipcMain.handle(IPC_CHANNELS.GET_CHANNELS, async () => {
    return getChannels()
  })

  ipcMain.handle(IPC_CHANNELS.UPDATE_CHANNEL, async (_, channel: Channel) => {
    const channels = getChannels()
    const index = channels.findIndex(c => c.id === channel.id)
    if (index !== -1) {
      channels[index] = channel
      saveChannels(channels)
    }
  })

  ipcMain.handle(IPC_CHANNELS.SET_MONITORED, async (_, channelId: string, monitored: boolean) => {
    const channels = getChannels()
    const channel = channels.find(c => c.id === channelId)
    if (channel) {
      channel.isMonitored = monitored
      saveChannels(channels)
    }
  })

  // Monitoring
  ipcMain.handle(IPC_CHANNELS.START_MONITORING, async () => {
    const channels = getChannels()
    const monitoredChannels = channels.filter(c => c.isMonitored)
    streamChecker.setChannels(monitoredChannels)
    streamChecker.start()
  })

  ipcMain.handle(IPC_CHANNELS.STOP_MONITORING, async () => {
    streamChecker.stop()
  })

  ipcMain.handle(IPC_CHANNELS.GET_MONITORING_STATUS, async () => {
    return { isRunning: streamChecker.isRunning() }
  })

  // Ping
  ipcMain.handle(IPC_CHANNELS.PING_HOST, async (_, host: string) => {
    return await pingService.ping(host)
  })

  // Notifications
  ipcMain.handle(IPC_CHANNELS.SEND_NOTIFICATION, async (_, title: string, body: string, type?: string) => {
    await notificationService.sendNotification(title, body, type as 'windows' | 'telegram' | 'email')
  })

  ipcMain.handle(IPC_CHANNELS.TEST_NOTIFICATION, async (_, type: string) => {
    return await notificationService.testNotification(type as 'windows' | 'telegram' | 'email')
  })

  // Panel API
  ipcMain.handle(IPC_CHANNELS.PANEL_REGISTER, async (_, config) => {
    panelService.updateConfig(config)
    return await panelService.register()
  })

  ipcMain.handle(IPC_CHANNELS.PANEL_GET_IPS, async () => {
    return await panelService.getIpPool()
  })

  ipcMain.handle(IPC_CHANNELS.PANEL_SEND_VOTE, async (_, vote) => {
    return await panelService.sendBurnVote(vote)
  })

  // Panel Heartbeat - API v1.1
  ipcMain.handle(IPC_CHANNELS.PANEL_HEARTBEAT, async (_, stats: HeartbeatStats) => {
    return await panelService.sendHeartbeat(stats)
  })

  // Settings
  ipcMain.handle(IPC_CHANNELS.GET_SETTINGS, async () => {
    return getSettings()
  })

  ipcMain.handle(IPC_CHANNELS.SAVE_SETTINGS, async (_, settings: AppSettings) => {
    saveSettings(settings)
    // Update services with new settings
    notificationService.updateSettings(settings.notifications)
    panelService.updateConfig(settings.panel)
    streamChecker.updateConfig(settings.monitoring)
  })

  // Error Log
  ipcMain.handle('errorlog:get', async () => {
    return getErrorLog()
  })

  ipcMain.handle('errorlog:clear', async () => {
    clearErrorLog()
  })

  // App Info
  ipcMain.handle('app:info', async () => {
    return {
      version: app.getVersion(),
      isPortable: isPortableMode(),
      dataPath: getStore().path,
    }
  })
}

// App lifecycle
app.whenReady().then(() => {
  // Initialize store first
  getStore()
  
  initializeServices()
  createWindow()
  createTray()
  setupIpcHandlers()
  
  // Start heartbeat timer - API v1.1
  startHeartbeat()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('before-quit', () => {
  isAppQuitting = true
  stopHeartbeat()
  streamChecker?.stop()
})
