/*
 * Hermes Node Android
 * Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package net.nexlab.hermesnodeandroid

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.widget.Toast

class HermesNodeService : Service() {
    private var agent: NodeAgent? = null

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
    }

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_STOP -> {
                stopAgent()
                stopSelf()
                return START_NOT_STICKY
            }
            ACTION_VIDEO_CAPTURE_COMPLETE -> {
                updateForegroundTextFromVideoResult()
                return START_STICKY
            }
            else -> startAgent()
        }
        return START_STICKY
    }

    override fun onDestroy() {
        stopAgent()
        super.onDestroy()
    }

    private fun startAgent() {
        val config = ConfigStore.load(this)
        val validation = config.validationError()
        if (validation != null) {
            StatusStore.set(this, "config_error", validation)
            Toast.makeText(this, validation, Toast.LENGTH_LONG).show()
            stopSelf()
            return
        }
        startForeground(NOTIFICATION_ID, notification("Connecting ${config.nodeName}"))
        agent?.stop()
        agent = NodeAgent(applicationContext, config).also { it.start() }
    }

    private fun stopAgent() {
        agent?.stop()
        agent = null
    }

    private fun updateForegroundTextFromVideoResult() {
        val result = VideoCaptureSessionStore.loadResult(this) ?: return
        val text = if (result.optBoolean("success", false)) {
            val bytes = result.optLong("bytes", 0L)
            "Video capture complete (${bytes} bytes)"
        } else {
            "Video capture failed: ${result.optString("error", "unknown error")}".take(120)
        }
        val manager = getSystemService(NotificationManager::class.java)
        manager.notify(NOTIFICATION_ID, notification(text))
    }

    private fun notification(text: String): Notification {
        val openIntent = Intent(this, MainActivity::class.java)
        val pending = PendingIntent.getActivity(
            this,
            0,
            openIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )
        val stopIntent = Intent(this, HermesNodeService::class.java).setAction(ACTION_STOP)
        val stopPending = PendingIntent.getService(
            this,
            1,
            stopIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )
        return Notification.Builder(this, CHANNEL_ID)
            .setContentTitle("Hermes Node Android")
            .setContentText(text)
            .setSmallIcon(android.R.drawable.stat_sys_upload_done)
            .setContentIntent(pending)
            .addAction(android.R.drawable.ic_menu_close_clear_cancel, "Stop", stopPending)
            .setOngoing(true)
            .build()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "Hermes Node",
                NotificationManager.IMPORTANCE_LOW,
            )
            getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
        }
    }

    companion object {
        const val ACTION_START = "net.nexlab.hermesnodeandroid.START"
        const val ACTION_STOP = "net.nexlab.hermesnodeandroid.STOP"
        const val ACTION_VIDEO_CAPTURE_COMPLETE = "net.nexlab.hermesnodeandroid.VIDEO_CAPTURE_COMPLETE"
        private const val CHANNEL_ID = "hermes_node_android"
        private const val NOTIFICATION_ID = 1001
    }
}
