package com.fieldlabel.collector.ui.screens

import android.content.Intent
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
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.foundation.shape.RoundedCornerShape
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.core.content.FileProvider
import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage
import com.fieldlabel.collector.domain.model.CollectionRecord
import com.fieldlabel.collector.service.ExportState
import com.fieldlabel.collector.service.ImportResult
import com.fieldlabel.collector.ui.viewmodel.CollectionViewModel
import com.fieldlabel.collector.ui.viewmodel.CollectionViewModel.ImportUiState
import com.fieldlabel.collector.ui.viewmodel.PrintState
import com.fieldlabel.collector.ui.viewmodel.SettingsViewModel
import java.io.File

/** 地点ごとに標本をまとめたグループ */
private data class LocationGroup(
    val locationId: String,
    val specimens: List<CollectionRecord>
) {
    val representativeRecord: CollectionRecord get() = specimens.first()

    /** 採集日表示。複数日にまたがる場合は「最初日〜最後日」の範囲形式 */
    val date: String get() {
        val dates = specimens.map { it.collectionDate }.distinct().sorted()
        return if (dates.size > 1) "${dates.first()}〜${dates.last()}"
        else dates.first().toString()
    }

    val address: String get() = representativeRecord.displayLocation
    val collectorName: String get() = representativeRecord.collectorName
}

@Composable
fun HistoryScreen(
    onNavigateToPreview:    (String) -> Unit,
    onNavigateToDetail:     (String) -> Unit = {},
    bottomContentPadding:   Dp = 0.dp,
    viewModel:              CollectionViewModel = hiltViewModel(),
    settingsViewModel:      SettingsViewModel   = hiltViewModel()
) {
    val context              = LocalContext.current
    val records              by viewModel.allRecords.collectAsState(initial = emptyList())
    val uiState              by viewModel.uiState.collectAsState()
    val exportState          by viewModel.exportState.collectAsState()
    val importState          by viewModel.importState.collectAsState()
    val firstPhotoByLocation by viewModel.firstPhotoByLocation.collectAsState()
    val showThumbnails       by settingsViewModel.showThumbnails.collectAsState()
    var query                by remember { mutableStateOf("") }

    // 選択中の地点 ID セット
    var selectedLocationIds by remember { mutableStateOf(emptySet<String>()) }
    val inSelectionMode = selectedLocationIds.isNotEmpty()

    // エクスポートダイアログ表示フラグ
    var showBulkExportDialog by remember { mutableStateOf(false) }

    // ファイルピッカー（ZIP / XLSX を選択してインポート）
    val importLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.OpenDocument()
    ) { uri: Uri? ->
        uri?.let { viewModel.importData(it) }
    }

    // エクスポート完了 → 共有インテント発行
    LaunchedEffect(exportState) {
        if (exportState is ExportState.Done) {
            val file = (exportState as ExportState.Done).file
            val uri  = FileProvider.getUriForFile(
                context,
                "${context.packageName}.fileprovider",
                file
            )
            val mimeType = if (file.name.endsWith(".zip"))
                "application/zip"
            else
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            val intent = Intent(Intent.ACTION_SEND).apply {
                type = mimeType
                putExtra(Intent.EXTRA_STREAM, uri)
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            context.startActivity(Intent.createChooser(intent, "エクスポートファイルを共有"))
            viewModel.clearExportState()
            selectedLocationIds = emptySet()   // 選択解除
        }
    }

    // 印刷結果ダイアログ（AlertDialog は独立ウィンドウなので配置順不問）
    when (val ps = uiState.printState) {
        is PrintState.Done -> AlertDialog(
            onDismissRequest = { viewModel.clearPrintState() },
            title = { Text("印刷完了") },
            text  = { Text(ps.message) },
            confirmButton = {
                TextButton(onClick = { viewModel.clearPrintState() }) { Text("OK") }
            }
        )
        is PrintState.Error -> AlertDialog(
            onDismissRequest = { viewModel.clearPrintState() },
            title = { Text("エラー") },
            text  = { Text(ps.message) },
            confirmButton = {
                TextButton(onClick = { viewModel.clearPrintState() }) { Text("閉じる") }
            }
        )
        else -> {}
    }

    // エクスポートエラーダイアログ
    if (exportState is ExportState.Error) {
        AlertDialog(
            onDismissRequest = { viewModel.clearExportState() },
            title = { Text("エクスポートエラー") },
            text  = { Text((exportState as ExportState.Error).message) },
            confirmButton = {
                TextButton(onClick = { viewModel.clearExportState() }) { Text("閉じる") }
            }
        )
    }

    // インポート進捗・結果ダイアログ
    when (val is_ = importState) {
        is ImportUiState.InProgress -> {
            AlertDialog(
                onDismissRequest = { /* 処理中は閉じない */ },
                title = { Text("インポート中…") },
                text  = {
                    Row(verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                        CircularProgressIndicator(modifier = Modifier.size(24.dp), strokeWidth = 2.5.dp)
                        Text("データを取り込んでいます")
                    }
                },
                confirmButton = {}
            )
        }
        is ImportUiState.Done -> {
            val r = is_.result
            AlertDialog(
                onDismissRequest = { viewModel.clearImportState() },
                title = { Text("インポート完了") },
                text  = {
                    Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                        Text("✓ 新規取込: ${r.imported} 件")
                        if (r.skipped > 0)
                            Text("⏭ スキップ (重複): ${r.skipped} 件",
                                color = MaterialTheme.colorScheme.outline)
                        if (r.errors.isNotEmpty()) {
                            Spacer(Modifier.height(4.dp))
                            Text("⚠ エラー: ${r.errors.size} 件",
                                color = MaterialTheme.colorScheme.error)
                            Text(r.errors.take(5).joinToString("\n"),
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.error)
                            if (r.errors.size > 5)
                                Text("… 他 ${r.errors.size - 5} 件",
                                    style = MaterialTheme.typography.bodySmall,
                                    color = MaterialTheme.colorScheme.outline)
                        }
                    }
                },
                confirmButton = {
                    TextButton(onClick = { viewModel.clearImportState() }) { Text("OK") }
                }
            )
        }
        is ImportUiState.Error -> {
            AlertDialog(
                onDismissRequest = { viewModel.clearImportState() },
                title = { Text("インポートエラー") },
                text  = { Text(is_.message) },
                confirmButton = {
                    TextButton(onClick = { viewModel.clearImportState() }) { Text("閉じる") }
                }
            )
        }
        else -> {}
    }

    // 一括エクスポートダイアログ
    if (showBulkExportDialog) {
        BulkExportDialog(
            selectedCount = selectedLocationIds.size,
            onExport = { includePhotos ->
                showBulkExportDialog = false
                viewModel.exportSelectedLocations(selectedLocationIds, includePhotos)
            },
            onDismiss = { showBulkExportDialog = false }
        )
    }

    // 検索フィルタ後にグループ化
    val groups = remember(records, query) {
        val filtered = if (query.isBlank()) records
        else records.filter { r ->
            r.specimenId.contains(query, ignoreCase = true) ||
            r.locationId.contains(query, ignoreCase = true) ||
            r.collectorName.contains(query, ignoreCase = true) ||
            (r.address?.contains(query, ignoreCase = true) == true) ||
            r.notes.contains(query, ignoreCase = true)
        }
        filtered
            .groupBy { it.locationId }
            .map { (id, recs) -> LocationGroup(id, recs.sortedBy { it.specimenNumber }) }
            .sortedByDescending { it.representativeRecord.createdAt }
    }

    Box(modifier = Modifier.fillMaxSize().padding(bottom = bottomContentPadding)) {
        Column(modifier = Modifier.fillMaxSize()) {
            // 検索バー
            OutlinedTextField(
                value         = query,
                onValueChange = { query = it },
                placeholder   = { Text("ID・採集者・場所で検索") },
                leadingIcon   = { Icon(Icons.Default.Search, null) },
                trailingIcon  = if (query.isNotBlank()) {
                    { IconButton(onClick = { query = "" }) { Icon(Icons.Default.Clear, "クリア") } }
                } else null,
                singleLine    = true,
                modifier      = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 12.dp, vertical = 8.dp)
            )

            // カウント行（選択中なら選択数、右端にインポートボタン）
            Row(
                modifier              = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp, vertical = 2.dp),
                verticalAlignment     = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Text(
                    "${groups.size} 地点  /  ${records.size} 標本",
                    style = MaterialTheme.typography.labelMedium,
                    color = MaterialTheme.colorScheme.outline
                )
                Row(verticalAlignment = Alignment.CenterVertically) {
                    if (inSelectionMode) {
                        Text(
                            "${selectedLocationIds.size} 件選択中",
                            style = MaterialTheme.typography.labelMedium,
                            color = MaterialTheme.colorScheme.primary,
                            fontWeight = FontWeight.SemiBold
                        )
                        Spacer(Modifier.width(8.dp))
                    }
                    // インポートボタン（ZIP / XLSX ファイルを取り込む）
                    TextButton(
                        onClick  = {
                            importLauncher.launch(arrayOf(
                                "application/zip",
                                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                                "application/octet-stream",
                                "*/*"
                            ))
                        },
                        enabled  = importState !is ImportUiState.InProgress,
                        contentPadding = PaddingValues(horizontal = 8.dp, vertical = 0.dp)
                    ) {
                        Icon(Icons.Default.FileDownload, null,
                            modifier = Modifier.size(16.dp))
                        Spacer(Modifier.width(4.dp))
                        Text("インポート",
                            style = MaterialTheme.typography.labelMedium)
                    }
                }
            }

            LazyColumn(
                contentPadding      = PaddingValues(
                    start  = 12.dp,
                    end    = 12.dp,
                    top    = 4.dp,
                    // 選択バーが表示される場合は底部余白を増やす
                    bottom = if (inSelectionMode) 160.dp else 88.dp
                ),
                verticalArrangement = Arrangement.spacedBy(8.dp),
                modifier            = Modifier.fillMaxSize()
            ) {
                items(groups, key = { it.locationId }) { group ->
                    LocationGroupCard(
                        group              = group,
                        isSelected         = group.locationId in selectedLocationIds,
                        thumbnailPath      = if (showThumbnails)
                            firstPhotoByLocation[group.locationId]?.filePath else null,
                        onToggleSelect     = {
                            selectedLocationIds = if (group.locationId in selectedLocationIds)
                                selectedLocationIds - group.locationId
                            else
                                selectedLocationIds + group.locationId
                        },
                        onPreview          = { onNavigateToPreview(it) },
                        onReprint          = { viewModel.reprintRecord(it) },
                        onDelete           = { viewModel.deleteRecord(it) },
                        onUpdate           = { viewModel.updateRecord(it) },
                        onPrintBatch       = { locationId, count ->
                            viewModel.printLocationBatch(locationId, count)
                        },
                        onDeleteGroup      = { viewModel.deleteLocationGroup(group.locationId) },
                        onUpdateCollector  = { newName ->
                            viewModel.updateLocationCollector(group.locationId, newName)
                        },
                        onNavigateToDetail = { onNavigateToDetail(group.locationId) }
                    )
                }
            }
        }

        // ── 一括操作バー（選択モード時） ──────────────────────────────────
        AnimatedVisibility(
            visible  = inSelectionMode,
            enter    = slideInVertically(initialOffsetY = { it }),
            exit     = slideOutVertically(targetOffsetY = { it }),
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .fillMaxWidth()
        ) {
            BulkSelectionBar(
                selectedCount  = selectedLocationIds.size,
                totalCount     = groups.size,
                isExporting    = exportState is ExportState.InProgress,
                onSelectAll    = { selectedLocationIds = groups.map { it.locationId }.toSet() },
                onDeselectAll  = { selectedLocationIds = emptySet() },
                onExport       = { showBulkExportDialog = true }
            )
        }

        // ── 印刷中オーバーレイ（最後に描画 → 最前面に表示） ───────────────
        if (uiState.printState is PrintState.Printing) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = 0.45f)),
                contentAlignment = Alignment.Center
            ) {
                CircularProgressIndicator(color = Color.White)
            }
        }
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// 地点グループカード
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun LocationGroupCard(
    group:              LocationGroup,
    isSelected:         Boolean         = false,
    thumbnailPath:      String?         = null,
    onToggleSelect:     () -> Unit      = {},
    onPreview:          (String) -> Unit,
    onReprint:          (CollectionRecord) -> Unit,
    onDelete:           (CollectionRecord) -> Unit,
    onUpdate:           (CollectionRecord) -> Unit,
    onPrintBatch:       (String, Int) -> Unit,
    onDeleteGroup:      () -> Unit,
    onUpdateCollector:  (String) -> Unit,
    onNavigateToDetail: () -> Unit = {}
) {
    var expanded            by remember { mutableStateOf(false) }
    var showBatchDialog     by remember { mutableStateOf(false) }
    var showEditGroupDialog  by remember { mutableStateOf(false) }
    var showDeleteGroupDialog by remember { mutableStateOf(false) }

    if (showBatchDialog) {
        BatchPrintDialog(
            locationId = group.locationId,
            onConfirm  = { count -> onPrintBatch(group.locationId, count); showBatchDialog = false },
            onDismiss  = { showBatchDialog = false }
        )
    }
    if (showEditGroupDialog) {
        EditLocationDialog(
            group     = group,
            onSave    = { newName -> onUpdateCollector(newName); showEditGroupDialog = false },
            onDismiss = { showEditGroupDialog = false }
        )
    }
    if (showDeleteGroupDialog) {
        AlertDialog(
            onDismissRequest = { showDeleteGroupDialog = false },
            title  = { Text("地点を削除") },
            text   = {
                Text(
                    "${group.locationId} とその全標本（${group.specimens.size}標本）および写真を削除しますか？\n" +
                    "この操作は元に戻せません。"
                )
            },
            confirmButton = {
                TextButton(
                    onClick = { onDeleteGroup(); showDeleteGroupDialog = false },
                    colors  = ButtonDefaults.textButtonColors(
                        contentColor = MaterialTheme.colorScheme.error
                    )
                ) { Text("削除") }
            },
            dismissButton = {
                TextButton(onClick = { showDeleteGroupDialog = false }) { Text("キャンセル") }
            }
        )
    }

    Card(
        modifier = Modifier.fillMaxWidth(),
        colors   = if (isSelected)
            CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.35f))
        else
            CardDefaults.cardColors()
    ) {
        Column(modifier = Modifier.padding(12.dp)) {
            // ── ヘッダー行 ──────────────────────────────────────────────
            Row(
                modifier              = Modifier.fillMaxWidth(),
                verticalAlignment     = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                // 選択チェックボックス
                Checkbox(
                    checked         = isSelected,
                    onCheckedChange = { onToggleSelect() },
                    modifier        = Modifier.size(36.dp)
                )

                Column(
                    modifier = Modifier
                        .weight(1f)
                        .clickable(onClick = onNavigateToDetail)
                        .padding(end = 4.dp)
                ) {
                    Row(
                        verticalAlignment     = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(4.dp)
                    ) {
                        Text(
                            text       = group.locationId,
                            style      = MaterialTheme.typography.titleMedium.copy(
                                fontFamily = FontFamily.Monospace,
                                fontWeight = FontWeight.Bold
                            )
                        )
                        Icon(
                            Icons.Default.ChevronRight,
                            contentDescription = "詳細を表示",
                            modifier = Modifier.size(16.dp),
                            tint     = MaterialTheme.colorScheme.outline
                        )
                    }
                    Text(
                        text  = "${group.date}  ·  ${group.collectorName}",
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.outline
                    )
                    Text(
                        text     = group.address,
                        style    = MaterialTheme.typography.bodySmall,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                    val altitude = group.representativeRecord.altitude
                    if (altitude != null) {
                        Text(
                            text  = "標高: ${"%.1f".format(altitude)}m",
                            style = MaterialTheme.typography.bodySmall,
                            color = MaterialTheme.colorScheme.outline
                        )
                    }
                }

                // サムネイル（設定が ON かつ写真あり）
                if (thumbnailPath != null) {
                    AsyncImage(
                        model              = File(thumbnailPath),
                        contentDescription = "採集写真",
                        contentScale       = ContentScale.Crop,
                        modifier           = Modifier
                            .padding(start = 6.dp)
                            .size(56.dp)
                            .clip(RoundedCornerShape(8.dp))
                    )
                }

                // 標本数バッジ
                Surface(
                    shape = MaterialTheme.shapes.small,
                    color = MaterialTheme.colorScheme.secondaryContainer,
                    modifier = Modifier.padding(start = 6.dp)
                ) {
                    Text(
                        "${group.specimens.size} 標本",
                        style    = MaterialTheme.typography.labelMedium,
                        modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
                    )
                }

                // 地点編集・削除アイコン
                IconButton(
                    onClick  = { showEditGroupDialog = true },
                    modifier = Modifier.size(36.dp)
                ) {
                    Icon(
                        Icons.Default.Edit,
                        contentDescription = "地点を編集",
                        modifier = Modifier.size(18.dp)
                    )
                }
                IconButton(
                    onClick  = { showDeleteGroupDialog = true },
                    modifier = Modifier.size(36.dp),
                    colors   = IconButtonDefaults.iconButtonColors(
                        contentColor = MaterialTheme.colorScheme.error
                    )
                ) {
                    Icon(
                        Icons.Default.Delete,
                        contentDescription = "地点を削除",
                        modifier = Modifier.size(18.dp)
                    )
                }
            }

            // ── ボタン行 ────────────────────────────────────────────────
            Row(
                modifier              = Modifier
                    .fillMaxWidth()
                    .padding(top = 8.dp),
                horizontalArrangement = Arrangement.spacedBy(4.dp)
            ) {
                // 地点ラベル一括印刷
                OutlinedButton(
                    onClick  = { showBatchDialog = true },
                    modifier = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 8.dp, vertical = 6.dp)
                ) {
                    Icon(Icons.Default.Print, null, modifier = Modifier.size(16.dp))
                    Spacer(Modifier.width(4.dp))
                    Text("地点ラベル印刷", style = MaterialTheme.typography.labelMedium)
                }

                // 展開トグル
                OutlinedButton(
                    onClick  = { expanded = !expanded },
                    modifier = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 8.dp, vertical = 6.dp)
                ) {
                    Icon(
                        if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
                        null, modifier = Modifier.size(16.dp)
                    )
                    Spacer(Modifier.width(4.dp))
                    Text(
                        if (expanded) "折りたたむ" else "標本一覧",
                        style = MaterialTheme.typography.labelMedium
                    )
                }
            }

            // ── 標本一覧（展開時） ──────────────────────────────────────
            AnimatedVisibility(
                visible = expanded,
                enter   = expandVertically(),
                exit    = shrinkVertically()
            ) {
                Column(
                    modifier            = Modifier.padding(top = 8.dp),
                    verticalArrangement = Arrangement.spacedBy(4.dp)
                ) {
                    HorizontalDivider()
                    group.specimens.forEach { specimen ->
                        SpecimenRow(
                            record    = specimen,
                            onPreview = { onPreview(specimen.id) },
                            onReprint = { onReprint(specimen) },
                            onDelete  = { onDelete(specimen) },
                            onUpdate  = { onUpdate(it) }
                        )
                    }
                }
            }
        }
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// 標本行
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun SpecimenRow(
    record:    CollectionRecord,
    onPreview: () -> Unit,
    onReprint: () -> Unit,
    onDelete:  () -> Unit,
    onUpdate:  (CollectionRecord) -> Unit
) {
    var showEditDialog   by remember { mutableStateOf(false) }
    var showDeleteDialog by remember { mutableStateOf(false) }

    if (showEditDialog) {
        EditSpecimenDialog(
            record    = record,
            onSave    = { updated -> onUpdate(updated); showEditDialog = false },
            onDismiss = { showEditDialog = false }
        )
    }
    if (showDeleteDialog) {
        AlertDialog(
            onDismissRequest = { showDeleteDialog = false },
            title  = { Text("標本の削除") },
            text   = { Text("${record.specimenId} を削除しますか？\nこの操作は元に戻せません。") },
            confirmButton = {
                TextButton(
                    onClick = { onDelete(); showDeleteDialog = false },
                    colors  = ButtonDefaults.textButtonColors(
                        contentColor = MaterialTheme.colorScheme.error
                    )
                ) { Text("削除") }
            },
            dismissButton = {
                TextButton(onClick = { showDeleteDialog = false }) { Text("キャンセル") }
            }
        )
    }

    Surface(
        shape    = MaterialTheme.shapes.small,
        color    = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f),
        modifier = Modifier.fillMaxWidth()
    ) {
        Row(
            modifier          = Modifier.padding(start = 12.dp, top = 6.dp, bottom = 6.dp, end = 4.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(modifier = Modifier.weight(1f)) {
                Row(
                    verticalAlignment     = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(6.dp)
                ) {
                    Text(
                        record.specimenId,
                        style = MaterialTheme.typography.bodyMedium.copy(
                            fontFamily = FontFamily.Monospace,
                            fontWeight = FontWeight.SemiBold
                        )
                    )
                    if (record.synced) {
                        Icon(Icons.Default.CloudDone, "同期済み",
                            modifier = Modifier.size(13.dp),
                            tint     = MaterialTheme.colorScheme.primary)
                    } else {
                        Icon(Icons.Default.CloudOff, "未同期",
                            modifier = Modifier.size(13.dp),
                            tint     = MaterialTheme.colorScheme.outline)
                    }
                }
                if (record.notes.isNotBlank()) {
                    Text(
                        record.notes,
                        style    = MaterialTheme.typography.bodySmall,
                        color    = MaterialTheme.colorScheme.outline,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                }
            }

            IconButton(onClick = onPreview, modifier = Modifier.size(36.dp)) {
                Icon(Icons.Default.Visibility, "プレビュー", modifier = Modifier.size(18.dp))
            }
            IconButton(onClick = onReprint, modifier = Modifier.size(36.dp)) {
                Icon(Icons.Default.Print, "再印刷", modifier = Modifier.size(18.dp))
            }
            IconButton(onClick = { showEditDialog = true }, modifier = Modifier.size(36.dp)) {
                Icon(Icons.Default.Edit, "編集", modifier = Modifier.size(18.dp))
            }
            IconButton(
                onClick  = { showDeleteDialog = true },
                modifier = Modifier.size(36.dp),
                colors   = IconButtonDefaults.iconButtonColors(
                    contentColor = MaterialTheme.colorScheme.error
                )
            ) {
                Icon(Icons.Default.Delete, "削除", modifier = Modifier.size(18.dp))
            }
        }
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// 地点編集ダイアログ（採集者名を全標本に一括適用）
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun EditLocationDialog(
    group:     LocationGroup,
    onSave:    (newCollectorName: String) -> Unit,
    onDismiss: () -> Unit
) {
    var collectorName by remember { mutableStateOf(group.collectorName) }

    AlertDialog(
        onDismissRequest = onDismiss,
        title  = { Text("地点を編集") },
        text   = {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                Text(
                    group.locationId,
                    style = MaterialTheme.typography.bodySmall.copy(
                        fontFamily = FontFamily.Monospace
                    ),
                    color = MaterialTheme.colorScheme.outline
                )
                OutlinedTextField(
                    value         = collectorName,
                    onValueChange = { collectorName = it },
                    label         = { Text("採集者名（全標本に一括適用）") },
                    leadingIcon   = { Icon(Icons.Default.Person, null) },
                    singleLine    = true,
                    modifier      = Modifier.fillMaxWidth()
                )
            }
        },
        confirmButton = {
            TextButton(
                onClick = { onSave(collectorName) },
                enabled = collectorName.isNotBlank()
            ) { Text("保存") }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) { Text("キャンセル") }
        }
    )
}

// ─────────────────────────────────────────────────────────────────────────────
// 標本編集ダイアログ
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun EditSpecimenDialog(
    record:    CollectionRecord,
    onSave:    (CollectionRecord) -> Unit,
    onDismiss: () -> Unit
) {
    var notes         by remember { mutableStateOf(record.notes) }
    var collectorName by remember { mutableStateOf(record.collectorName) }

    AlertDialog(
        onDismissRequest = onDismiss,
        title  = { Text("標本を編集: ${record.specimenId}") },
        text   = {
            Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
                OutlinedTextField(
                    value         = collectorName,
                    onValueChange = { collectorName = it },
                    label         = { Text("採集者名") },
                    leadingIcon   = { Icon(Icons.Default.Person, null) },
                    singleLine    = true,
                    modifier      = Modifier.fillMaxWidth()
                )
                OutlinedTextField(
                    value         = notes,
                    onValueChange = { notes = it },
                    label         = { Text("備考・メモ") },
                    leadingIcon   = { Icon(Icons.Default.Notes, null) },
                    minLines      = 2,
                    maxLines      = 4,
                    modifier      = Modifier.fillMaxWidth()
                )
            }
        },
        confirmButton = {
            TextButton(
                onClick = { onSave(record.copy(notes = notes, collectorName = collectorName)) },
                enabled = collectorName.isNotBlank()
            ) { Text("保存") }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) { Text("キャンセル") }
        }
    )
}

// ─────────────────────────────────────────────────────────────────────────────
// 一括選択操作バー
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun BulkSelectionBar(
    selectedCount: Int,
    totalCount:    Int,
    isExporting:   Boolean,
    onSelectAll:   () -> Unit,
    onDeselectAll: () -> Unit,
    onExport:      () -> Unit
) {
    Surface(
        tonalElevation = 8.dp,
        shadowElevation = 8.dp,
        color = MaterialTheme.colorScheme.surfaceContainer
    ) {
        Column {
            HorizontalDivider()
            Row(
                modifier              = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 12.dp, vertical = 8.dp),
                verticalAlignment     = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.spacedBy(6.dp)
            ) {
                // 全解除
                OutlinedButton(
                    onClick        = onDeselectAll,
                    modifier       = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 6.dp)
                ) {
                    Icon(Icons.Default.Deselect, null, modifier = Modifier.size(16.dp))
                    Spacer(Modifier.width(4.dp))
                    Text("全解除", style = MaterialTheme.typography.labelMedium)
                }

                // 全選択
                OutlinedButton(
                    onClick        = onSelectAll,
                    enabled        = selectedCount < totalCount,
                    modifier       = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 6.dp)
                ) {
                    Icon(Icons.Default.SelectAll, null, modifier = Modifier.size(16.dp))
                    Spacer(Modifier.width(4.dp))
                    Text("全選択", style = MaterialTheme.typography.labelMedium)
                }

                // エクスポートボタン
                Button(
                    onClick        = onExport,
                    enabled        = !isExporting,
                    modifier       = Modifier.weight(1.4f),
                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 6.dp)
                ) {
                    if (isExporting) {
                        CircularProgressIndicator(
                            modifier = Modifier.size(16.dp),
                            color    = MaterialTheme.colorScheme.onPrimary,
                            strokeWidth = 2.dp
                        )
                    } else {
                        Icon(Icons.Default.FileDownload, null, modifier = Modifier.size(16.dp))
                    }
                    Spacer(Modifier.width(4.dp))
                    Text(
                        if (isExporting) "処理中…" else "エクスポート ($selectedCount)",
                        style = MaterialTheme.typography.labelMedium
                    )
                }
            }
        }
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// 一括エクスポートダイアログ
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun BulkExportDialog(
    selectedCount: Int,
    onExport:      (includePhotos: Boolean) -> Unit,
    onDismiss:     () -> Unit
) {
    var includePhotos by remember { mutableStateOf(false) }

    AlertDialog(
        onDismissRequest = onDismiss,
        icon  = { Icon(Icons.Default.FileDownload, null) },
        title = { Text("一括エクスポート") },
        text  = {
            Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
                Text(
                    "${selectedCount} 地点のデータをエクスポートします。",
                    style = MaterialTheme.typography.bodyMedium
                )

                Row(
                    modifier              = Modifier.fillMaxWidth(),
                    verticalAlignment     = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    Column(modifier = Modifier.weight(1f)) {
                        Text("写真を含める", style = MaterialTheme.typography.bodyMedium)
                        Text(
                            "XLSX + 写真を ZIP にまとめて出力",
                            style = MaterialTheme.typography.bodySmall,
                            color = MaterialTheme.colorScheme.outline
                        )
                    }
                    Switch(
                        checked         = includePhotos,
                        onCheckedChange = { includePhotos = it }
                    )
                }

                Surface(
                    shape = MaterialTheme.shapes.small,
                    color = MaterialTheme.colorScheme.surfaceVariant
                ) {
                    Row(
                        modifier              = Modifier.padding(10.dp),
                        horizontalArrangement = Arrangement.spacedBy(8.dp),
                        verticalAlignment     = Alignment.CenterVertically
                    ) {
                        Icon(
                            if (includePhotos) Icons.Default.FolderZip
                            else Icons.Default.TableChart,
                            null,
                            modifier = Modifier.size(20.dp),
                            tint     = MaterialTheme.colorScheme.primary
                        )
                        Column {
                            Text(
                                if (includePhotos) "ZIP (Excel + 写真)" else "Excel (.xlsx)",
                                style      = MaterialTheme.typography.bodySmall,
                                fontWeight = FontWeight.SemiBold
                            )
                            Text(
                                if (includePhotos)
                                    "写真パスはスプレッドシート内の相対パスで記載"
                                else
                                    "全選択地点の標本情報をまとめてスプレッドシートに出力",
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.outline
                            )
                        }
                    }
                }
            }
        },
        confirmButton = {
            Button(onClick = { onExport(includePhotos) }) {
                Icon(Icons.Default.FileDownload, null)
                Spacer(Modifier.width(6.dp))
                Text("エクスポート")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) { Text("キャンセル") }
        }
    )
}

// ─────────────────────────────────────────────────────────────────────────────
// 地点ラベル一括印刷ダイアログ
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun BatchPrintDialog(
    locationId: String,
    onConfirm:  (Int) -> Unit,
    onDismiss:  () -> Unit
) {
    var count by remember { mutableStateOf(1) }

    AlertDialog(
        onDismissRequest = onDismiss,
        title  = { Text("地点ラベル印刷") },
        text   = {
            Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
                Text(
                    "地点ID: $locationId\n標本番号なしのラベルを印刷します。",
                    style = MaterialTheme.typography.bodyMedium
                )
                Text("印刷枚数", style = MaterialTheme.typography.labelMedium)
                Row(
                    verticalAlignment     = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(12.dp)
                ) {
                    IconButton(onClick = { if (count > 1) count-- }, enabled = count > 1) {
                        Icon(Icons.Default.Remove, "減らす")
                    }
                    Text(
                        "${count}枚",
                        style    = MaterialTheme.typography.headlineSmall,
                        modifier = Modifier.widthIn(min = 64.dp),
                        textAlign = androidx.compose.ui.text.style.TextAlign.Center
                    )
                    IconButton(onClick = { if (count < 20) count++ }, enabled = count < 20) {
                        Icon(Icons.Default.Add, "増やす")
                    }
                }
                Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
                    listOf(1, 3, 5, 10).forEach { n ->
                        FilterChip(
                            selected = count == n,
                            onClick  = { count = n },
                            label    = { Text("${n}枚") }
                        )
                    }
                }
            }
        },
        confirmButton = {
            Button(onClick = { onConfirm(count) }) {
                Icon(Icons.Default.Print, null)
                Spacer(Modifier.width(6.dp))
                Text("印刷")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) { Text("キャンセル") }
        }
    )
}
