package com.fieldlabel.collector.ui.screens

import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
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.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.compose.foundation.text.KeyboardOptions
import com.fieldlabel.collector.ui.viewmodel.SettingsViewModel
import com.fieldlabel.collector.ui.viewmodel.SupportedPrinterModel
import com.fieldlabel.collector.ui.viewmodel.TestPrintState

// ─────────────────────────────────────────────────────────────────────────────
// PrintSettingsScreen
// 上部固定: ラベルプレビュー
// 下部スクロール: 全印刷設定
// ─────────────────────────────────────────────────────────────────────────────

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PrintSettingsScreen(
    onNavigateBack: () -> Unit,
    onNavigateToPrinterScan: () -> Unit,
    viewModel: SettingsViewModel = hiltViewModel()
) {
    val tapeWidthMm        by viewModel.tapeWidthMm       .collectAsState()
    val printerLocalName   by viewModel.printerLocalName  .collectAsState()
    val printerModelKey    by viewModel.printerModelKey   .collectAsState()
    val testPrintState     by viewModel.testPrintState    .collectAsState()
    val printModeImmediate by viewModel.printModeImmediate.collectAsState()
    val labelLayout        by viewModel.labelLayout       .collectAsState()
    val labelLengthMm      by viewModel.labelLengthMm     .collectAsState()
    val labelFontScale     by viewModel.labelFontScale    .collectAsState()
    val labelShowQr        by viewModel.labelShowQr       .collectAsState()
    val labelShowDate      by viewModel.labelShowDate     .collectAsState()
    val labelShowLocation  by viewModel.labelShowLocation .collectAsState()
    val labelShowNotes     by viewModel.labelShowNotes    .collectAsState()
    val labelShowCollector    by viewModel.labelShowCollector   .collectAsState()
    val labelShowCoordinates  by viewModel.labelShowCoordinates .collectAsState()
    val cutMode            by viewModel.cutMode           .collectAsState()
    val labelFontFamily    by viewModel.labelFontFamily   .collectAsState()
    val labelFontBold      by viewModel.labelFontBold     .collectAsState()
    val labelPreviewBitmap by viewModel.labelPreviewBitmap.collectAsState()

    val elemIdScale         by viewModel.elemIdScale        .collectAsState()
    val elemIdWeight        by viewModel.elemIdWeight       .collectAsState()
    val elemDateScale       by viewModel.elemDateScale      .collectAsState()
    val elemDateWeight      by viewModel.elemDateWeight     .collectAsState()
    val elemLocationScale   by viewModel.elemLocationScale  .collectAsState()
    val elemLocationWeight  by viewModel.elemLocationWeight .collectAsState()
    val elemCollectorScale  by viewModel.elemCollectorScale .collectAsState()
    val elemCollectorWeight by viewModel.elemCollectorWeight.collectAsState()
    val elemNotesScale      by viewModel.elemNotesScale     .collectAsState()
    val elemNotesWeight     by viewModel.elemNotesWeight    .collectAsState()
    val elemQrWeight        by viewModel.elemQrWeight       .collectAsState()

    // 設定が変わるたびにプレビューを再生成
    LaunchedEffect(tapeWidthMm, labelLayout, labelLengthMm, labelFontScale,
                   labelFontFamily, labelFontBold,
                   labelShowQr, labelShowDate, labelShowLocation, labelShowNotes,
                   labelShowCollector, labelShowCoordinates,
                   elemIdScale, elemIdWeight, elemDateScale, elemDateWeight,
                   elemLocationScale, elemLocationWeight, elemCollectorScale, elemCollectorWeight,
                   elemNotesScale, elemNotesWeight, elemQrWeight) {
        viewModel.refreshLabelPreview()
    }

    var tapeSel        by remember(tapeWidthMm)    { mutableStateOf(tapeWidthMm) }
    var lengthDraft    by remember(labelLengthMm)  { mutableStateOf(labelLengthMm.toFloat()) }
    var scaleDraft     by remember(labelFontScale) { mutableStateOf(labelFontScale) }
    var customFontDraft by remember(labelFontFamily) { mutableStateOf(labelFontFamily) }
    var expandedElem   by remember { mutableStateOf<String?>(null) }
    var modelMenuExpanded by remember { mutableStateOf(false) }
    var showTestPrintDialog by remember { mutableStateOf(false) }
    var showCustomFont by remember { mutableStateOf(false) }

    val currentModel = SupportedPrinterModel.fromKey(printerModelKey)

    // テスト印刷結果ダイアログ
    val currentTestState = testPrintState
    if (currentTestState is TestPrintState.Success || currentTestState is TestPrintState.Error) {
        val isError = currentTestState is TestPrintState.Error
        val msg = when (currentTestState) {
            is TestPrintState.Success -> currentTestState.message
            is TestPrintState.Error   -> currentTestState.message
            else -> ""
        }
        AlertDialog(
            onDismissRequest = { viewModel.clearTestPrintState() },
            title = { Text(if (isError) "印刷失敗" else "印刷成功") },
            text  = { Text(msg) },
            confirmButton = {
                TextButton(onClick = { viewModel.clearTestPrintState() }) { Text("OK") }
            }
        )
    }

    // テスト印刷プレビューダイアログ
    if (showTestPrintDialog) {
        AlertDialog(
            onDismissRequest = { showTestPrintDialog = false },
            icon  = { Icon(Icons.Default.Print, null) },
            title = { Text("テスト印刷") },
            text  = {
                Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
                    Text("現在の印刷設定でサンプルラベルを印刷します。")
                    // プレビュー
                    val bmp = labelPreviewBitmap
                    if (bmp != null) {
                        Box(
                            modifier = Modifier
                                .fillMaxWidth()
                                .border(1.dp, MaterialTheme.colorScheme.outlineVariant, MaterialTheme.shapes.small)
                                .padding(8.dp),
                            contentAlignment = Alignment.Center
                        ) {
                            Image(
                                bitmap = bmp.asImageBitmap(),
                                contentDescription = "テスト印刷プレビュー",
                                contentScale = ContentScale.Fit,
                                modifier = Modifier.fillMaxWidth().heightIn(min = 40.dp, max = 160.dp)
                            )
                        }
                    }
                    Text(
                        "プリンター: ${printerLocalName.ifBlank { "未接続" }}",
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.outline
                    )
                }
            },
            confirmButton = {
                Button(
                    onClick  = { viewModel.testPrint(); showTestPrintDialog = false },
                    enabled  = printerLocalName.isNotBlank() && currentTestState !is TestPrintState.Printing
                ) {
                    Icon(Icons.Default.Print, null)
                    Spacer(Modifier.width(6.dp))
                    Text("印刷する")
                }
            },
            dismissButton = {
                TextButton(onClick = { showTestPrintDialog = false }) { Text("キャンセル") }
            }
        )
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("印刷設定") },
                navigationIcon = {
                    IconButton(onClick = onNavigateBack) {
                        Icon(Icons.Default.ArrowBack, "戻る")
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
        ) {
            // ── 上部固定：ラベルプレビュー ────────────────────────────────────
            Surface(
                tonalElevation = 2.dp,
                modifier = Modifier.fillMaxWidth()
            ) {
                Column(modifier = Modifier.padding(12.dp)) {
                    Text("ラベルプレビュー",
                        style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.outline)
                    Spacer(Modifier.height(6.dp))
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .border(1.dp, MaterialTheme.colorScheme.outlineVariant, MaterialTheme.shapes.small)
                            .padding(8.dp),
                        contentAlignment = Alignment.Center
                    ) {
                        val bmp = labelPreviewBitmap
                        if (bmp != null) {
                            Image(
                                bitmap = bmp.asImageBitmap(),
                                contentDescription = "ラベルプレビュー",
                                contentScale = ContentScale.Fit,
                                modifier = Modifier.fillMaxWidth().heightIn(min = 60.dp, max = 180.dp)
                            )
                        } else {
                            CircularProgressIndicator(modifier = Modifier.size(32.dp))
                        }
                    }
                    Text(
                        "※ 実際の印刷結果は端末の解像度により異なる場合があります",
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.outline,
                        modifier = Modifier.padding(top = 4.dp)
                    )
                }
            }

            // ── 下部スクロール：各設定 ─────────────────────────────────────────
            Column(
                modifier = Modifier
                    .weight(1f)
                    .verticalScroll(rememberScrollState())
                    .navigationBarsPadding()
                    .imePadding()
                    .padding(start = 16.dp, end = 16.dp, top = 12.dp, bottom = 32.dp),
                verticalArrangement = Arrangement.spacedBy(14.dp)
            ) {

                // ── 印刷モード ────────────────────────────────────────────────
                PrintSection("印刷モード") {
                    Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
                        listOf(
                            false to "あとでまとめて印刷（登録のみ）",
                            true  to "随時印刷（登録と同時に印刷）"
                        ).forEach { (value, label) ->
                            Row(
                                modifier = Modifier.fillMaxWidth()
                                    .clickable { viewModel.savePrintModeImmediate(value) }
                                    .padding(vertical = 6.dp),
                                verticalAlignment = Alignment.CenterVertically
                            ) {
                                RadioButton(selected = printModeImmediate == value,
                                    onClick = { viewModel.savePrintModeImmediate(value) })
                                Spacer(Modifier.width(8.dp))
                                Text(label, style = MaterialTheme.typography.bodyMedium)
                            }
                        }
                    }
                }

                HorizontalDivider()

                // ── プリンター ─────────────────────────────────────────────────
                PrintSection("プリンター") {
                    // モデル警告カード
                    Card(
                        colors = CardDefaults.cardColors(
                            containerColor = MaterialTheme.colorScheme.secondaryContainer),
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        Row(
                            modifier = Modifier.padding(10.dp),
                            horizontalArrangement = Arrangement.spacedBy(8.dp),
                            verticalAlignment = Alignment.Top
                        ) {
                            Icon(Icons.Default.Info, null,
                                modifier = Modifier.size(16.dp).padding(top = 2.dp),
                                tint = MaterialTheme.colorScheme.onSecondaryContainer)
                            Text(
                                "動作確認済みモデル：PT-P910BT（36mm）、PT-P300BT（12mm）。" +
                                "その他のモデルは Bluetooth 接続が確立しても正常に印刷できない場合があります。",
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.onSecondaryContainer
                            )
                        }
                    }

                    Text("プリンターモデル", style = MaterialTheme.typography.labelMedium,
                        color = MaterialTheme.colorScheme.outline)
                    Box {
                        OutlinedButton(onClick = { modelMenuExpanded = true },
                            modifier = Modifier.fillMaxWidth()) {
                            Icon(Icons.Default.Print, null)
                            Spacer(Modifier.width(8.dp))
                            Text(currentModel.displayName, modifier = Modifier.weight(1f))
                            Text("▼", style = MaterialTheme.typography.labelSmall)
                        }
                        DropdownMenu(expanded = modelMenuExpanded,
                            onDismissRequest = { modelMenuExpanded = false },
                            modifier = Modifier.fillMaxWidth(0.9f)) {
                            SupportedPrinterModel.entries.forEach { model ->
                                DropdownMenuItem(
                                    text = {
                                        Row(verticalAlignment = Alignment.CenterVertically,
                                            horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                                            Column(modifier = Modifier.weight(1f)) {
                                                Text(model.displayName, style = MaterialTheme.typography.bodyMedium)
                                                Text("最大テープ幅: ${model.maxTapeMm}mm",
                                                    style = MaterialTheme.typography.bodySmall,
                                                    color = MaterialTheme.colorScheme.outline)
                                            }
                                            if (model == currentModel)
                                                Text("✓", color = MaterialTheme.colorScheme.primary)
                                        }
                                    },
                                    onClick = { viewModel.savePrinterModel(model); modelMenuExpanded = false }
                                )
                            }
                        }
                    }

                    if (printerLocalName.isNotBlank()) {
                        Text("接続先: $printerLocalName",
                            style = MaterialTheme.typography.bodySmall,
                            color = MaterialTheme.colorScheme.outline)
                    }
                    OutlinedButton(onClick = onNavigateToPrinterScan,
                        modifier = Modifier.fillMaxWidth()) {
                        Icon(Icons.Default.Bluetooth, null)
                        Spacer(Modifier.width(8.dp))
                        Text("プリンターをスキャン・接続")
                    }

                    // テスト印刷（プレビューダイアログを経由）
                    Button(
                        onClick  = { showTestPrintDialog = true },
                        enabled  = printerLocalName.isNotBlank() && currentTestState !is TestPrintState.Printing,
                        modifier = Modifier.fillMaxWidth(),
                        colors   = ButtonDefaults.buttonColors(
                            containerColor = MaterialTheme.colorScheme.secondary)
                    ) {
                        if (currentTestState is TestPrintState.Printing) {
                            CircularProgressIndicator(modifier = Modifier.size(18.dp),
                                strokeWidth = 2.dp, color = MaterialTheme.colorScheme.onSecondary)
                            Spacer(Modifier.width(8.dp)); Text("印刷中…")
                        } else {
                            Icon(Icons.Default.Print, null)
                            Spacer(Modifier.width(8.dp))
                            Text("テスト印刷")
                        }
                    }
                    if (printerLocalName.isBlank()) {
                        Text("テスト印刷はプリンターを選択してから使用できます",
                            style = MaterialTheme.typography.bodySmall,
                            color = MaterialTheme.colorScheme.outline)
                    }
                    if (tapeSel > currentModel.maxTapeMm) {
                        Card(colors = CardDefaults.cardColors(
                                containerColor = MaterialTheme.colorScheme.errorContainer),
                            modifier = Modifier.fillMaxWidth()) {
                            Text(
                                "⚠ 選択中のテープ幅 ${tapeSel}mm は ${currentModel.displayName} の最大幅 " +
                                "(${currentModel.maxTapeMm}mm) を超えています。",
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.onErrorContainer,
                                modifier = Modifier.padding(12.dp)
                            )
                        }
                    }
                }

                HorizontalDivider()

                // ── テープ幅 ──────────────────────────────────────────────────
                PrintSection("テープ幅") {
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        listOf(12, 18, 24, 36).forEach { mm ->
                            FilterChip(
                                selected = tapeSel == mm,
                                onClick  = { tapeSel = mm; viewModel.saveTapeWidth(mm) },
                                label    = { Text("${mm}mm") },
                                modifier = Modifier.weight(1f)
                            )
                        }
                    }
                }

                HorizontalDivider()

                // ── カット設定 ─────────────────────────────────────────────────
                PrintSection("カット設定") {
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        listOf("half" to "ハーフカット", "auto" to "オートカット", "none" to "カットなし")
                            .forEach { (mode, label) ->
                                FilterChip(selected = cutMode == mode,
                                    onClick = { viewModel.saveCutMode(mode) },
                                    label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                    modifier = Modifier.weight(1f))
                            }
                    }
                }

                HorizontalDivider()

                // ── ラベルデザイン ─────────────────────────────────────────────
                PrintSection("ラベルデザイン") {

                    // レイアウト選択（オート→シンプル→セクション順）
                    Text("レイアウト", style = MaterialTheme.typography.labelMedium,
                        color = MaterialTheme.colorScheme.outline)

                    // オートレイアウト
                    Text("オート（長さ自動）", style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.outline,
                        modifier = Modifier.padding(top = 2.dp))
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) {
                        listOf("auto_h" to "横型オート", "auto_v" to "縦型オート").forEach { (key, label) ->
                            FilterChip(selected = labelLayout == key,
                                onClick = { viewModel.saveLabelLayout(key) },
                                label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                modifier = Modifier.weight(1f))
                        }
                    }

                    // シンプル
                    Text("シンプル", style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.outline,
                        modifier = Modifier.padding(top = 2.dp))
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) {
                        listOf("simple_h" to "シンプル横", "simple_v" to "シンプル縦").forEach { (key, label) ->
                            FilterChip(selected = labelLayout == key,
                                onClick = { viewModel.saveLabelLayout(key) },
                                label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                modifier = Modifier.weight(1f))
                        }
                    }

                    // セクション分割
                    Text("セクション（横分割）", style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.outline,
                        modifier = Modifier.padding(top = 2.dp))
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) {
                        listOf("column_h" to "セクション横", "column_v" to "セクション縦").forEach { (key, label) ->
                            FilterChip(selected = labelLayout == key,
                                onClick = { viewModel.saveLabelLayout(key) },
                                label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                modifier = Modifier.weight(1f))
                        }
                    }
                    Text("セクション（縦分割）", style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.outline,
                        modifier = Modifier.padding(top = 2.dp))
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) {
                        listOf("row_h" to "行セクション横", "row_v" to "行セクション縦").forEach { (key, label) ->
                            FilterChip(selected = labelLayout == key,
                                onClick = { viewModel.saveLabelLayout(key) },
                                label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                modifier = Modifier.weight(1f))
                        }
                    }

                    // オートレイアウト説明 / 長さスライダー
                    val isAutoLayout = labelLayout == "auto_v" || labelLayout == "auto_h"
                    if (!isAutoLayout) {
                        Spacer(Modifier.height(4.dp))
                        Text("ラベル長さ: ${lengthDraft.toInt()}mm",
                            style = MaterialTheme.typography.labelMedium,
                            color = MaterialTheme.colorScheme.outline)
                        Slider(value = lengthDraft, onValueChange = { lengthDraft = it },
                            onValueChangeFinished = { viewModel.saveLabelLengthMm(lengthDraft.toInt()) },
                            valueRange = 10f..150f, steps = 27, modifier = Modifier.fillMaxWidth())
                    } else {
                        Card(colors = CardDefaults.cardColors(
                                containerColor = MaterialTheme.colorScheme.secondaryContainer),
                            modifier = Modifier.fillMaxWidth()) {
                            Text(
                                when (labelLayout) {
                                    "auto_h" -> "横型オート: ラベル長さが内容に応じて自動計算されます。横向きのまま貼り付けてください。"
                                    else     -> "縦型オート: 長さが自動計算されます。印刷後、テープを90°回転させて縦向きに貼り付けてください。"
                                },
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.onSecondaryContainer,
                                modifier = Modifier.padding(10.dp)
                            )
                        }
                    }

                    // 全体フォントスケール
                    Spacer(Modifier.height(4.dp))
                    Text("全体フォントスケール: ${"%.1f".format(scaleDraft)}x",
                        style = MaterialTheme.typography.labelMedium,
                        color = MaterialTheme.colorScheme.outline)
                    Slider(value = scaleDraft, onValueChange = { scaleDraft = it },
                        onValueChangeFinished = { viewModel.saveLabelFontScale(scaleDraft) },
                        valueRange = 0.1f..2.0f, steps = 38, modifier = Modifier.fillMaxWidth())

                    // フォント選択
                    Text("フォント", style = MaterialTheme.typography.labelMedium,
                        color = MaterialTheme.colorScheme.outline)
                    val builtinFonts = listOf(
                        "" to "デフォルト", "sans-serif" to "Sans-Serif",
                        "sans-serif-condensed" to "Condensed", "sans-serif-medium" to "Medium",
                        "serif" to "Serif", "monospace" to "Monospace"
                    )
                    val isCustomFont = builtinFonts.none { (k, _) -> k == labelFontFamily }
                    Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.fillMaxWidth()) {
                        builtinFonts.take(3).forEach { (key, label) ->
                            FilterChip(selected = labelFontFamily == key && !isCustomFont,
                                onClick = { viewModel.saveLabelFontFamily(key); customFontDraft = key },
                                label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                modifier = Modifier.weight(1f))
                        }
                    }
                    Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.fillMaxWidth()) {
                        builtinFonts.drop(3).forEach { (key, label) ->
                            FilterChip(selected = labelFontFamily == key && !isCustomFont,
                                onClick = { viewModel.saveLabelFontFamily(key); customFontDraft = key },
                                label = { Text(label, style = MaterialTheme.typography.bodySmall) },
                                modifier = Modifier.weight(1f))
                        }
                    }
                    Row(modifier = Modifier.fillMaxWidth().clickable { showCustomFont = !showCustomFont },
                        verticalAlignment = Alignment.CenterVertically) {
                        Text("カスタムフォント名を入力",
                            style = MaterialTheme.typography.bodySmall,
                            color = if (isCustomFont) MaterialTheme.colorScheme.primary
                                    else MaterialTheme.colorScheme.outline,
                            modifier = Modifier.weight(1f))
                        Icon(if (showCustomFont) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
                            null, tint = MaterialTheme.colorScheme.outline)
                    }
                    if (showCustomFont) {
                        OutlinedTextField(value = customFontDraft,
                            onValueChange = { customFontDraft = it },
                            label = { Text("フォントファミリー名") },
                            placeholder = { Text("例: sans-serif-condensed") },
                            singleLine = true, modifier = Modifier.fillMaxWidth(),
                            supportingText = { Text("Android フォントファミリー名を直接入力できます") })
                        Button(onClick = { viewModel.saveLabelFontFamily(customFontDraft) },
                            enabled = customFontDraft != labelFontFamily,
                            modifier = Modifier.fillMaxWidth()) { Text("このフォントを適用") }
                    }

                    // ボールド設定
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.SpaceBetween
                    ) {
                        Column(modifier = Modifier.weight(1f)) {
                            Text("ボールド体",
                                style = MaterialTheme.typography.bodyMedium,
                                fontWeight = FontWeight.Medium)
                            Text("全要素のフォントを太字にします",
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.outline)
                        }
                        Switch(
                            checked = labelFontBold,
                            onCheckedChange = { viewModel.saveLabelFontBold(it) }
                        )
                    }
                }

                HorizontalDivider()

                // ── 表示要素 ──────────────────────────────────────────────────
                PrintSection("表示要素") {

                    @Composable
                    fun ElemOptionsPanel(scale: Float, weight: Float,
                                         onScaleChange: (Float) -> Unit,
                                         onWeightChange: (Float) -> Unit,
                                         showScale: Boolean = true) {
                        Column(modifier = Modifier.fillMaxWidth().padding(start = 16.dp, top = 4.dp, bottom = 4.dp),
                            verticalArrangement = Arrangement.spacedBy(4.dp)) {
                            if (showScale) {
                                var s by remember(scale) { mutableStateOf(scale) }
                                Text("文字サイズ倍率: ${"%.2f".format(s)}x",
                                    style = MaterialTheme.typography.bodySmall,
                                    color = MaterialTheme.colorScheme.outline)
                                Slider(value = s, onValueChange = { s = it },
                                    onValueChangeFinished = { onScaleChange(s) },
                                    valueRange = 0.4f..2.5f, steps = 20, modifier = Modifier.fillMaxWidth())
                            }
                            var wt by remember(weight) { mutableStateOf(weight) }
                            Text("占有幅/高さ調整: ${"%.1f".format(wt)}x",
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.outline)
                            Slider(value = wt, onValueChange = { wt = it },
                                onValueChangeFinished = { onWeightChange(wt) },
                                valueRange = 0.3f..3.0f, steps = 26, modifier = Modifier.fillMaxWidth())
                        }
                    }

                    @Composable
                    fun ElemRow(key: String, label: String, show: Boolean?, onShowChange: ((Boolean) -> Unit)?,
                                 expanded: Boolean, onExpandToggle: () -> Unit) {
                        Row(modifier = Modifier.fillMaxWidth().clickable { onExpandToggle() }.padding(vertical = 6.dp),
                            verticalAlignment = Alignment.CenterVertically) {
                            Text(label, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.weight(1f))
                            if (show != null && onShowChange != null) {
                                Switch(checked = show, onCheckedChange = onShowChange,
                                    modifier = Modifier.padding(end = 4.dp))
                            }
                            Icon(if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
                                null, tint = MaterialTheme.colorScheme.outline)
                        }
                    }

                    // ID（常時表示）
                    ElemRow("id", "ID（標本番号）", null, null,
                        expanded = expandedElem == "id",
                        onExpandToggle = { expandedElem = if (expandedElem == "id") null else "id" })
                    if (expandedElem == "id") ElemOptionsPanel(elemIdScale, elemIdWeight,
                        { viewModel.saveElemIdScale(it) }, { viewModel.saveElemIdWeight(it) })

                    ElemRow("date", "採集日", labelShowDate, { viewModel.saveLabelShowDate(it) },
                        expandedElem == "date", { expandedElem = if (expandedElem == "date") null else "date" })
                    if (expandedElem == "date") ElemOptionsPanel(elemDateScale, elemDateWeight,
                        { viewModel.saveElemDateScale(it) }, { viewModel.saveElemDateWeight(it) })

                    ElemRow("location", "採集地点", labelShowLocation, { viewModel.saveLabelShowLocation(it) },
                        expandedElem == "location", { expandedElem = if (expandedElem == "location") null else "location" })
                    if (expandedElem == "location") ElemOptionsPanel(elemLocationScale, elemLocationWeight,
                        { viewModel.saveElemLocationScale(it) }, { viewModel.saveElemLocationWeight(it) })

                    ElemRow("coords", "座標（緯度・経度）",
                        labelShowCoordinates, { viewModel.saveLabelShowCoordinates(it) },
                        expanded = false, onExpandToggle = {})

                    ElemRow("collector", "採集者名", labelShowCollector, { viewModel.saveLabelShowCollector(it) },
                        expandedElem == "collector", { expandedElem = if (expandedElem == "collector") null else "collector" })
                    if (expandedElem == "collector") ElemOptionsPanel(elemCollectorScale, elemCollectorWeight,
                        { viewModel.saveElemCollectorScale(it) }, { viewModel.saveElemCollectorWeight(it) })

                    ElemRow("notes", "備考", labelShowNotes, { viewModel.saveLabelShowNotes(it) },
                        expandedElem == "notes", { expandedElem = if (expandedElem == "notes") null else "notes" })
                    if (expandedElem == "notes") ElemOptionsPanel(elemNotesScale, elemNotesWeight,
                        { viewModel.saveElemNotesScale(it) }, { viewModel.saveElemNotesWeight(it) })

                    ElemRow("qr", "QRコード", labelShowQr, { viewModel.saveLabelShowQr(it) },
                        expandedElem == "qr", { expandedElem = if (expandedElem == "qr") null else "qr" })
                    if (expandedElem == "qr") ElemOptionsPanel(1.0f, elemQrWeight, {}, { viewModel.saveElemQrWeight(it) },
                        showScale = false)
                }

            }
        }
    }
}

// ─────────────────────────────────────────────────────────────────────────────
// 共通: セクションヘッダ付きラッパー
// ─────────────────────────────────────────────────────────────────────────────
@Composable
private fun PrintSection(title: String, content: @Composable ColumnScope.() -> Unit) {
    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        Text(title, style = MaterialTheme.typography.titleSmall,
            fontWeight = FontWeight.SemiBold,
            color = MaterialTheme.colorScheme.primary)
        content()
    }
}
