package invalid.lena.rsend

import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.os.storage.StorageManager
import android.widget.Button
import android.widget.TextView
import androidx.activity.addCallback
import androidx.appcompat.app.AppCompatActivity
import java.io.File

// FolderPickerActivity browses the real filesystem and returns one directory's
// absolute path in the "path" result extra. The app holds all-files access, so
// rsync works on real paths; this picker stays on real paths too (no SAF, no
// content URIs). Browsing is rooted at primary shared storage and cannot go
// above it; SD cards and other volumes are still reachable by typing the path.
class FolderPickerActivity : AppCompatActivity() {

    private lateinit var pathView: TextView
    private lateinit var list: android.widget.LinearLayout
    private lateinit var root: File
    private lateinit var current: File

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_picker)
        setSupportActionBar(findViewById(R.id.toolbar))
        title = "Pick folder"
        fitSystemBars()
        pathView = findViewById(R.id.currentPath)
        list = findViewById(R.id.list)

        root = getSystemService(StorageManager::class.java).primaryStorageVolume.directory
            ?: Environment.getExternalStorageDirectory()

        // Start where the field already points, if that is a directory under the
        // root; otherwise at the root itself.
        val start = intent.getStringExtra("start")?.let { File(it) }
        current = if (start != null && start.isDirectory && underRoot(start)) start else root

        findViewById<Button>(R.id.use).setOnClickListener {
            setResult(RESULT_OK, Intent().putExtra("path", current.absolutePath))
            finish()
        }
        findViewById<Button>(R.id.cancel).setOnClickListener { finish() }

        // Hardware back walks up the tree until the root, then leaves the screen.
        onBackPressedDispatcher.addCallback(this) {
            if (current.absolutePath != root.absolutePath) {
                current = current.parentFile ?: root
                render()
            } else {
                isEnabled = false
                onBackPressedDispatcher.onBackPressed()
            }
        }

        render()
    }

    private fun render() {
        pathView.text = current.absolutePath
        list.removeAllViews()

        if (current.absolutePath != root.absolutePath && current.parentFile != null) {
            addRow("..", current.parentFile!!)
        }

        val dirs = current.listFiles { f -> f.isDirectory }
            ?.sortedBy { it.name.lowercase() } ?: emptyList()
        for (d in dirs) addRow(d.name, d)

        if (dirs.isEmpty()) {
            list.addView(TextView(this).apply {
                text = "No subfolders here. Tap \"Use this folder\" to pick it."
                setTextAppearance(R.style.TextAppearance_Rsend_Caption)
            })
        }
    }

    // Anchored at a path separator so /storage/emulated/0-evil does not pass
    // for a root of /storage/emulated/0.
    private fun underRoot(f: File): Boolean =
        f.absolutePath == root.absolutePath || f.absolutePath.startsWith(root.absolutePath + "/")

    private fun addRow(label: String, dir: File) {
        val row = layoutInflater.inflate(R.layout.item_dir, list, false)
        row.findViewById<TextView>(R.id.dirName).text = label
        row.setOnClickListener { current = dir; render() }
        list.addView(row)
    }
}
