package com.syncflow.ui.addpair

import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.selection.selectable
import androidx.compose.ui.semantics.Role
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.syncflow.domain.model.*
import com.syncflow.ui.browser.LocalBrowserDialog
import com.syncflow.ui.browser.RemoteBrowserDialog
import java.time.DayOfWeek

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AddPairScreen(onDone: () -> Unit, vm: AddPairViewModel = hiltViewModel()) {
    val s by vm.state.collectAsState()
    LaunchedEffect(s.done) { if (s.done) onDone() }

    val context = LocalContext.current
    var showRemoteBrowser by remember { mutableStateOf(false) }
    var showLocalBrowser by remember { mutableStateOf(false) }

    val safLauncher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
        if (uri != null) {
            context.contentResolver.takePersistableUriPermission(
                uri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
            )
            vm.update { copy(localPath = uri.toString()) }
        }
    }

    if (showLocalBrowser) {
        LocalBrowserDialog(
            initialPath = s.localPath.ifBlank { "" },
            onSelect = { path ->
                if (s.multiFolder) vm.addLocalFolder(path) else vm.update { copy(localPath = path) }
                showLocalBrowser = false
            },
            onDismiss = { showLocalBrowser = false },
        )
    }

    if (showRemoteBrowser && s.selectedAccountId != -1L) {
        RemoteBrowserDialog(
            accountId = s.selectedAccountId,
            initialPath = s.remotePath.ifBlank { "/" },
            onSelect = { path ->
                vm.update { copy(remotePath = path) }
                showRemoteBrowser = false
            },
            onDismiss = { showRemoteBrowser = false },
        )
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(if (s.name.isBlank()) "New Sync Pair" else s.name, fontWeight = FontWeight.SemiBold) },
                navigationIcon = { IconButton(onClick = onDone) { Icon(Icons.Default.Close, null) } },
                actions = {
                    TextButton(onClick = vm::save, enabled = !s.isSaving) {
                        if (s.isSaving) CircularProgressIndicator(Modifier.size(18.dp), strokeWidth = 2.dp)
                        else Text("Save", fontWeight = FontWeight.SemiBold)
                    }
                },
            )
        },
    ) { padding ->
        Column(
            modifier = Modifier
                .padding(padding)
                .verticalScroll(rememberScrollState()),
        ) {
            // ── Pair name ────────────────────────────────────────────────────
            Section(title = null) {
                OutlinedTextField(
                    value = s.name, onValueChange = { vm.update { copy(name = it) } },
                    label = { Text(if (s.multiFolder) "Group name prefix (optional)" else "Sync pair name") },
                    leadingIcon = { Icon(Icons.Default.DriveFileRenameOutline, null) },
                    singleLine = true, modifier = Modifier.fillMaxWidth(),
                    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
                )
            }

            // ── Folders ──────────────────────────────────────────────────────
            Section(title = "Folders", icon = Icons.Default.FolderOpen) {
                // Account
                if (s.accounts.isEmpty()) {
                    Text("No accounts added — go to Settings first.", color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall)
                } else {
                    Text("Cloud account", style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
                    SingleChoiceSegmentedButtonRow(modifier = Modifier.fillMaxWidth()) {
                        s.accounts.forEachIndexed { idx, acct ->
                            SegmentedButton(
                                selected = s.selectedAccountId == acct.id,
                                onClick = { vm.update { copy(selectedAccountId = acct.id, remotePath = "") } },
                                shape = SegmentedButtonDefaults.itemShape(idx, s.accounts.size),
                                label = { Text(acct.displayName, maxLines = 1) },
                            )
                        }
                    }
                }

                Spacer(Modifier.height(4.dp))

                // Multi-folder mode toggle (new pairs only — editing stays single-folder)
                if (!s.isEditing) {
                    ToggleRow(
                        label = "Back up multiple folders",
                        description = "Pick several folders; each is saved as its own subfolder under the remote base (no overwrites)",
                        checked = s.multiFolder,
                        onToggle = { vm.setMultiFolder(it) },
                    )
                    Spacer(Modifier.height(4.dp))
                }

                if (s.multiFolder) {
                    // Chosen folders list
                    s.localPaths.forEach { p ->
                        Row(
                            modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp),
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            Icon(Icons.Default.Folder, null, Modifier.size(18.dp), tint = MaterialTheme.colorScheme.primary)
                            Spacer(Modifier.width(8.dp))
                            Text(uriToDisplay(p), style = MaterialTheme.typography.bodyMedium,
                                maxLines = 1, modifier = Modifier.weight(1f))
                            IconButton(onClick = { vm.removeLocalFolder(p) }) {
                                Icon(Icons.Default.Close, "Remove folder")
                            }
                        }
                    }
                    OutlinedButton(onClick = { showLocalBrowser = true }, modifier = Modifier.fillMaxWidth()) {
                        Icon(Icons.Default.Add, null)
                        Spacer(Modifier.width(6.dp))
                        Text("Add folder")
                    }
                } else {
                    // Single local folder
                    Box(modifier = Modifier.fillMaxWidth()) {
                        OutlinedTextField(
                            value = uriToDisplay(s.localPath), onValueChange = {},
                            label = { Text("Local folder") },
                            leadingIcon = { Icon(Icons.Default.PhoneAndroid, null) },
                            trailingIcon = { Icon(Icons.Default.FolderOpen, null) },
                            readOnly = true, singleLine = true, modifier = Modifier.fillMaxWidth(),
                            placeholder = { Text("Tap to choose folder…") },
                        )
                        Box(modifier = Modifier.matchParentSize().clickable { showLocalBrowser = true })
                    }
                }

                // Remote folder (base, in multi-folder mode)
                OutlinedTextField(
                    value = s.remotePath, onValueChange = { vm.update { copy(remotePath = it) } },
                    label = { Text(if (s.multiFolder) "Remote base folder" else "Remote folder") },
                    leadingIcon = { Icon(Icons.Default.Cloud, null) },
                    trailingIcon = {
                        IconButton(
                            onClick = { if (s.selectedAccountId != -1L) showRemoteBrowser = true },
                            enabled = s.selectedAccountId != -1L,
                        ) { Icon(Icons.Default.Folder, "Browse remote") }
                    },
                    singleLine = true, modifier = Modifier.fillMaxWidth(),
                    placeholder = { Text(if (s.multiFolder) "/Backup — each folder becomes a subfolder" else "/ or /Documents/Photos") },
                )

                // Recursive
                ToggleRow(
                    label = "Include subfolders",
                    description = "Sync all nested folders recursively",
                    checked = s.recursive,
                    onToggle = { vm.update { copy(recursive = it) } },
                )
            }

            // ── Sync type ────────────────────────────────────────────────────
            Section(title = "Sync Type", icon = Icons.Default.SyncAlt) {
                RadioGroup(
                    label = "Direction",
                    options = SyncDirection.entries,
                    selected = s.syncDirection,
                    onSelect = { vm.setDirection(it) },
                    itemLabel = { "${it.label}  —  ${it.description}" },
                )
                Spacer(Modifier.height(8.dp))
                RadioGroup(
                    label = "Conflict resolution",
                    options = ConflictStrategy.entries,
                    selected = s.conflictStrategy,
                    onSelect = { vm.update { copy(conflictStrategy = it) } },
                    itemLabel = { it.label },
                )
                Spacer(Modifier.height(8.dp))
                RadioGroup(
                    label = "Deletion behaviour",
                    options = DeleteBehavior.entries,
                    selected = s.deleteBehavior,
                    onSelect = { vm.setDeleteBehavior(it) },
                    itemLabel = { "${it.label}  —  ${it.description}" },
                )
            }

            // ── Schedule ─────────────────────────────────────────────────────
            Section(title = "Schedule", icon = Icons.Default.Schedule) {
                RadioGroup(
                    label = null,
                    options = ScheduleType.entries,
                    selected = s.scheduleType,
                    onSelect = { vm.update { copy(scheduleType = it) } },
                    itemLabel = { it.label },
                )
                AnimatedVisibility(s.scheduleType == ScheduleType.INTERVAL) {
                    Column(Modifier.padding(top = 8.dp)) {
                        OutlinedTextField(
                            value = s.intervalMinutes.toString(),
                            onValueChange = { vm.update { copy(intervalMinutes = it.toIntOrNull()?.coerceAtLeast(15) ?: 15) } },
                            label = { Text("Interval (minutes, min 15)") },
                            leadingIcon = { Icon(Icons.Default.Timer, null) },
                            singleLine = true, modifier = Modifier.fillMaxWidth(),
                            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                        )
                    }
                }
                AnimatedVisibility(s.scheduleType == ScheduleType.DAILY || s.scheduleType == ScheduleType.WEEKLY) {
                    Column(Modifier.padding(top = 8.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
                        OutlinedTextField(
                            value = s.dailyTime,
                            onValueChange = { vm.update { copy(dailyTime = it) } },
                            label = { Text("Time (HH:mm)") },
                            leadingIcon = { Icon(Icons.Default.AccessTime, null) },
                            singleLine = true, modifier = Modifier.fillMaxWidth(),
                            placeholder = { Text("02:00") },
                        )
                        if (s.scheduleType == ScheduleType.WEEKLY) {
                            WeekdayPicker(weekdays = s.weekdays, onChange = { vm.update { copy(weekdays = it) } })
                        }
                    }
                }
            }

            // ── Conditions ───────────────────────────────────────────────────
            Section(title = "Run Conditions", icon = Icons.Default.Tune) {
                ToggleRow("Wi-Fi only", "Only sync on unmetered Wi-Fi connections", s.wifiOnly) {
                    vm.update { copy(wifiOnly = it, wifiSsid = if (!it) "" else wifiSsid) }
                }
                AnimatedVisibility(s.wifiOnly) {
                    OutlinedTextField(
                        value = s.wifiSsid,
                        onValueChange = { vm.update { copy(wifiSsid = it) } },
                        label = { Text("Specific Wi-Fi network (SSID)") },
                        placeholder = { Text("Leave blank for any Wi-Fi") },
                        leadingIcon = { Icon(Icons.Default.Wifi, null) },
                        singleLine = true, modifier = Modifier.fillMaxWidth().padding(top = 6.dp),
                    )
                }
                ToggleRow("Charging only", "Only sync when device is charging", s.chargingOnly) {
                    vm.update { copy(chargingOnly = it) }
                }
                Spacer(Modifier.height(4.dp))
                Text("Minimum battery level: ${if (s.minBatteryPct == 0) "None" else "${s.minBatteryPct}%"}",
                    style = MaterialTheme.typography.bodySmall)
                Slider(
                    value = s.minBatteryPct.toFloat(),
                    onValueChange = { vm.update { copy(minBatteryPct = it.toInt()) } },
                    valueRange = 0f..90f, steps = 17,
                    modifier = Modifier.fillMaxWidth(),
                )
            }

            // ── File filters ─────────────────────────────────────────────────
            Section(title = "File Filters", icon = Icons.Default.FilterAlt) {
                ToggleRow("Skip hidden files", "Skip files/folders starting with '.'", s.skipHiddenFiles) {
                    vm.update { copy(skipHiddenFiles = it) }
                }

                Spacer(Modifier.height(8.dp))
                Text("Extensions to sync (leave blank = all files)",
                    style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
                OutlinedTextField(
                    value = s.includeExtensions,
                    onValueChange = { vm.update { copy(includeExtensions = it) } },
                    label = { Text("Include only (e.g. jpg png pdf)") },
                    placeholder = { Text("Space-separated, blank = all") },
                    singleLine = true, modifier = Modifier.fillMaxWidth(),
                )
                Spacer(Modifier.height(4.dp))
                OutlinedTextField(
                    value = s.excludeExtensions,
                    onValueChange = { vm.update { copy(excludeExtensions = it) } },
                    label = { Text("Exclude extensions (e.g. tmp bak log)") },
                    singleLine = true, modifier = Modifier.fillMaxWidth(),
                )

                Spacer(Modifier.height(8.dp))
                Text("Exclude filename patterns",
                    style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
                OutlinedTextField(
                    value = s.excludePatterns,
                    onValueChange = { vm.update { copy(excludePatterns = it) } },
                    label = { Text("One pattern per line (supports *)") },
                    modifier = Modifier.fillMaxWidth().height(90.dp),
                )

                Spacer(Modifier.height(8.dp))
                Text("File size limits (0 = no limit)",
                    style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    OutlinedTextField(
                        value = if (s.minFileSizeKb == 0L) "" else s.minFileSizeKb.toString(),
                        onValueChange = { vm.update { copy(minFileSizeKb = it.toLongOrNull() ?: 0L) } },
                        label = { Text("Min size (KB)") },
                        singleLine = true, modifier = Modifier.weight(1f),
                        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                    )
                    OutlinedTextField(
                        value = if (s.maxFileSizeKb == 0L) "" else s.maxFileSizeKb.toString(),
                        onValueChange = { vm.update { copy(maxFileSizeKb = it.toLongOrNull() ?: 0L) } },
                        label = { Text("Max size (KB)") },
                        singleLine = true, modifier = Modifier.weight(1f),
                        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                    )
                }
            }

            // ── Notifications ────────────────────────────────────────────────
            Section(title = "Notifications", icon = Icons.Default.Notifications) {
                ToggleRow("Notify on sync complete", "Show notification when sync finishes successfully", s.notifyOnComplete) {
                    vm.update { copy(notifyOnComplete = it) }
                }
                ToggleRow("Notify on errors", "Show notification when sync encounters errors", s.notifyOnError) {
                    vm.update { copy(notifyOnError = it) }
                }
            }

            // ── Error ────────────────────────────────────────────────────────
            s.error?.let { err ->
                Box(Modifier.padding(horizontal = 20.dp)) {
                    Text(err, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall)
                }
            }

            Spacer(Modifier.height(40.dp))
        }
    }
}

// ─── Section wrapper ──────────────────────────────────────────────────────────

@Composable
private fun Section(
    title: String?,
    icon: androidx.compose.ui.graphics.vector.ImageVector? = null,
    content: @Composable ColumnScope.() -> Unit,
) {
    Column(modifier = Modifier.padding(horizontal = 20.dp, vertical = 4.dp)) {
        if (title != null) {
            Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 14.dp, bottom = 4.dp)) {
                icon?.let {
                    Icon(it, null, Modifier.size(18.dp), tint = MaterialTheme.colorScheme.primary)
                    Spacer(Modifier.width(6.dp))
                }
                Text(title, style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.SemiBold, color = MaterialTheme.colorScheme.primary)
            }
            HorizontalDivider()
            Spacer(Modifier.height(8.dp))
        }
        content()
    }
}

// ─── Reusable row components ──────────────────────────────────────────────────

@Composable
private fun ToggleRow(label: String, description: String, checked: Boolean, onToggle: (Boolean) -> Unit) {
    Row(
        modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Column(modifier = Modifier.weight(1f)) {
            Text(label, style = MaterialTheme.typography.bodyMedium)
            Text(description, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
        }
        Switch(checked = checked, onCheckedChange = onToggle)
    }
}

@Composable
private fun <T> RadioGroup(
    label: String?,
    options: List<T>,
    selected: T,
    onSelect: (T) -> Unit,
    itemLabel: (T) -> String,
) {
    Column {
        label?.let {
            Text(it, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(bottom = 2.dp))
        }
        options.forEach { option ->
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .selectable(
                        selected = option == selected,
                        role = Role.RadioButton,
                        onClick = { onSelect(option) },
                    ),
                verticalAlignment = Alignment.CenterVertically,
            ) {
                // onClick = null: the whole row handles selection (bigger tap target + a11y).
                RadioButton(selected = option == selected, onClick = null)
                Text(itemLabel(option), style = MaterialTheme.typography.bodyMedium)
            }
        }
    }
}

@Composable
private fun WeekdayPicker(weekdays: Int, onChange: (Int) -> Unit) {
    val days = listOf("M", "T", "W", "T", "F", "S", "S")
    val fullNames = listOf("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
    Column {
        Text("Repeat on", style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
        Spacer(Modifier.height(4.dp))
        Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
            days.forEachIndexed { i, label ->
                val bit = 1 shl i
                val selected = (weekdays and bit) != 0
                FilterChip(
                    selected = selected,
                    onClick = { onChange(if (selected) weekdays and bit.inv() else weekdays or bit) },
                    label = { Text(label) },
                    modifier = Modifier.weight(1f),
                )
            }
        }
    }
}

private fun uriToDisplay(uriString: String): String {
    if (uriString.isBlank()) return ""
    return try {
        val uri = android.net.Uri.parse(uriString)
        uri.lastPathSegment?.replace(":", "/") ?: uriString
    } catch (e: Exception) {
        uriString
    }
}
