package de.hackernet.wireguardtv.ui

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import androidx.leanback.app.GuidedStepSupportFragment
import androidx.leanback.widget.GuidanceStylist
import androidx.leanback.widget.GuidedAction
import androidx.lifecycle.lifecycleScope
import de.hackernet.wireguardtv.data.TunnelRepository
import kotlinx.coroutines.launch
import java.io.File

/**
 * Activity zum Importieren von .conf Dateien vom lokalen Speicher
 * Dateien können per ADB in /sdcard/Download oder /sdcard/WireGuard übertragen werden
 */
class FileImportActivity : FragmentActivity() {

    companion object {
        private const val REQUEST_STORAGE_PERMISSION = 100
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Immer neu starten - savedInstanceState ignorieren, da wir immer frische Daten wollen
        if (hasStoragePermission()) {
            showFileBrowser()
        } else {
            requestStoragePermission()
        }
    }

    private fun hasStoragePermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11+ kann auf Download-Ordner ohne spezielle Permission zugreifen
            true
        } else {
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_EXTERNAL_STORAGE
            ) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun requestStoragePermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                REQUEST_STORAGE_PERMISSION
            )
        } else {
            showFileBrowser()
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_STORAGE_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                showFileBrowser()
            } else {
                Toast.makeText(this, "Speicher-Berechtigung erforderlich", Toast.LENGTH_LONG).show()
                finish()
            }
        }
    }

    private fun showFileBrowser() {
        // Dateien VORHER scannen, bevor Fragment erstellt wird
        FileBrowserFragment.scanForConfFiles()

        // Alte Fragments entfernen falls vorhanden
        supportFragmentManager.fragments.forEach { fragment ->
            supportFragmentManager.beginTransaction().remove(fragment).commitNow()
        }

        GuidedStepSupportFragment.addAsRoot(
            this,
            FileBrowserFragment(),
            android.R.id.content
        )
    }
}

/**
 * Fragment zum Durchsuchen und Auswählen von .conf Dateien
 */
class FileBrowserFragment : GuidedStepSupportFragment() {

    companion object {
        private const val ACTION_REFRESH = 1000L
        private const val ACTION_CANCEL = 1001L

        // Statische Liste, damit sie zwischen Lifecycle-Callbacks erhalten bleibt
        private var scannedFiles: List<File> = emptyList()

        fun scanForConfFiles(): List<File> {
            val searchPaths = listOf(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                File(Environment.getExternalStorageDirectory(), "WireGuard"),
                File(Environment.getExternalStorageDirectory(), "wireguard"),
                File(Environment.getExternalStorageDirectory(), "Download"),
                Environment.getExternalStorageDirectory()
            )

            scannedFiles = searchPaths
                .filter { it.exists() && it.isDirectory }
                .flatMap { dir ->
                    dir.listFiles { file ->
                        file.isFile && file.name.endsWith(".conf", ignoreCase = true)
                    }?.toList() ?: emptyList()
                }
                .distinctBy { it.absolutePath }
                .sortedBy { it.name.lowercase() }

            return scannedFiles
        }
    }

    private val confFiles: List<File>
        get() = scannedFiles

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Immer scannen beim Erstellen
        scanForConfFiles()
    }

    override fun onCreateGuidance(savedInstanceState: Bundle?): GuidanceStylist.Guidance {
        val files = confFiles

        val subtitle = if (files.isEmpty()) {
            "Keine .conf Dateien gefunden.\n\n" +
            "Übertrage Dateien per ADB:\n" +
            "adb push meine-config.conf /sdcard/Download/"
        } else {
            "${files.size} Config-Datei(en) gefunden"
        }

        return GuidanceStylist.Guidance(
            "Config-Datei auswählen",
            subtitle,
            "WireGuard TV",
            null
        )
    }

    override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {
        val files = confFiles

        // Gefundene .conf Dateien anzeigen
        files.forEachIndexed { index, file ->
            val sizeKB = file.length() / 1024
            val sizeStr = if (sizeKB > 0) "${sizeKB}KB" else "${file.length()}B"
            val location = file.parentFile?.name ?: "?"

            actions.add(GuidedAction.Builder(requireContext())
                .id(index.toLong())
                .title(file.nameWithoutExtension)
                .description("$location/${file.name} ($sizeStr)")
                .build())
        }

        // Aktionen
        actions.add(GuidedAction.Builder(requireContext())
            .id(ACTION_REFRESH)
            .title("Aktualisieren")
            .description("Erneut nach Dateien suchen")
            .build())

        actions.add(GuidedAction.Builder(requireContext())
            .id(ACTION_CANCEL)
            .title("Abbrechen")
            .build())
    }

    override fun onGuidedActionClicked(action: GuidedAction) {
        val files = confFiles

        when (action.id) {
            ACTION_REFRESH -> {
                scanForConfFiles()
                // Fragment neu laden
                parentFragmentManager.beginTransaction()
                    .replace(android.R.id.content, FileBrowserFragment())
                    .commit()
            }
            ACTION_CANCEL -> {
                activity?.finish()
            }
            else -> {
                // Config-Datei ausgewählt (IDs 0 bis confFiles.size-1)
                val index = action.id.toInt()
                if (index >= 0 && index < files.size) {
                    importConfigFile(files[index])
                }
            }
        }
    }

    private fun importConfigFile(file: File) {
        lifecycleScope.launch {
            try {
                val content = file.readText()
                val name = file.nameWithoutExtension

                // Validierung: Muss [Interface] und [Peer] enthalten
                if (!content.contains("[Interface]") || !content.contains("[Peer]")) {
                    Toast.makeText(
                        context,
                        "Ungültige WireGuard Config: [Interface] und [Peer] Sektionen erforderlich",
                        Toast.LENGTH_LONG
                    ).show()
                    return@launch
                }

                val repository = TunnelRepository.getInstance(requireContext())
                repository.importFromConf(content, name)

                Toast.makeText(
                    context,
                    "Tunnel '$name' importiert!",
                    Toast.LENGTH_LONG
                ).show()

                activity?.finish()
            } catch (e: Exception) {
                Toast.makeText(
                    context,
                    "Fehler beim Import: ${e.message}",
                    Toast.LENGTH_LONG
                ).show()
            }
        }
    }
}
