<script setup>
import { ref, onMounted, computed } from 'vue'
import { useTranslation } from 'i18next-vue'
import { useSettings } from '../composables/useSettings.js'
import { useAudioCues } from '../composables/useAudioCues.js'
import { useBackupStatus } from '../composables/useBackupStatus.js'
import { useBackupDownload } from '../composables/useBackupDownload.js'
import { useAppUpdate } from '../composables/useAppUpdate.js'
import { useJsonExport } from '../composables/useJsonExport.js'
import { useJsonImport } from '../composables/useJsonImport.js'
import { suffixRepository } from '../db/repositories/suffixRepository.js'
import { db } from '../db/database.js'
import { formatDateTime } from '../utils/dateFormatter.js'
import ModalDialog from '../components/ModalDialog.vue'
import ExportFilterDialog from '../components/ExportFilterDialog.vue'
import ImportDialog from '../components/ImportDialog.vue'
import CreditsDialog from '../components/CreditsDialog.vue'
import AboutDialog from '../components/AboutDialog.vue'
import CleanJournalDialog from '../components/CleanJournalDialog.vue'

const { t, i18next } = useTranslation()
const { settings, fetchAll, get, set } = useSettings()
const { playBip, playBIP } = useAudioCues()
const { exportByFilter, exportAll } = useJsonExport()
const { loadFile } = useJsonImport()
const { markBackedUp, load: loadBackupStatus } = useBackupStatus()
const { downloadBackup } = useBackupDownload()
const { needRefresh, checkingForUpdate, checkForUpdate } = useAppUpdate()

const userName = ref('')
const userUuid = ref('')
const language = ref('en')
const theme = ref('light')
const audioVolume = ref(50)
const voiceEnabled = ref(true)
const nameError = ref('')
const restoring = ref(false)
const restoreReport = ref(null)
const showInitializeDialog = ref(false)
const showCreditsDialog = ref(false)
const showAboutDialog = ref(false)
const showCleanJournalDialog = ref(false)
const initializeConfirmed = ref(false)
const initializing = ref(false)

// App update check
const showUpToDate = ref(false)
let upToDateTimer = null
let hideUpToDateTimer = null
const lastUpdateCheckAtRaw = ref(null)

const lastUpdateCheckDisplay = computed(() => {
  if (!lastUpdateCheckAtRaw.value) return ''
  return formatDateTime(lastUpdateCheckAtRaw.value, language.value)
})

// Backup reminder
const lastBackupAtRaw = ref(null)
const backupReminderDays = ref('7')
const backupReminderDaysError = ref('')

const lastBackupDisplay = computed(() => {
  if (!lastBackupAtRaw.value) return ''
  return formatDateTime(lastBackupAtRaw.value, language.value)
})

// Export/Import
const showExportFilter = ref(false)
const showImportDialog = ref(false)
const importEnvelope = ref(null)
const importAsMine = ref(false)

// Suffix management
const suffixes = ref([])
const editingSuffix = ref(null)
const editSuffixValue = ref('')
const editSuffixError = ref('')
const pendingDeleteSuffix = ref(null)

onMounted(async () => {
  await fetchAll()
  userName.value = settings.value.user_name || ''
  userUuid.value = settings.value.user_uuid || ''
  language.value = settings.value.language || 'en'
  theme.value = settings.value.theme || 'light'
  const volumeStr = await get('audio_volume')
  const parsed = parseInt(volumeStr, 10)
  audioVolume.value = isNaN(parsed) ? 50 : parsed
  const voiceStr = await get('voice_enabled')
  voiceEnabled.value = voiceStr === null ? true : voiceStr === 'true'
  const lastUpdateCheckStr = await get('last_update_check_at')
  lastUpdateCheckAtRaw.value = lastUpdateCheckStr ? new Date(lastUpdateCheckStr) : null
  await loadSuffixes()
  await loadBackupInfo()
  await loadBackupStatus()
})

async function onLanguageChange() {
  const lang = language.value
  await set('language', lang)
  i18next.changeLanguage(lang)
}

async function onNameBlur() {
  const trimmed = userName.value.trim()
  if (!trimmed) {
    nameError.value = t('settings.nameRequired')
    return
  }
  nameError.value = ''
  userName.value = trimmed
  await set('user_name', trimmed)
}

async function onThemeChange() {
  const newTheme = theme.value
  await set('theme', newTheme)
  document.documentElement.setAttribute('data-theme', newTheme)
}

async function onVolumeChange() {
  await set('audio_volume', String(audioVolume.value))
}

async function onVoiceEnabledChange() {
  await set('voice_enabled', String(voiceEnabled.value))
}

async function onCheckForUpdate() {
  clearTimeout(upToDateTimer)
  clearTimeout(hideUpToDateTimer)
  showUpToDate.value = false
  await checkForUpdate()
  const now = new Date()
  await set('last_update_check_at', now.toISOString())
  lastUpdateCheckAtRaw.value = now
  // There is no "no update found" event from the SW API, so fall back to a
  // timeout: if the update prompt hasn't appeared shortly after the check,
  // tell the user they're up to date.
  upToDateTimer = setTimeout(() => {
    if (!needRefresh.value) {
      showUpToDate.value = true
      hideUpToDateTimer = setTimeout(() => {
        showUpToDate.value = false
      }, 3000)
    }
  }, 2000)
}

function onSoundTest() {
  const vol = audioVolume.value / 100
  playBip(vol)
  setTimeout(() => playBIP(vol), 300)
}

async function downloadDatabase() {
  await downloadBackup()
  await loadBackupInfo()
}

function restoreDatabase() {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.sqlite3,.db'

  input.onchange = async (e) => {
    const file = e.target.files[0]
    if (!file) return

    const confirmed = window.confirm(t('settings.restoreDbWarning', { version: __APP_VERSION__ }))
    if (!confirmed) return

    restoring.value = true
    restoreReport.value = null

    try {
      const bytes = await file.arrayBuffer()
      const report = await db.importDatabase(new Uint8Array(bytes))
      restoreReport.value = report

      if (report.success) {
        // Re-fetch settings to reflect restored data
        await fetchAll()
        userName.value = settings.value.user_name || ''
        userUuid.value = settings.value.user_uuid || ''
        language.value = settings.value.language || 'en'
        theme.value = settings.value.theme || 'light'
        // Apply restored language and theme
        i18next.changeLanguage(language.value)
        document.documentElement.setAttribute('data-theme', theme.value)
        // Update backup timestamp
        await markBackedUp()
        await loadBackupInfo()
      }
    } catch (err) {
      restoreReport.value = { success: false, error: 'UNEXPECTED', message: err.message }
    } finally {
      restoring.value = false
    }
  }

  input.click()
}

function dismissReport() {
  restoreReport.value = null
}

function openInitializeDialog() {
  showInitializeDialog.value = true
  initializeConfirmed.value = false
}

function cancelInitialize() {
  showInitializeDialog.value = false
  initializeConfirmed.value = false
}

async function confirmInitialize() {
  if (!initializeConfirmed.value) return
  initializing.value = true
  try {
    await db.resetDatabase()
    window.location.reload()
  } catch (err) {
    console.error('Failed to reset database:', err)
    window.alert(t('error.dbInitFailed'))
  } finally {
    initializing.value = false
  }
}

// --- Export / Import ---

async function onExportAll() {
  await exportAll()
}

function onExportData() {
  showExportFilter.value = true
}

async function onExportConfirm(filters) {
  showExportFilter.value = false
  await exportByFilter(filters)
}

async function onImportData(asMine = false) {
  const result = await loadFile()
  if (result.cancelled) return
  if (result.error) {
    window.alert(t(result.error))
    return
  }
  importEnvelope.value = result.envelope
  importAsMine.value = asMine
  showImportDialog.value = true
}

function onImportDone() {
  showImportDialog.value = false
  importEnvelope.value = null
  importAsMine.value = false
}

function onImportClose() {
  showImportDialog.value = false
  importEnvelope.value = null
  importAsMine.value = false
}

// --- Suffix management ---

async function loadSuffixes() {
  suffixes.value = await suffixRepository.getAll()
}

function startEditSuffix(entry) {
  editingSuffix.value = entry.user_uuid
  editSuffixValue.value = entry.suffix
  editSuffixError.value = ''
}

function cancelEditSuffix() {
  editingSuffix.value = null
  editSuffixValue.value = ''
  editSuffixError.value = ''
}

async function saveEditSuffix(entry) {
  const trimmed = editSuffixValue.value.trim()
  if (!trimmed) {
    editSuffixError.value = t('import.suffixRequired')
    return
  }
  if (trimmed === entry.suffix) {
    cancelEditSuffix()
    return
  }

  // Check uniqueness
  const existing = await suffixRepository.getBySuffix(trimmed)
  if (existing && existing.user_uuid !== entry.user_uuid) {
    editSuffixError.value = t('import.suffixTaken')
    return
  }

  try {
    await suffixRepository.renameSuffix(entry.user_uuid, trimmed)
    await loadSuffixes()
    cancelEditSuffix()
  } catch (e) {
    console.error('Suffix rename failed:', e)
    editSuffixError.value = t('import.suffixRenameFailed')
  }
}

async function deleteSuffix(entry) {
  pendingDeleteSuffix.value = entry
}

async function confirmDeleteSuffix() {
  const entry = pendingDeleteSuffix.value
  if (!entry) return
  await suffixRepository.delete(entry.user_uuid)
  pendingDeleteSuffix.value = null
  await loadSuffixes()
}

function cancelDeleteSuffix() {
  pendingDeleteSuffix.value = null
}

// -- backup DB

async function loadBackupInfo() {
  const lastBackupAtStr = await get('last_backup_at')
  if (lastBackupAtStr) {
    lastBackupAtRaw.value = new Date(lastBackupAtStr)
  } else {
    lastBackupAtRaw.value = null
  }

  const daysStr = await get('backup_reminder_days')
  if (daysStr !== null && daysStr !== undefined) {
    backupReminderDays.value = daysStr
  } else {
    backupReminderDays.value = '7'
  }
}

async function onBackupReminderDaysChange() {
  const trimmed = String(backupReminderDays.value).trim()
  const parsed = parseInt(trimmed, 10)
  if (isNaN(parsed) || parsed < 1 || parsed > 365) {
    backupReminderDaysError.value = t('settings.backupReminderInvalid')
    return
  }
  backupReminderDaysError.value = ''
  backupReminderDays.value = String(parsed)
  await set('backup_reminder_days', String(parsed))
  await loadBackupStatus()
}
</script>

<template>
  <div class="settings-view">
    <!-- Language -->
    <div class="card setting-card">
      <label class="setting-label" for="settings-language">
        <i class="bi bi-translate"></i>
        {{ $t('settings.language') }}
      </label>
      <select
        id="settings-language"
        v-model="language"
        data-testid="settings-language"
        @change="onLanguageChange"
      >
        <option value="en">English</option>
        <option value="fr">Français</option>
        <option value="da">Dansk</option>
      </select>
    </div>

    <!-- User Name -->
    <div class="card setting-card">
      <label class="setting-label" for="settings-username">
        <i class="bi bi-person"></i>
        {{ $t('settings.userName') }}
      </label>
      <input
        id="settings-username"
        v-model="userName"
        data-testid="settings-username"
        type="text"
        :placeholder="$t('settings.userNamePlaceholder')"
        @blur="onNameBlur"
        @keyup.enter="onNameBlur"
      />
      <p v-if="nameError" class="field-error" data-testid="settings-name-error">{{ nameError }}</p>
    </div>

    <!-- UUID -->
    <div class="card setting-card">
      <label class="setting-label" for="settings-uuid">
        <i class="bi bi-fingerprint"></i>
        {{ $t('settings.userId') }}
      </label>
      <input
        id="settings-uuid"
        data-testid="settings-uuid"
        type="text"
        :value="userUuid"
        readonly
        class="input-readonly"
      />
    </div>

    <!-- Theme -->
    <div class="card setting-card">
      <label class="setting-label" for="settings-theme">
        <i class="bi bi-palette"></i>
        {{ $t('settings.theme') }}
      </label>
      <select
        id="settings-theme"
        v-model="theme"
        data-testid="settings-theme"
        @change="onThemeChange"
      >
        <option value="light">{{ $t('settings.themeLight') }}</option>
        <option value="dark">{{ $t('settings.themeDark') }}</option>
        <option value="trainus">{{ $t('settings.themeTrainus') }}</option>
      </select>
    </div>

    <!-- Sound -->
    <div class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-volume-up"></i>
        {{ $t('settings.sound') }}
      </label>
      <div class="sound-row">
        <label class="sound-volume-label" for="settings-volume">{{
          $t('settings.soundVolume')
        }}</label>
        <input
          id="settings-volume"
          v-model.number="audioVolume"
          data-testid="settings-volume"
          type="range"
          min="0"
          max="100"
          step="1"
          class="volume-slider"
          @change="onVolumeChange"
        />
        <span class="volume-value" data-testid="settings-volume-value">{{ audioVolume }}%</span>
        <button class="btn btn-primary" data-testid="settings-sound-test" @click="onSoundTest">
          <i class="bi bi-play-fill"></i>
          {{ $t('settings.soundTest') }}
        </button>
      </div>
      <label class="checkbox-label" data-testid="settings-voice-enabled-label">
        <input
          v-model="voiceEnabled"
          type="checkbox"
          data-testid="settings-voice-enabled"
          @change="onVoiceEnabledChange"
        />
        <span>{{ $t('settings.voiceAnnouncements') }}</span>
      </label>
    </div>

    <!-- Restore overlay (spinner) -->
    <div v-if="restoring" class="restore-overlay" data-testid="restore-spinner">
      <div class="restore-spinner">
        <i class="bi bi-arrow-repeat spin"></i>
        <p>{{ $t('settings.restoreInProgress') }}</p>
      </div>
    </div>

    <!-- Restore report -->
    <div v-if="restoreReport" class="card setting-card restore-report" data-testid="restore-report">
      <div :class="['report-header', restoreReport.success ? 'report-success' : 'report-error']">
        <i :class="restoreReport.success ? 'bi bi-check-circle' : 'bi bi-exclamation-triangle'"></i>
        <strong>{{
          restoreReport.success ? $t('settings.restoreSuccess') : $t('settings.restoreError')
        }}</strong>
      </div>
      <div class="report-body">
        <template v-if="restoreReport.success">
          <p v-if="restoreReport.adapted" data-testid="restore-adapted">
            <i class="bi bi-arrow-left-right"></i>
            {{
              $t('settings.restoreAdapted', {
                from: restoreReport.importedVersion,
                to: restoreReport.currentVersion,
              })
            }}
          </p>
          <ul class="report-tables">
            <li v-for="row in restoreReport.tablesRestored" :key="row.table">
              <strong>{{ row.table }}</strong
              >: {{ row.rows }} {{ $t('settings.restoreRows') }}
            </li>
          </ul>
        </template>
        <template v-else>
          <p data-testid="restore-error-message">
            {{
              $t('settings.restoreErrorCodes.' + restoreReport.error, {
                defaultValue: restoreReport.message,
              })
            }}
          </p>
        </template>
      </div>
      <button class="btn btn-primary" data-testid="restore-report-dismiss" @click="dismissReport">
        {{ $t('settings.restoreDismiss') }}
      </button>
    </div>

    <!-- Download / Restore Database -->
    <div id="settings-backup-section" class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-database-down"></i>
        {{ $t('settings.database') }}
      </label>
      <div class="export-import-buttons">
        <button
          class="btn btn-primary flex-fill"
          data-testid="settings-download-db"
          @click="downloadDatabase"
        >
          <i class="bi bi-download"></i>
          {{ $t('settings.downloadDb') }}
        </button>
        <button
          class="btn btn-danger flex-fill"
          data-testid="settings-restore-db"
          :disabled="restoring"
          @click="restoreDatabase"
        >
          <i class="bi bi-upload"></i>
          {{ $t('settings.restoreDb') }}
        </button>
      </div>
      <div class="export-import-buttons initialize-db-row">
        <button
          class="btn btn-danger"
          data-testid="settings-initialize-db"
          :disabled="initializing"
          @click="openInitializeDialog"
        >
          <i class="bi bi-arrow-counterclockwise"></i>
          {{ $t('settings.initializeDb') }}
        </button>
      </div>
      <p class="text-muted">{{ $t('settings.downloadDbHint') }}</p>
      <div class="backup-info">
        <p class="backup-last-backup" data-testid="backup-last-backup">
          <i class="bi bi-clock"></i>
          {{
            lastBackupDisplay
              ? $t('settings.backup.lastBackup', { when: lastBackupDisplay })
              : $t('settings.backup.neverBackedUp')
          }}
        </p>
      </div>
      <div class="backup-reminder-setting">
        <label for="backup-reminder-days" class="reminder-label">
          {{ $t('settings.backup.reminderEvery') }}
        </label>
        <input
          id="backup-reminder-days"
          v-model="backupReminderDays"
          data-testid="backup-reminder-days"
          type="text"
          inputmode="numeric"
          pattern="[0-9]*"
          class="reminder-input"
          @blur="onBackupReminderDaysChange"
          @keyup.enter="onBackupReminderDaysChange"
        />
        <span class="reminder-unit">{{ $t('settings.backup.reminderEveryUnit') }}</span>
        <p v-if="backupReminderDaysError" class="field-error" data-testid="backup-reminder-error">
          {{ backupReminderDaysError }}
        </p>
      </div>
    </div>

    <!-- Export / Import -->
    <div class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-box-arrow-up"></i>
        {{ $t('settings.exportImport') }}
      </label>
      <div class="export-import-grid">
        <button class="btn btn-primary" data-testid="settings-export-all" @click="onExportAll">
          <i class="bi bi-download"></i>
          {{ $t('settings.exportAllData') }}
        </button>
        <button class="btn btn-primary" data-testid="settings-export" @click="onExportData">
          <i class="bi bi-filter"></i>
          {{ $t('settings.exportData') }}
        </button>
        <button class="btn btn-primary" data-testid="settings-import" @click="onImportData(false)">
          <i class="bi bi-upload"></i>
          {{ $t('settings.importData') }}
        </button>
        <button
          class="btn btn-primary"
          data-testid="settings-import-as-mine"
          @click="onImportData(true)"
        >
          <i class="bi bi-person-check"></i>
          {{ $t('settings.importAsMine') }}
        </button>
      </div>
    </div>

    <!-- Manage Exercise Logs -->
    <div class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-journal-x"></i>
        {{ $t('settings.manageJournal') }}
      </label>
      <p class="text-muted">{{ $t('settings.manageJournalHint') }}</p>
      <div>
        <button
          class="btn btn-danger"
          data-testid="settings-clean-journal"
          @click="showCleanJournalDialog = true"
        >
          <i class="bi bi-trash"></i>
          {{ $t('settings.cleanJournalBtn') }}
        </button>
      </div>
    </div>

    <!-- Suffix Management -->
    <div v-if="suffixes.length > 0" class="card setting-card" data-testid="suffix-management">
      <label class="setting-label">
        <i class="bi bi-people"></i>
        {{ $t('settings.suffixManagement') }}
      </label>
      <p class="text-muted">{{ $t('settings.suffixHint') }}</p>
      <div
        v-for="entry in suffixes"
        :key="entry.user_uuid"
        class="suffix-entry"
        :data-testid="'suffix-entry-' + entry.user_uuid"
      >
        <div class="suffix-info">
          <strong>{{ entry.user_name }}</strong>
          <template v-if="editingSuffix !== entry.user_uuid">
            <span class="suffix-badge" data-testid="suffix-value">[{{ entry.suffix }}]</span>
          </template>
          <template v-else>
            <input
              v-model="editSuffixValue"
              type="text"
              class="suffix-edit-input"
              data-testid="suffix-edit-input"
              @keyup.enter="saveEditSuffix(entry)"
              @keyup.escape="cancelEditSuffix"
            />
            <p v-if="editSuffixError" class="field-error" data-testid="suffix-edit-error">
              {{ editSuffixError }}
            </p>
          </template>
        </div>
        <div class="suffix-actions">
          <template v-if="editingSuffix !== entry.user_uuid">
            <button
              class="btn btn-sm"
              data-testid="suffix-edit-btn"
              @click="startEditSuffix(entry)"
            >
              <i class="bi bi-pencil"></i>
            </button>
            <button
              class="btn btn-sm btn-danger"
              data-testid="suffix-delete-btn"
              @click="deleteSuffix(entry)"
            >
              <i class="bi bi-trash"></i>
            </button>
          </template>
          <template v-else>
            <button
              class="btn btn-sm btn-primary"
              data-testid="suffix-save-btn"
              @click="saveEditSuffix(entry)"
            >
              <i class="bi bi-check-lg"></i>
            </button>
            <button class="btn btn-sm" data-testid="suffix-cancel-btn" @click="cancelEditSuffix">
              <i class="bi bi-x-lg"></i>
            </button>
          </template>
        </div>
      </div>
    </div>

    <!-- Suffix delete confirmation dialog -->
    <ModalDialog
      v-if="pendingDeleteSuffix"
      :title="$t('settings.suffixDeleteTitle')"
      @close="cancelDeleteSuffix"
    >
      <p>
        {{
          $t('settings.suffixDeleteConfirm', {
            name: pendingDeleteSuffix.user_name,
            suffix: pendingDeleteSuffix.suffix,
          })
        }}
      </p>
      <div class="confirm-actions">
        <button class="btn" data-testid="suffix-delete-cancel" @click="cancelDeleteSuffix">
          {{ $t('import.cancel') }}
        </button>
        <button
          class="btn btn-danger"
          data-testid="suffix-delete-confirm"
          @click="confirmDeleteSuffix"
        >
          <i class="bi bi-trash"></i>
          {{ $t('settings.suffixDeleteTitle') }}
        </button>
      </div>
    </ModalDialog>

    <!-- Initialize DB confirmation dialog -->
    <ModalDialog
      v-if="showInitializeDialog"
      :title="$t('settings.initializeDbTitle')"
      @close="cancelInitialize"
    >
      <p class="initialize-warning">
        <i class="bi bi-exclamation-triangle"></i>
        {{ $t('settings.initializeDbHint') }}
      </p>
      <label class="checkbox-label" data-testid="initialize-confirm-label">
        <input
          v-model="initializeConfirmed"
          type="checkbox"
          data-testid="initialize-confirm-checkbox"
        />
        <span>{{ $t('settings.initializeDbConfirm') }}</span>
      </label>
      <div class="confirm-actions">
        <button class="btn" data-testid="initialize-cancel" @click="cancelInitialize">
          {{ $t('import.cancel') }}
        </button>
        <button
          class="btn btn-danger"
          data-testid="initialize-confirm"
          :disabled="!initializeConfirmed"
          @click="confirmInitialize"
        >
          <i class="bi bi-arrow-counterclockwise"></i>
          {{ $t('settings.initializeDb') }}
        </button>
      </div>
    </ModalDialog>

    <!-- Export filter dialog -->
    <ExportFilterDialog
      v-if="showExportFilter"
      @export="onExportConfirm"
      @close="showExportFilter = false"
    />

    <!-- Import dialog -->
    <ImportDialog
      v-if="showImportDialog && importEnvelope"
      :envelope="importEnvelope"
      :local-uuid="userUuid"
      :as-mine="importAsMine"
      @done="onImportDone"
      @close="onImportClose"
    />

    <!-- Check Updates -->
    <div class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-arrow-repeat"></i>
        {{ $t('settings.checkUpdates') }}
      </label>
      <div>
        <button
          class="btn btn-primary"
          data-testid="settings-check-for-update"
          :disabled="checkingForUpdate"
          @click="onCheckForUpdate"
        >
          <i class="bi bi-arrow-repeat"></i>
          {{ $t('settings.checkForUpdate') }}
        </button>
        <p v-if="showUpToDate" class="text-muted" data-testid="settings-up-to-date">
          {{ $t('settings.upToDate') }}
        </p>
      </div>
      <p class="text-muted" data-testid="settings-last-update-check">
        {{
          lastUpdateCheckDisplay
            ? $t('settings.lastManualCheck', { when: lastUpdateCheckDisplay })
            : $t('settings.neverCheckedManually')
        }}
      </p>
    </div>

    <!-- Credits -->
    <div class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-heart"></i>
        {{ $t('settings.credits') }}
      </label>
      <button class="btn" data-testid="settings-credits" @click="showCreditsDialog = true">
        <i class="bi bi-info-circle"></i>
        {{ $t('credits.title') }}
      </button>
    </div>

    <CreditsDialog v-if="showCreditsDialog" @close="showCreditsDialog = false" />

    <!-- About -->
    <div class="card setting-card">
      <label class="setting-label">
        <i class="bi bi-info-circle"></i>
        {{ $t('about.title') }}
      </label>
      <button class="btn" data-testid="settings-about" @click="showAboutDialog = true">
        <i class="bi bi-info-circle"></i>
        {{ $t('about.title') }}
      </button>
    </div>

    <AboutDialog v-if="showAboutDialog" @close="showAboutDialog = false" />

    <!-- Clean Journal dialog -->
    <CleanJournalDialog
      v-if="showCleanJournalDialog"
      @close="showCleanJournalDialog = false"
      @cleaned="showCleanJournalDialog = false"
    />
  </div>
</template>

<style scoped>
.settings-view {
  max-width: 600px;
}

.setting-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.setting-label {
  font-weight: 600;
  font-size: 15px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.setting-label i {
  font-size: 18px;
}

.field-error {
  color: var(--btn-danger-bg);
  font-size: 13px;
  margin: 0;
}

.input-readonly {
  opacity: 0.7;
  cursor: default;
  background-color: var(--bg-color2);
}

.export-import-buttons {
  display: flex;
  gap: 8px;
}

.export-import-buttons .flex-fill {
  flex: 1;
}

.initialize-db-row {
  margin-top: 8px;
  justify-content: center;
}

.export-import-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.export-import-buttons button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.coming-soon {
  font-size: 13px;
  font-style: italic;
}

/* Restore overlay */
.restore-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.restore-spinner {
  text-align: center;
  color: #fff;
  font-size: 18px;
}

.restore-spinner .spin {
  font-size: 48px;
  display: inline-block;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* Restore report */
.restore-report {
  border-left: 4px solid var(--front-color1);
}

.report-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
}

.report-success {
  color: #28a745;
  border-color: #28a745;
}

.report-success i {
  font-size: 20px;
}

.report-error {
  color: var(--btn-danger-bg);
  border-color: var(--btn-danger-bg);
}

.report-error i {
  font-size: 20px;
}

.report-body {
  font-size: 14px;
}

.report-tables {
  margin: 4px 0;
  padding-left: 20px;
}

.report-tables li {
  margin-bottom: 2px;
}

/* Suffix management */
.suffix-entry {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-color);
}

.suffix-entry:last-child {
  border-bottom: none;
}

.suffix-info {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.suffix-badge {
  font-size: 13px;
  padding: 2px 8px;
  border-radius: 12px;
  background-color: var(--btn-primary-bg);
  color: var(--btn-primary-color);
}

.suffix-edit-input {
  width: 120px;
  font-size: 14px;
  padding: 4px 8px;
}

.suffix-actions {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
  margin-left: 8px;
}

.btn-sm {
  font-size: 12px;
  padding: 4px 10px;
}

.confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border-color);
}

.confirm-actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.initialize-warning {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  color: var(--btn-danger-bg);
  font-size: 14px;
}

.initialize-warning i {
  font-size: 18px;
  flex-shrink: 0;
  margin-top: 2px;
}

.checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 16px;
  font-size: 14px;
  cursor: pointer;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

.checkbox-label input[type='checkbox'] {
  margin-top: 2px;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}

.checkbox-label span {
  flex: 1 1 0;
  min-width: 0;
}

/* Backup section */
.backup-info {
  margin-top: 8px;
}

.backup-last-backup {
  font-size: 14px;
  color: var(--front-color2);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}

.backup-reminder-setting {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

.reminder-label {
  font-size: 14px;
  color: var(--front-color2);
}

.reminder-input {
  width: 60px;
  font-size: 14px;
  padding: 4px 8px;
}

.reminder-unit {
  font-size: 14px;
  color: var(--front-color2);
}

/* Sound section */
.sound-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.sound-volume-label {
  font-size: 14px;
  color: var(--front-color2);
  white-space: nowrap;
}

.volume-slider {
  flex: 1;
  min-width: 80px;
  accent-color: var(--btn-primary-bg);
  outline: none;
}

.volume-value {
  font-size: 14px;
  color: var(--front-color2);
  min-width: 36px;
  text-align: right;
}
</style>
