@file:Suppress("DEPRECATION") // Legacy code using LocalBroadcastManager, will be removed in v2.0.0

package dev.dettmer.simplenotes

import android.Manifest
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import dev.dettmer.simplenotes.utils.Logger
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.color.DynamicColors
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dev.dettmer.simplenotes.adapters.NotesAdapter
import dev.dettmer.simplenotes.models.Note
import dev.dettmer.simplenotes.storage.NotesStorage
import dev.dettmer.simplenotes.sync.SyncWorker
import dev.dettmer.simplenotes.utils.NotificationHelper
import dev.dettmer.simplenotes.utils.showToast
import dev.dettmer.simplenotes.utils.Constants
import android.widget.TextView
import android.widget.CheckBox
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import dev.dettmer.simplenotes.sync.WebDavSyncService
import dev.dettmer.simplenotes.sync.SyncStateManager
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import android.view.View
import android.widget.LinearLayout
import android.view.Gravity
import android.widget.PopupMenu
import dev.dettmer.simplenotes.models.NoteType

/**
 * Legacy MainActivity - DEPRECATED seit v1.5.0, wird entfernt in v2.0.0
 * Ersetzt durch ComposeMainActivity
 */
@Suppress("DEPRECATION") // Legacy code using LocalBroadcastManager, will be removed in v2.0.0
class MainActivity : AppCompatActivity() {
    
    private lateinit var recyclerViewNotes: RecyclerView
    private lateinit var emptyStateCard: MaterialCardView
    private lateinit var fabAddNote: FloatingActionButton
    private lateinit var toolbar: MaterialToolbar
    private lateinit var swipeRefreshLayout: SwipeRefreshLayout
    
    // 🔄 v1.3.1: Sync Status Banner
    private lateinit var syncStatusBanner: LinearLayout
    private lateinit var syncStatusText: TextView
    
    private lateinit var adapter: NotesAdapter
    private val storage by lazy { NotesStorage(this) }
    
    // Menu reference for sync button state
    private var optionsMenu: Menu? = null
    
    // Track pending deletions to prevent flicker when notes reload
    private val pendingDeletions = mutableSetOf<String>()
    
    private val prefs by lazy {
        getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE)
    }
    
    companion object {
        private const val TAG = "MainActivity"
        private const val REQUEST_NOTIFICATION_PERMISSION = 1001
        private const val REQUEST_SETTINGS = 1002
        private const val MIN_AUTO_SYNC_INTERVAL_MS = 60_000L // 1 Minute
        private const val PREF_LAST_AUTO_SYNC_TIME = "last_auto_sync_timestamp"
        private const val SYNC_COMPLETED_DELAY_MS = 1500L
        private const val ERROR_DISPLAY_DELAY_MS = 3000L
    }
    
    /**
     * BroadcastReceiver für Background-Sync Completion (Periodic Sync)
     */
    private val syncCompletedReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val success = intent?.getBooleanExtra("success", false) ?: false
            val count = intent?.getIntExtra("count", 0) ?: 0
            
            Logger.d(TAG, "📡 Sync completed broadcast received: success=$success, count=$count")
            
            // UI refresh
            if (success && count > 0) {
                loadNotes()
                Logger.d(TAG, "🔄 Notes reloaded after background sync")
            }
        }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // Install Splash Screen (Android 12+)
        installSplashScreen()
        
        super.onCreate(savedInstanceState)
        
        // Apply Dynamic Colors for Android 12+ (Material You)
        DynamicColors.applyToActivityIfAvailable(this)
        
        setContentView(R.layout.activity_main)
        
        // Logger initialisieren und File-Logging aktivieren wenn eingestellt
        Logger.init(this)
        if (prefs.getBoolean(Constants.KEY_FILE_LOGGING_ENABLED, false)) {
            Logger.setFileLoggingEnabled(true)
        }
        
        // Alte Sync-Notifications beim App-Start löschen
        NotificationHelper.clearSyncNotifications(this)
        
        // Permission für Notifications (Android 13+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            requestNotificationPermission()
        }
        
        // 🌍 v1.7.2: Debug Locale für Fehlersuche
        logLocaleInfo()
        
        findViews()
        setupToolbar()
        setupRecyclerView()
        setupFab()
        
        // v1.4.1: Migrate checklists for backwards compatibility
        migrateChecklistsForBackwardsCompat()
        
        loadNotes()
        
        // 🔄 v1.3.1: Observe sync state for UI updates
        setupSyncStateObserver()
    }
    
    /**
     * 🔄 v1.3.1: Beobachtet Sync-Status für UI-Feedback
     */
    private fun setupSyncStateObserver() {
        SyncStateManager.syncStatus.observe(this) { status ->
            when (status.state) {
                SyncStateManager.SyncState.SYNCING -> {
                    // Disable sync controls
                    setSyncControlsEnabled(false)
                    // 🔄 v1.3.1: Show sync status banner (ersetzt SwipeRefresh-Animation)
                    syncStatusText.text = getString(R.string.sync_status_syncing)
                    syncStatusBanner.visibility = View.VISIBLE
                }
                SyncStateManager.SyncState.COMPLETED -> {
                    // Re-enable sync controls
                    setSyncControlsEnabled(true)
                    swipeRefreshLayout.isRefreshing = false
                    // Show completed briefly, then hide
                    syncStatusText.text = status.message ?: getString(R.string.sync_status_completed)
                    lifecycleScope.launch {
                        kotlinx.coroutines.delay(SYNC_COMPLETED_DELAY_MS)
                        syncStatusBanner.visibility = View.GONE
                        SyncStateManager.reset()
                    }
                }
                SyncStateManager.SyncState.ERROR -> {
                    // Re-enable sync controls
                    setSyncControlsEnabled(true)
                    swipeRefreshLayout.isRefreshing = false
                    // Show error briefly, then hide
                    syncStatusText.text = status.message ?: getString(R.string.sync_status_error)
                    lifecycleScope.launch {
                        kotlinx.coroutines.delay(ERROR_DISPLAY_DELAY_MS)
                        syncStatusBanner.visibility = View.GONE
                        SyncStateManager.reset()
                    }
                }
                SyncStateManager.SyncState.IDLE -> {
                    setSyncControlsEnabled(true)
                    swipeRefreshLayout.isRefreshing = false
                    syncStatusBanner.visibility = View.GONE
                }
                // v1.5.0: Silent-Sync - Banner nicht anzeigen, aber Sync-Controls deaktivieren
                SyncStateManager.SyncState.SYNCING_SILENT -> {
                    setSyncControlsEnabled(false)
                    // Kein Banner anzeigen bei Silent-Sync (z.B. onResume Auto-Sync)
                }
            }
        }
    }
    
    /**
     * 🔄 v1.3.1: Aktiviert/deaktiviert Sync-Controls (Button + SwipeRefresh)
     */
    private fun setSyncControlsEnabled(enabled: Boolean) {
        // Menu Sync-Button
        optionsMenu?.findItem(R.id.action_sync)?.isEnabled = enabled
        // SwipeRefresh
        swipeRefreshLayout.isEnabled = enabled
    }
    
    override fun onResume() {
        super.onResume()
        
        Logger.d(TAG, "📱 MainActivity.onResume() - Registering receivers")
        
        // Register BroadcastReceiver für Background-Sync
        LocalBroadcastManager.getInstance(this).registerReceiver(
            syncCompletedReceiver,
            IntentFilter(SyncWorker.ACTION_SYNC_COMPLETED)
        )
        
        Logger.d(TAG, "📡 BroadcastReceiver registered (sync-completed)")
        
        // Reload notes (scroll to top wird in loadNotes() gemacht)
        loadNotes()
        
        // Trigger Auto-Sync beim App-Wechsel in Vordergrund (Toast)
        triggerAutoSync("onResume")
    }
    
    /**
     * Automatischer Sync (onResume)
     * - Nutzt WiFi-gebundenen Socket (VPN Fix!)
     * - Nur Success-Toast (kein "Auto-Sync..." Toast)
     * 
     * NOTE: WiFi-Connect Sync nutzt WorkManager (auch wenn App geschlossen!)
     * v1.5.0: Silent-Sync - kein Banner während des Syncs, Fehler werden trotzdem angezeigt
     */
    private fun triggerAutoSync(source: String = "unknown") {
        // Throttling: Max 1 Sync pro Minute
        if (!canTriggerAutoSync()) {
            return
        }
        
        // 🔄 v1.3.1: Check if sync already running
        // v1.5.0: silent=true - kein Banner bei Auto-Sync
        if (!SyncStateManager.tryStartSync("auto-$source", silent = true)) {
            Logger.d(TAG, "⏭️ Auto-sync ($source): Another sync already in progress")
            return
        }
        
        Logger.d(TAG, "🔄 Auto-sync triggered ($source)")
        
        // Update last sync timestamp
        prefs.edit().putLong(PREF_LAST_AUTO_SYNC_TIME, System.currentTimeMillis()).apply()
        
        lifecycleScope.launch {
            try {
                val syncService = WebDavSyncService(this@MainActivity)
                
                // 🔥 v1.1.2: Check if there are unsynced changes first (performance optimization)
                if (!syncService.hasUnsyncedChanges()) {
                    Logger.d(TAG, "⏭️ Auto-sync ($source): No unsynced changes - skipping")
                    SyncStateManager.reset()
                    return@launch
                }
                
                // ⭐ WICHTIG: Server-Erreichbarkeits-Check VOR Sync (wie in SyncWorker)
                val isReachable = withContext(Dispatchers.IO) {
                    syncService.isServerReachable()
                }
                
                if (!isReachable) {
                    Logger.d(TAG, "⏭️ Auto-sync ($source): Server not reachable - skipping silently")
                    SyncStateManager.reset()
                    return@launch
                }
                
                // Server ist erreichbar → Sync durchführen
                val result = withContext(Dispatchers.IO) {
                    syncService.syncNotes()
                }
                
                // Feedback abhängig von Source
                if (result.isSuccess && result.syncedCount > 0) {
                    Logger.d(TAG, "✅ Auto-sync successful ($source): ${result.syncedCount} notes")
                    SyncStateManager.markCompleted("${result.syncedCount} Notizen")
                    
                    // onResume: Nur Success-Toast
                    showToast("✅ Gesynct: ${result.syncedCount} Notizen")
                    loadNotes()
                    
                } else if (result.isSuccess) {
                    Logger.d(TAG, "ℹ️ Auto-sync ($source): No changes")
                    SyncStateManager.markCompleted()
                    
                } else {
                    Logger.e(TAG, "❌ Auto-sync failed ($source): ${result.errorMessage}")
                    SyncStateManager.markError(result.errorMessage)
                    // Kein Toast - App ist im Hintergrund
                }
                
            } catch (e: Exception) {
                Logger.e(TAG, "💥 Auto-sync exception ($source): ${e.message}")
                SyncStateManager.markError(e.message)
                // Kein Toast - App ist im Hintergrund
            }
        }
    }
    
    /**
     * Prüft ob Auto-Sync getriggert werden darf (Throttling)
     */
    private fun canTriggerAutoSync(): Boolean {
        val lastSyncTime = prefs.getLong(PREF_LAST_AUTO_SYNC_TIME, 0)
        val now = System.currentTimeMillis()
        val timeSinceLastSync = now - lastSyncTime
        
        if (timeSinceLastSync < MIN_AUTO_SYNC_INTERVAL_MS) {
            val remainingSeconds = (MIN_AUTO_SYNC_INTERVAL_MS - timeSinceLastSync) / 1000
            Logger.d(TAG, "⏳ Auto-sync throttled - wait ${remainingSeconds}s")
            return false
        }
        
        return true
    }
    
    override fun onPause() {
        super.onPause()
        
        // Unregister BroadcastReceiver
        LocalBroadcastManager.getInstance(this).unregisterReceiver(syncCompletedReceiver)
        Logger.d(TAG, "📡 BroadcastReceiver unregistered")
    }
    
    private fun findViews() {
        recyclerViewNotes = findViewById(R.id.recyclerViewNotes)
        emptyStateCard = findViewById(R.id.emptyStateCard)
        fabAddNote = findViewById(R.id.fabAddNote)
        toolbar = findViewById(R.id.toolbar)
        swipeRefreshLayout = findViewById<SwipeRefreshLayout>(R.id.swipeRefreshLayout)
        
        // 🔄 v1.3.1: Sync Status Banner
        syncStatusBanner = findViewById(R.id.syncStatusBanner)
        syncStatusText = findViewById(R.id.syncStatusText)
    }
    
    private fun setupToolbar() {
        setSupportActionBar(toolbar)
    }
    
    private fun setupRecyclerView() {
        adapter = NotesAdapter { note ->
            openNoteEditor(note.id)
        }
        recyclerViewNotes.adapter = adapter
        recyclerViewNotes.layoutManager = LinearLayoutManager(this)
        
        // 🔥 v1.1.2: Setup Pull-to-Refresh
        setupPullToRefresh()
        
        // Setup Swipe-to-Delete
        setupSwipeToDelete()
    }
    
    /**
     * Setup Pull-to-Refresh für manuellen Sync (v1.1.2)
     */
    private fun setupPullToRefresh() {
        swipeRefreshLayout.setOnRefreshListener {
            Logger.d(TAG, "🔄 Pull-to-Refresh triggered - starting manual sync")
            
            // 🔄 v1.3.1: Check if sync already running (Banner zeigt Status)
            if (!SyncStateManager.tryStartSync("pullToRefresh")) {
                swipeRefreshLayout.isRefreshing = false
                return@setOnRefreshListener
            }
            
            lifecycleScope.launch {
                try {
                    val prefs = getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE)
                    val serverUrl = prefs.getString(Constants.KEY_SERVER_URL, null)
                    
                    if (serverUrl.isNullOrEmpty()) {
                        showToast("⚠️ Server noch nicht konfiguriert")
                        SyncStateManager.reset()
                        return@launch
                    }
                    
                    val syncService = WebDavSyncService(this@MainActivity)
                    
                    // 🔥 v1.1.2: Check if there are unsynced changes first (performance optimization)
                    if (!syncService.hasUnsyncedChanges()) {
                        Logger.d(TAG, "⏭️ No unsynced changes, skipping server reachability check")
                        SyncStateManager.markCompleted(getString(R.string.snackbar_already_synced))
                        return@launch
                    }
                    
                    // Check if server is reachable
                    if (!syncService.isServerReachable()) {
                        SyncStateManager.markError(getString(R.string.snackbar_server_unreachable))
                        return@launch
                    }
                    
                    // Perform sync
                    val result = syncService.syncNotes()
                    
                    if (result.isSuccess) {
                        SyncStateManager.markCompleted(getString(R.string.snackbar_synced_count, result.syncedCount))
                        loadNotes()
                    } else {
                        SyncStateManager.markError(result.errorMessage)
                    }
                } catch (e: Exception) {
                    Logger.e(TAG, "Pull-to-Refresh sync failed", e)
                    SyncStateManager.markError(e.message)
                }
            }
        }
        
        // Set Material 3 color scheme
        swipeRefreshLayout.setColorSchemeResources(
            com.google.android.material.R.color.material_dynamic_primary50
        )
    }
    
    private fun setupSwipeToDelete() {
        val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
            0, // No drag
            ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT // Swipe left or right
        ) {
            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean = false
            
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                val position = viewHolder.bindingAdapterPosition
                val swipedNote = adapter.currentList[position]
                
                // Store original list BEFORE removing note
                val originalList = adapter.currentList.toList()
                
                // Remove from list for visual feedback (NOT from storage yet!)
                val listWithoutNote = originalList.toMutableList().apply {
                    removeAt(position)
                }
                adapter.submitList(listWithoutNote)
                
                // Show dialog with ability to restore
                showServerDeletionDialog(swipedNote, originalList)
            }
            
            override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float {
                // Require 80% swipe to trigger
                return 0.8f
            }
        })
        
        itemTouchHelper.attachToRecyclerView(recyclerViewNotes)
    }
    
    private fun showServerDeletionDialog(note: Note, originalList: List<Note>) {
        val alwaysDeleteFromServer = prefs.getBoolean(Constants.KEY_ALWAYS_DELETE_FROM_SERVER, false)
        
        if (alwaysDeleteFromServer) {
            // Auto-delete from server without asking
            deleteNoteLocally(note, deleteFromServer = true)
            return
        }
        
        val dialogView = layoutInflater.inflate(R.layout.dialog_server_deletion, null)
        val checkboxAlways = dialogView.findViewById<CheckBox>(R.id.checkboxAlwaysDeleteFromServer)
        
        MaterialAlertDialogBuilder(this)
            .setTitle(getString(R.string.legacy_delete_dialog_title))
            .setMessage(getString(R.string.legacy_delete_dialog_message, note.title))
            .setView(dialogView)
            .setNeutralButton(getString(R.string.cancel)) { _, _ ->
                // RESTORE: Re-submit original list (note is NOT deleted from storage)
                adapter.submitList(originalList)
            }
            .setOnCancelListener {
                // User pressed back - also restore
                adapter.submitList(originalList)
            }
            .setPositiveButton("Nur lokal") { _, _ ->
                if (checkboxAlways.isChecked) {
                    prefs.edit().putBoolean(Constants.KEY_ALWAYS_DELETE_FROM_SERVER, false).apply()
                }
                // NOW actually delete from storage
                deleteNoteLocally(note, deleteFromServer = false)
            }
            .setNegativeButton(getString(R.string.legacy_delete_from_server)) { _, _ ->
                if (checkboxAlways.isChecked) {
                    prefs.edit().putBoolean(Constants.KEY_ALWAYS_DELETE_FROM_SERVER, true).apply()
                }
                deleteNoteLocally(note, deleteFromServer = true)
            }
            .setCancelable(true)
            .show()
    }
    
    private fun deleteNoteLocally(note: Note, deleteFromServer: Boolean) {
        // Track pending deletion to prevent flicker
        pendingDeletions.add(note.id)
        
        // Delete from storage
        storage.deleteNote(note.id)
        
        // Reload to reflect changes
        loadNotes()
        
        // Show Snackbar with UNDO option
        val message = if (deleteFromServer) {
            getString(R.string.legacy_delete_with_server, note.title)
        } else {
            getString(R.string.legacy_delete_local_only, note.title)
        }
        
        Snackbar.make(recyclerViewNotes, message, Snackbar.LENGTH_LONG)
            .setAction(getString(R.string.snackbar_undo)) {
                // UNDO: Restore note
                storage.saveNote(note)
                pendingDeletions.remove(note.id)
                loadNotes()
            }
            .addCallback(object : Snackbar.Callback() {
                override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                    if (event != DISMISS_EVENT_ACTION) {
                        // Snackbar dismissed without UNDO
                        pendingDeletions.remove(note.id)
                        
                        // Delete from server if requested
                        if (deleteFromServer) {
                            lifecycleScope.launch {
                                try {
                                    val webdavService = WebDavSyncService(this@MainActivity)
                                    val success = webdavService.deleteNoteFromServer(note.id)
                                    if (success) {
                                        runOnUiThread {
                                            Toast.makeText(
                                                this@MainActivity,
                                                getString(R.string.snackbar_deleted_from_server),
                                                Toast.LENGTH_SHORT
                                            ).show()
                                        }
                                    } else {
                                        runOnUiThread {
                                            Toast.makeText(
                                                this@MainActivity,
                                                getString(R.string.snackbar_server_delete_failed),
                                                Toast.LENGTH_LONG
                                            ).show()
                                        }
                                    }
                                } catch (e: Exception) {
                                    runOnUiThread {
                                        Toast.makeText(
                                            this@MainActivity,
                                            "Server-Fehler: ${e.message}",
                                            Toast.LENGTH_LONG
                                        ).show()
                                    }
                                }
                            }
                        }
                    }
                }
            }).show()
    }
    
    /**
     * v1.4.0: Setup FAB mit Dropdown für Notiz-Typ Auswahl
     */
    private fun setupFab() {
        fabAddNote.setOnClickListener { view ->
            showNoteTypePopup(view)
        }
    }
    
    /**
     * v1.4.0: Zeigt Popup-Menü zur Auswahl des Notiz-Typs
     */
    private fun showNoteTypePopup(anchor: View) {
        val popupMenu = PopupMenu(this, anchor, Gravity.END)
        popupMenu.inflate(R.menu.menu_fab_note_types)
        
        // Icons im Popup anzeigen (via Reflection, da standardmäßig ausgeblendet)
        try {
            val fields = popupMenu.javaClass.declaredFields
            for (field in fields) {
                if ("mPopup" == field.name) {
                    field.isAccessible = true
                    val menuPopupHelper = field.get(popupMenu)
                    val classPopupHelper = Class.forName(menuPopupHelper.javaClass.name)
                    val setForceIcons = classPopupHelper.getMethod("setForceShowIcon", Boolean::class.java)
                    setForceIcons.invoke(menuPopupHelper, true)
                    break
                }
            }
        } catch (e: Exception) {
            Logger.w(TAG, "Could not force show icons in popup menu: ${e.message}")
        }
        
        popupMenu.setOnMenuItemClickListener { menuItem ->
            val noteType = when (menuItem.itemId) {
                R.id.action_create_text_note -> NoteType.TEXT
                R.id.action_create_checklist -> NoteType.CHECKLIST
                else -> return@setOnMenuItemClickListener false
            }
            
            val intent = Intent(this, NoteEditorActivity::class.java)
            intent.putExtra(NoteEditorActivity.EXTRA_NOTE_TYPE, noteType.name)
            startActivity(intent)
            true
        }
        
        popupMenu.show()
    }
    
    private fun loadNotes() {
        val notes = storage.loadAllNotes()
        
        // Filter out notes that are pending deletion (prevent flicker)
        val filteredNotes = notes.filter { it.id !in pendingDeletions }
        
        // Submit list with callback to scroll to top after list is updated
        adapter.submitList(filteredNotes) {
            // Scroll to top after list update is complete
            // Wichtig: Nach dem Erstellen/Bearbeiten einer Notiz
            if (filteredNotes.isNotEmpty()) {
                recyclerViewNotes.scrollToPosition(0)
            }
        }
        
        // Material 3 Empty State Card
        emptyStateCard.visibility = if (filteredNotes.isEmpty()) {
            android.view.View.VISIBLE
        } else {
            android.view.View.GONE
        }
    }
    
    private fun openNoteEditor(noteId: String?) {
        val intent = Intent(this, NoteEditorActivity::class.java)
        noteId?.let {
            intent.putExtra(NoteEditorActivity.EXTRA_NOTE_ID, it)
        }
        startActivity(intent)
    }
    
    private fun openSettings() {
        // v1.5.0: Use new Jetpack Compose Settings
        val intent = Intent(this, dev.dettmer.simplenotes.ui.settings.ComposeSettingsActivity::class.java)
        @Suppress("DEPRECATION")
        startActivityForResult(intent, REQUEST_SETTINGS)
    }
    
    private fun triggerManualSync() {
        // 🔄 v1.3.1: Check if sync already running (Banner zeigt Status)
        if (!SyncStateManager.tryStartSync("manual")) {
            return
        }
        
        lifecycleScope.launch {
            try {
                // Create sync service
                val syncService = WebDavSyncService(this@MainActivity)
                
                // 🔥 v1.1.2: Check if there are unsynced changes first (performance optimization)
                if (!syncService.hasUnsyncedChanges()) {
                    Logger.d(TAG, "⏭️ Manual Sync: No unsynced changes - skipping")
                    val message = getString(R.string.toast_already_synced)
                    SyncStateManager.markCompleted(message)
                    return@launch
                }
                
                // ⭐ WICHTIG: Server-Erreichbarkeits-Check VOR Sync (wie in SyncWorker)
                val isReachable = withContext(Dispatchers.IO) {
                    syncService.isServerReachable()
                }
                
                if (!isReachable) {
                    Logger.d(TAG, "⏭️ Manual Sync: Server not reachable - aborting")
                    SyncStateManager.markError(getString(R.string.snackbar_server_unreachable))
                    return@launch
                }
                
                // Server ist erreichbar → Sync durchführen
                val result = withContext(Dispatchers.IO) {
                    syncService.syncNotes()
                }
                
                // Show result
                if (result.isSuccess) {
                    SyncStateManager.markCompleted("${result.syncedCount} Notizen")
                    loadNotes() // Reload notes
                } else {
                    SyncStateManager.markError(result.errorMessage)
                }
                
            } catch (e: Exception) {
                SyncStateManager.markError(e.message)
            }
        }
    }
    
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        optionsMenu = menu  // 🔄 v1.3.1: Store reference for sync button state
        return true
    }
    
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_settings -> {
                openSettings()
                true
            }
            R.id.action_sync -> {
                triggerManualSync()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
    
    private fun requestNotificationPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) 
                != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(
                    arrayOf(Manifest.permission.POST_NOTIFICATIONS),
                    REQUEST_NOTIFICATION_PERMISSION
                )
            }
        }
    }
    
    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        
        if (requestCode == REQUEST_SETTINGS && resultCode == RESULT_OK) {
            // Restore was successful, reload notes
            loadNotes()
        }
    }
    
    /**
     * v1.4.1: Migriert bestehende Checklisten für Abwärtskompatibilität.
     * 
     * Problem: v1.4.0 Checklisten haben leeren "content", was auf älteren
     * App-Versionen (v1.3.x) als leere Notiz angezeigt wird.
     * 
     * Lösung: Alle Checklisten ohne Fallback-Content als PENDING markieren,
     * damit sie beim nächsten Sync mit Fallback-Content hochgeladen werden.
     * 
     * TODO: Diese Migration kann entfernt werden, sobald v1.4.0 nicht mehr
     * im Umlauf ist (ca. 6 Monate nach v1.4.1 Release, also ~Juli 2026).
     * Tracking: https://github.com/inventory69/simple-notes-sync/issues/XXX
     */
    private fun migrateChecklistsForBackwardsCompat() {
        val migrationKey = "v1.4.1_checklist_migration_done"
        
        // Nur einmal ausführen
        if (prefs.getBoolean(migrationKey, false)) {
            return
        }
        
        val allNotes = storage.loadAllNotes()
        val checklistsToMigrate = allNotes.filter { note ->
            note.noteType == NoteType.CHECKLIST && 
            note.content.isBlank() &&
            note.checklistItems?.isNotEmpty() == true
        }
        
        if (checklistsToMigrate.isNotEmpty()) {
            Logger.d(TAG, "🔄 v1.4.1 Migration: Found ${checklistsToMigrate.size} checklists without fallback content")
            
            for (note in checklistsToMigrate) {
                // Als PENDING markieren, damit beim nächsten Sync der Fallback-Content 
                // generiert und hochgeladen wird
                val updatedNote = note.copy(
                    syncStatus = dev.dettmer.simplenotes.models.SyncStatus.PENDING
                )
                storage.saveNote(updatedNote)
                Logger.d(TAG, "   📝 Marked for re-sync: ${note.title}")
            }
            
            Logger.d(TAG, "✅ v1.4.1 Migration: ${checklistsToMigrate.size} checklists marked for re-sync")
        }
        
        // Migration als erledigt markieren
        prefs.edit().putBoolean(migrationKey, true).apply()
    }
    
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        
        when (requestCode) {
            REQUEST_NOTIFICATION_PERMISSION -> {
                if (grantResults.isNotEmpty() && 
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    showToast(getString(R.string.toast_notifications_enabled))
                } else {
                    showToast(getString(R.string.toast_notifications_disabled))
                }
            }
        }
    }
    
    /**
     * 🌍 v1.7.2: Debug-Logging für Locale-Problem
     * Hilft zu identifizieren warum deutsche Strings trotz englischer App angezeigt werden
     */
    private fun logLocaleInfo() {
        if (!BuildConfig.DEBUG) return
        
        Logger.d(TAG, "╔═══════════════════════════════════════════════════")
        Logger.d(TAG, "║ 🌍 LOCALE DEBUG INFO")
        Logger.d(TAG, "╠═══════════════════════════════════════════════════")
        
        // System Locale
        val systemLocale = java.util.Locale.getDefault()
        Logger.d(TAG, "║ System Locale (Locale.getDefault()): $systemLocale")
        
        // Resources Locale
        val resourcesLocale = resources.configuration.locales[0]
        Logger.d(TAG, "║ Resources Locale: $resourcesLocale")
        
        // Context Locale (API 24+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            val contextLocales = resources.configuration.locales
            Logger.d(TAG, "║ Context Locales (all): $contextLocales")
        }
        
        // Test String Loading
        val testString = getString(R.string.toast_already_synced)
        Logger.d(TAG, "║ Test: getString(R.string.toast_already_synced)")
        Logger.d(TAG, "║ Result: '$testString'")
        Logger.d(TAG, "║ Expected EN: '✅ Already synced'")
        Logger.d(TAG, "║ Is German?: ${testString.contains("Bereits") || testString.contains("synchronisiert")}")
        
        Logger.d(TAG, "╚═══════════════════════════════════════════════════")
    }
}
