<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useWipeStore } from '@/stores/wipe'
import { useServerStore } from '@/stores/server'
import { useToastStore } from '@/stores/toast'
import { useApi } from '@/composables/useApi'
import { useThemeGame } from '@/composables/useThemeGame'
import { useGameProfile } from '@/config/gameProfiles'
import { RouterLink } from 'vue-router'
import { safeDate } from '@/utils/formatters'
import Panel from '@/components/ds/data/Panel.vue'
import Button from '@/components/ds/core/Button.vue'
import Badge from '@/components/ds/core/Badge.vue'
import Switch from '@/components/ds/forms/Switch.vue'
import Select from '@/components/ds/forms/Select.vue'
import Alert from '@/components/ds/feedback/Alert.vue'
import EmptyState from '@/components/ds/feedback/EmptyState.vue'

const wipeStore = useWipeStore()
const server = useServerStore()
const toast = useToastStore()
const api = useApi()
const { activeGame } = useThemeGame()
const profile = computed(() => useGameProfile(activeGame.value === 'all' ? 'rust' : activeGame.value))

const triggerType = ref<'map' | 'blueprint' | 'full'>('map')
const selectedProfileId = ref<string>('')
const triggerLoading = ref(false)
const dryRunLoading = ref(false)
const scheduleToggling = ref<string | null>(null)

interface DryRunResult {
  would_delete: string[]
  would_preserve: string[]
  estimated_duration_seconds: number
}

const dryRunResult = ref<DryRunResult | null>(null)

async function triggerWipe() {
  if (!confirm(`Trigger a ${triggerType.value} wipe? This cannot be undone.`)) return
  triggerLoading.value = true
  try {
    await wipeStore.triggerWipe(triggerType.value, selectedProfileId.value)
  } catch (err) {
    toast.error(err instanceof Error ? err.message : 'Failed to trigger wipe')
  } finally {
    triggerLoading.value = false
  }
}

async function triggerDryRun() {
  dryRunLoading.value = true
  dryRunResult.value = null
  try {
    const result = await wipeStore.triggerDryRun(triggerType.value, selectedProfileId.value)
    dryRunResult.value = result
  } catch (err) {
    toast.error(err instanceof Error ? err.message : 'Failed to run dry-run')
  } finally {
    dryRunLoading.value = false
  }
}

async function toggleSchedule(scheduleId: string, currentlyActive: boolean) {
  scheduleToggling.value = scheduleId
  try {
    await api.put(`/wipes/schedules/${scheduleId}`, { is_active: !currentlyActive })
    await wipeStore.fetchSchedules()
    toast.success(`Schedule ${currentlyActive ? 'paused' : 'activated'}`)
  } catch {
    toast.error('Failed to update schedule')
  } finally {
    scheduleToggling.value = null
  }
}

const WIPE_TYPE_OPTIONS_BASE = [
  { value: 'map', label: 'Map' },
  { value: 'full', label: 'Full' },
]
const WIPE_TYPE_OPTIONS_RUST = [
  { value: 'map', label: 'Map' },
  { value: 'blueprint', label: 'Blueprint' },
  { value: 'full', label: 'Full' },
]
const wipeTypeOptions = computed(() =>
  profile.value.mods === 'umod' ? WIPE_TYPE_OPTIONS_RUST : WIPE_TYPE_OPTIONS_BASE
)

function profileOptions() {
  const opts: { value: string; label: string }[] = [{ value: '', label: 'No profile' }]
  for (const p of wipeStore.profiles) {
    opts.push({ value: p.id, label: p.profile_name })
  }
  return opts
}

function wipeTone(status: string): 'online' | 'offline' | 'warn' | 'neutral' {
  if (status === 'success') return 'online'
  if (status === 'failed' || status === 'rolled_back') return 'offline'
  if (status === 'wiping' || status === 'pre_wipe' || status === 'post_wipe') return 'warn'
  return 'neutral'
}

onMounted(async () => {
  await wipeStore.fetchProfiles()
  const first = wipeStore.profiles[0]
  if (first) {
    selectedProfileId.value = first.id
  }
  wipeStore.fetchSchedules()
  wipeStore.fetchHistory()
})
</script>

<template>
  <div class="wipes">
    <!-- Page head -->
    <div class="page__head">
      <div>
        <div class="t-eyebrow">Operations</div>
        <h1 class="page__title">Auto-wiper</h1>
      </div>
      <div class="page__actions">
        <RouterLink to="/wipes/profiles">
          <Button variant="secondary" size="sm" icon="file-text">Profiles</Button>
        </RouterLink>
        <RouterLink to="/wipes/calendar">
          <Button variant="secondary" size="sm" icon="calendar">Calendar</Button>
        </RouterLink>
        <RouterLink to="/wipes/history">
          <Button variant="secondary" size="sm" icon="clock">History</Button>
        </RouterLink>
      </div>
    </div>

    <!-- Manual trigger -->
    <Panel title="Manual wipe" subtitle="Trigger an immediate wipe outside the schedule">
      <div class="trigger-body">
        <Alert
          v-if="wipeStore.profiles.length === 0"
          tone="warn"
          title="No wipe profiles"
        >
          <template #default>
            Create a profile before triggering a wipe.
          </template>
          <template #actions>
            <RouterLink to="/wipes/profiles">
              <Button variant="outline" size="sm" icon="plus">New profile</Button>
            </RouterLink>
          </template>
        </Alert>

        <div class="trigger-row">
          <!-- Wipe type segment -->
          <div class="trigger-field">
            <div class="cc-field__label">Wipe type</div>
            <div class="type-seg">
              <button
                v-for="opt in wipeTypeOptions"
                :key="opt.value"
                type="button"
                class="type-seg__btn"
                :class="triggerType === opt.value && 'type-seg__btn--active'"
                @click="triggerType = opt.value as 'map' | 'blueprint' | 'full'"
              >
                {{ opt.label }}
              </button>
            </div>
          </div>

          <!-- Profile select -->
          <Select
            label="Profile"
            :options="profileOptions()"
            :disabled="wipeStore.profiles.length === 0"
            :model-value="selectedProfileId"
            @update:model-value="selectedProfileId = $event ?? ''"
          />

          <div class="trigger-actions">
            <Button
              variant="secondary"
              size="md"
              icon="flask-conical"
              :loading="dryRunLoading"
              :disabled="wipeStore.profiles.length === 0"
              @click="triggerDryRun"
            >
              Dry run
            </Button>
            <Button
              variant="danger"
              size="md"
              icon="zap"
              :loading="triggerLoading"
              :disabled="triggerLoading || wipeStore.profiles.length === 0 || server.connection?.connection_status !== 'connected'"
              @click="triggerWipe"
            >
              Trigger wipe
            </Button>
          </div>
        </div>
      </div>
    </Panel>

    <!-- Dry-run results -->
    <Panel
      v-if="dryRunResult"
      title="Dry-run results"
      :subtitle="`Estimated duration: ${Math.round(dryRunResult.estimated_duration_seconds)}s`"
    >
      <template #actions>
        <Button variant="ghost" size="sm" icon="x" @click="dryRunResult = null">Dismiss</Button>
      </template>
      <div class="dry-run-grid">
        <div>
          <div class="dry-run__head dry-run__head--delete">
            Would delete ({{ dryRunResult.would_delete.length }})
          </div>
          <div v-if="dryRunResult.would_delete.length === 0" class="dry-run__empty">
            Nothing to delete
          </div>
          <ul v-else class="dry-run__list">
            <li
              v-for="item in dryRunResult.would_delete"
              :key="item"
              class="dry-run__item dry-run__item--delete"
            >{{ item }}</li>
          </ul>
        </div>
        <div>
          <div class="dry-run__head dry-run__head--keep">
            Would preserve ({{ dryRunResult.would_preserve.length }})
          </div>
          <div v-if="dryRunResult.would_preserve.length === 0" class="dry-run__empty">
            Nothing preserved
          </div>
          <ul v-else class="dry-run__list">
            <li
              v-for="item in dryRunResult.would_preserve"
              :key="item"
              class="dry-run__item dry-run__item--keep"
            >{{ item }}</li>
          </ul>
        </div>
      </div>
    </Panel>

    <!-- Scheduled wipes -->
    <Panel title="Scheduled wipes" subtitle="Active cron schedules">
      <EmptyState
        v-if="wipeStore.schedules.length === 0"
        icon="calendar-clock"
        title="No schedules"
        description="Create a profile and schedule to automate wipes."
      />
      <div v-else class="sched-list">
        <div
          v-for="schedule in wipeStore.schedules"
          :key="schedule.id"
          class="sched-row"
        >
          <div class="sched-info">
            <div class="sched-name">{{ schedule.schedule_name }}</div>
            <div class="sched-meta">
              {{ schedule.wipe_type }} wipe
              &middot;
              <span class="mono">{{ schedule.cron_expression }}</span>
              &middot; {{ schedule.timezone }}
            </div>
          </div>
          <div class="sched-controls">
            <Badge :tone="schedule.is_active ? 'online' : 'neutral'">
              {{ schedule.is_active ? 'Active' : 'Paused' }}
            </Badge>
            <Switch
              :model-value="schedule.is_active"
              :disabled="scheduleToggling === schedule.id"
              @update:model-value="toggleSchedule(schedule.id, schedule.is_active)"
            />
          </div>
        </div>
      </div>
    </Panel>

    <!-- Recent history -->
    <Panel :flush-body="true" title="Recent wipes">
      <template #actions>
        <RouterLink to="/wipes/history">
          <Button variant="ghost" size="sm">View all</Button>
        </RouterLink>
      </template>

      <EmptyState
        v-if="wipeStore.history.length === 0"
        icon="trash-2"
        title="No wipe history"
        description="Wipes will appear here once they run."
      />

      <table v-else class="cc-table">
        <thead>
          <tr>
            <th>Type</th>
            <th>Trigger</th>
            <th>Started</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          <tr
            v-for="wipe in wipeStore.history.slice(0, 5)"
            :key="wipe.id"
          >
            <td class="td-primary">{{ wipe.wipe_type }} wipe</td>
            <td>{{ wipe.trigger_type }}</td>
            <td class="td-mono">{{ safeDate(wipe.started_at, 'Pending') }}</td>
            <td>
              <Badge :tone="wipeTone(wipe.status)">{{ wipe.status }}</Badge>
            </td>
          </tr>
        </tbody>
      </table>
    </Panel>
  </div>
</template>

<style scoped>
.wipes {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Page head */
.page__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.page__title {
  font-size: var(--text-3xl);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin-top: 4px;
}
.page__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.page__actions a { text-decoration: none; }

/* Trigger body */
.trigger-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.trigger-row {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
}
.trigger-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.trigger-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

/* Wipe type segment */
.type-seg {
  display: flex;
  background: var(--surface-inset);
  border-radius: var(--radius-md);
  box-shadow: var(--ring-default);
  overflow: hidden;
}
.type-seg__btn {
  height: var(--control-h-md);
  padding: 0 14px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: var(--transition-colors);
}
.type-seg__btn:hover { color: var(--text-primary); background: var(--surface-hover); }
.type-seg__btn--active {
  background: var(--accent-soft);
  color: var(--accent-text);
  box-shadow: inset 0 0 0 1px var(--accent-border);
}

/* Dry-run results */
.dry-run-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.dry-run__head {
  font-size: var(--text-xs);
  font-weight: 600;
  margin-bottom: 8px;
}
.dry-run__head--delete { color: var(--status-offline); }
.dry-run__head--keep { color: var(--status-online); }
.dry-run__empty {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
}
.dry-run__list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  list-style: none;
  padding: 0;
  margin: 0;
}
.dry-run__item {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  padding: 4px 8px;
  border-radius: var(--radius-sm);
}
.dry-run__item--delete {
  background: var(--status-offline-soft);
  color: var(--text-secondary);
  box-shadow: inset 0 0 0 1px var(--status-offline-border);
}
.dry-run__item--keep {
  background: var(--status-online-soft);
  color: var(--text-secondary);
  box-shadow: inset 0 0 0 1px var(--status-online-border);
}

/* Schedule list */
.sched-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.sched-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--border-subtle);
}
.sched-row:last-child { border-bottom: 0; }
.sched-info { flex: 1; min-width: 0; }
.sched-name {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-primary);
}
.sched-meta {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  margin-top: 2px;
}
.sched-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}
.mono { font-family: var(--font-mono); }

/* Table */
.cc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.cc-table thead tr {
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-inset);
}
.cc-table th {
  padding: 10px 16px;
  text-align: left;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-tertiary);
  white-space: nowrap;
}
.cc-table tbody tr {
  border-bottom: 1px solid var(--border-subtle);
  transition: var(--transition-colors);
}
.cc-table tbody tr:last-child { border-bottom: 0; }
.cc-table tbody tr:hover { background: var(--surface-hover); }
.cc-table td {
  padding: 11px 16px;
  color: var(--text-secondary);
  vertical-align: middle;
}
.td-primary { color: var(--text-primary); font-weight: 500; }
.td-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

@media (max-width: 768px) {
  .dry-run-grid { grid-template-columns: 1fr; }
  .trigger-row { flex-direction: column; align-items: stretch; }
  .trigger-actions { margin-left: 0; }
}
</style>
