package com.seven.ikar.kotlin.feature.archive

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.seven.ikar.kotlin.ui.IkarScreenSurface
import com.seven.ikar.kotlin.ui.IkarSimpleHeader
import com.seven.ikar.kotlin.ui.theme.TelegramBorder
import com.seven.ikar.kotlin.ui.theme.TelegramInkMuted

@Composable
fun ArchiveExtractorScreen(
    state: ArchiveExtractorUiState,
    onBackClick: () -> Unit,
    onKeepFoldersChanged: (Boolean) -> Unit,
    onOverwriteExistingChanged: (Boolean) -> Unit,
    onExtractClick: () -> Unit,
    onCancelClick: () -> Unit
) {
    IkarScreenSurface(modifier = Modifier.fillMaxSize()) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top))
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 18.dp, top = 16.dp, end = 18.dp, bottom = 12.dp),
                verticalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                IkarSimpleHeader(
                    title = "Архив",
                    onBackClick = onBackClick
                )
            }

            Column(
                modifier = Modifier
                    .weight(1f)
                    .verticalScroll(rememberScrollState())
                    .padding(horizontal = 18.dp),
                verticalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                state.openError?.let { error ->
                    ArchiveErrorPanel(
                        title = "Не удалось открыть архив",
                        message = error.message,
                        fileName = error.fileName
                    )
                }

                state.archive?.let { archive ->
                    ArchivePanel {
                        Text(
                            text = archive.fileName,
                            style = MaterialTheme.typography.headlineMedium,
                            maxLines = 2,
                            overflow = TextOverflow.Ellipsis
                        )
                        Text(
                            text = "${formatArchiveBytes(archive.fileSizeBytes)} · ZIP-архив",
                            style = MaterialTheme.typography.bodyMedium,
                            color = TelegramInkMuted
                        )
                    }

                    ArchivePanel {
                        Text(
                            text = "Что будет сделано",
                            style = MaterialTheme.typography.titleLarge,
                            fontWeight = FontWeight.SemiBold
                        )
                        Spacer(modifier = Modifier.height(6.dp))
                        Text(
                            text = "Икар распакует файлы в отдельную папку приложения. Опасные пути вида ../ будут пропущены, чтобы архив не смог записать файлы вне папки распаковки.",
                            style = MaterialTheme.typography.bodyMedium,
                            color = TelegramInkMuted
                        )
                    }
                }

                if (state.isInspecting) {
                    ArchivePanel {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically,
                            horizontalArrangement = Arrangement.spacedBy(12.dp)
                        ) {
                            CircularProgressIndicator(modifier = Modifier.size(22.dp), strokeWidth = 2.dp)
                            Text(
                                text = "Читаю список файлов в архиве...",
                                style = MaterialTheme.typography.bodyMedium
                            )
                        }
                    }
                }

                state.inspection?.let { inspection ->
                    ArchivePanel {
                        Text(
                            text = "Состав архива",
                            style = MaterialTheme.typography.titleLarge,
                            fontWeight = FontWeight.SemiBold
                        )
                        Spacer(modifier = Modifier.height(10.dp))
                        ArchiveStatRow("Файлы", inspection.totalFiles.toString())
                        ArchiveStatRow("Папки", inspection.totalDirectories.toString())
                        ArchiveStatRow("Общий размер", formatArchiveBytes(inspection.knownUncompressedBytes))
                        if (inspection.skippedUnsafeEntries > 0) {
                            ArchiveStatRow("Будет пропущено небезопасных путей", inspection.skippedUnsafeEntries.toString())
                        }
                    }

                    ArchivePanel(padding = PaddingValues(0.dp)) {
                        Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 14.dp)) {
                            Text(
                                text = "Первые файлы",
                                style = MaterialTheme.typography.titleLarge,
                                fontWeight = FontWeight.SemiBold
                            )
                            Text(
                                text = "Показан предварительный список, сама распаковка начнётся только после нажатия кнопки.",
                                style = MaterialTheme.typography.bodySmall,
                                color = TelegramInkMuted
                            )
                        }

                        if (inspection.previewEntries.isEmpty()) {
                            Text(
                                text = "В архиве нет файлов для распаковки.",
                                modifier = Modifier.padding(horizontal = 16.dp, vertical = 14.dp),
                                style = MaterialTheme.typography.bodyMedium,
                                color = TelegramInkMuted
                            )
                        } else {
                            inspection.previewEntries.forEach { entry ->
                                ArchiveEntryRow(entry)
                            }
                        }
                    }

                    ArchivePanel(padding = PaddingValues(0.dp)) {
                        ArchiveOptionRow(
                            title = "Сохранить папки из архива",
                            subtitle = "Если выключить, все файлы будут сложены в одну папку.",
                            checked = state.options.keepFolders,
                            enabled = !state.isExtracting,
                            onCheckedChange = onKeepFoldersChanged
                        )
                        ArchiveDivider()
                        ArchiveOptionRow(
                            title = "Заменять совпадающие файлы",
                            subtitle = "Если выключить, Икар добавит номер к имени файла и ничего не перезапишет.",
                            checked = state.options.overwriteExisting,
                            enabled = !state.isExtracting,
                            onCheckedChange = onOverwriteExistingChanged
                        )
                    }
                }

                state.progress?.let { progress ->
                    ArchivePanel {
                        Text(
                            text = "Распаковка выполняется",
                            style = MaterialTheme.typography.titleLarge,
                            fontWeight = FontWeight.SemiBold
                        )
                        Spacer(modifier = Modifier.height(10.dp))
                        LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
                        Spacer(modifier = Modifier.height(10.dp))
                        Text(
                            text = buildProgressText(progress),
                            style = MaterialTheme.typography.bodyMedium,
                            color = TelegramInkMuted
                        )
                        progress.currentEntry?.let { currentEntry ->
                            Text(
                                text = currentEntry,
                                style = MaterialTheme.typography.bodySmall,
                                color = TelegramInkMuted,
                                maxLines = 1,
                                overflow = TextOverflow.Ellipsis
                            )
                        }
                    }
                }

                state.result?.let { result ->
                    ArchivePanel {
                        Text(
                            text = "Готово",
                            style = MaterialTheme.typography.titleLarge,
                            color = MaterialTheme.colorScheme.primary,
                            fontWeight = FontWeight.SemiBold
                        )
                        Spacer(modifier = Modifier.height(8.dp))
                        Text(
                            text = "Распаковано файлов: ${result.extractedFiles}. Записано: ${formatArchiveBytes(result.writtenBytes)}.",
                            style = MaterialTheme.typography.bodyMedium
                        )
                        if (result.skippedUnsafeEntries > 0) {
                            Text(
                                text = "Пропущено небезопасных путей: ${result.skippedUnsafeEntries}.",
                                style = MaterialTheme.typography.bodyMedium,
                                color = MaterialTheme.colorScheme.error
                            )
                        }
                        Spacer(modifier = Modifier.height(8.dp))
                        Text(
                            text = result.outputDirectoryPath,
                            style = MaterialTheme.typography.bodySmall,
                            color = TelegramInkMuted
                        )
                    }
                }

                state.errorMessage?.let { message ->
                    ArchiveErrorPanel(
                        title = "Ошибка",
                        message = message,
                        fileName = state.archive?.fileName
                    )
                }

                Spacer(modifier = Modifier.height(8.dp))
            }

            ArchiveActionBar(
                state = state,
                onExtractClick = onExtractClick,
                onCancelClick = onCancelClick
            )
        }
    }
}

@Composable
private fun ArchiveActionBar(
    state: ArchiveExtractorUiState,
    onExtractClick: () -> Unit,
    onCancelClick: () -> Unit
) {
    Surface(
        color = MaterialTheme.colorScheme.surface,
        shape = RectangleShape,
        shadowElevation = 8.dp
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .navigationBarsPadding()
                .padding(horizontal = 18.dp, vertical = 12.dp),
            verticalArrangement = Arrangement.spacedBy(10.dp)
        ) {
            if (state.isExtracting) {
                OutlinedButton(
                    onClick = onCancelClick,
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text("Отменить распаковку")
                }
            } else {
                Button(
                    onClick = onExtractClick,
                    modifier = Modifier.fillMaxWidth(),
                    enabled = state.archive != null && state.inspection != null && state.inspection.totalFiles > 0
                ) {
                    Text("Распаковать ZIP")
                }
            }
        }
    }
}

@Composable
private fun ArchivePanel(
    modifier: Modifier = Modifier,
    padding: PaddingValues = PaddingValues(16.dp),
    content: @Composable ColumnScope.() -> Unit
) {
    Surface(
        modifier = modifier
            .fillMaxWidth()
            .border(1.dp, TelegramBorder, RectangleShape),
        shape = RectangleShape,
        color = MaterialTheme.colorScheme.surface,
        shadowElevation = 0.dp
    ) {
        Column(
            modifier = Modifier.padding(padding),
            verticalArrangement = Arrangement.spacedBy(0.dp),
            content = content
        )
    }
}

@Composable
private fun ArchiveErrorPanel(
    title: String,
    message: String,
    fileName: String?
) {
    ArchivePanel {
        Text(
            text = title,
            style = MaterialTheme.typography.titleLarge,
            color = MaterialTheme.colorScheme.error,
            fontWeight = FontWeight.SemiBold
        )
        fileName?.let {
            Text(
                text = it,
                style = MaterialTheme.typography.bodyMedium,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
        Spacer(modifier = Modifier.height(6.dp))
        Text(
            text = message,
            style = MaterialTheme.typography.bodyMedium,
            color = TelegramInkMuted
        )
    }
}

@Composable
private fun ArchiveStatRow(
    title: String,
    value: String
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 4.dp),
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            text = title,
            modifier = Modifier.weight(1f),
            style = MaterialTheme.typography.bodyMedium,
            color = TelegramInkMuted
        )
        Text(
            text = value,
            style = MaterialTheme.typography.titleMedium
        )
    }
}

@Composable
private fun ArchiveEntryRow(entry: ArchiveEntryPreview) {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 10.dp),
        verticalArrangement = Arrangement.spacedBy(3.dp)
    ) {
        Text(
            text = if (entry.isDirectory) "${entry.name}/" else entry.name,
            style = MaterialTheme.typography.bodyMedium,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
        Text(
            text = if (entry.isDirectory) "папка" else formatArchiveBytes(entry.sizeBytes),
            style = MaterialTheme.typography.bodySmall,
            color = TelegramInkMuted
        )
    }
    ArchiveDivider()
}

@Composable
private fun ArchiveOptionRow(
    title: String,
    subtitle: String,
    checked: Boolean,
    enabled: Boolean,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(enabled = enabled) { onCheckedChange(!checked) }
            .padding(horizontal = 12.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        Checkbox(
            checked = checked,
            enabled = enabled,
            onCheckedChange = onCheckedChange
        )
        Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(3.dp)) {
            Text(
                text = title,
                style = MaterialTheme.typography.titleMedium
            )
            Text(
                text = subtitle,
                style = MaterialTheme.typography.bodySmall,
                color = TelegramInkMuted
            )
        }
    }
}

@Composable
private fun ArchiveDivider() {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(1.dp)
            .background(TelegramBorder)
    )
}

private fun buildProgressText(progress: ArchiveExtractionProgress): String {
    val total = progress.totalEntries.takeIf { it > 0 }
    val entryPart = if (total != null) {
        "${progress.processedEntries} из $total"
    } else {
        progress.processedEntries.toString()
    }
    return "Обработано записей: $entryPart. Файлов: ${progress.extractedFiles}. Записано: ${formatArchiveBytes(progress.writtenBytes)}."
}
