<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useTimedExecuteStore } from '@/stores/timedexecute'
import { useThemeGame } from '@/composables/useThemeGame'
import { useGameProfile } from '@/config/gameProfiles'

import Panel from '@/components/ds/data/Panel.vue'
import Button from '@/components/ds/core/Button.vue'
import Icon from '@/components/ds/core/Icon.vue'
import Tabs from '@/components/ds/navigation/Tabs.vue'
import Input from '@/components/ds/forms/Input.vue'
import Select from '@/components/ds/forms/Select.vue'
import Switch from '@/components/ds/forms/Switch.vue'
import EmptyState from '@/components/ds/feedback/EmptyState.vue'

const store = useTimedExecuteStore()
const { activeGame } = useThemeGame()
const gameProfile = computed(() => useGameProfile(activeGame.value === 'all' ? 'rust' : activeGame.value))

const activeTab = ref<string>('timed')
const showCreateModal = ref(false)
const showImportModal = ref(false)
const newConfigName = ref('')
const newConfigDesc = ref('')
const importConfigName = ref('')

const tabItems = [
  { value: 'timed', label: 'Timed commands', icon: 'clock' },
  { value: 'realtime', label: 'Real-time', icon: 'settings' },
  { value: 'connect', label: 'On connect', icon: 'user' },
  { value: 'disconnect', label: 'On disconnect', icon: 'user' },
]

onMounted(async () => {
  await store.fetchConfigs()
  if (store.configs.length > 0 && store.configs[0]) {
    await store.loadConfig(store.configs[0].id)
  }
})

// --- Config data helpers ---

function getConfigValue(path: string, defaultValue: any = false): any {
  if (!store.currentConfig?.config_data) return defaultValue
  const parts = path.split('.')
  let current: any = store.currentConfig.config_data
  for (const part of parts) {
    if (current == null || typeof current !== 'object') return defaultValue
    current = current[part]
  }
  return current ?? defaultValue
}

function setConfigValue(path: string, value: any) {
  if (!store.currentConfig) return
  if (!store.currentConfig.config_data) store.currentConfig.config_data = {}
  const parts = path.split('.')
  let current: any = store.currentConfig.config_data
  for (let i = 0; i < parts.length - 1; i++) {
    const part = parts[i]!
    if (current[part] == null || typeof current[part] !== 'object') {
      current[part] = {}
    }
    current = current[part]
  }
  current[parts[parts.length - 1]!] = value
  store.markDirty()
}

// --- TimerRepeat helpers ---

const timerRepeatEntries = computed(() => {
  const obj = getConfigValue('TimerRepeat', {}) as Record<string, number>
  return Object.entries(obj).map(([command, interval]) => ({ command, interval }))
})

function addTimerRepeat() {
  const obj = { ...getConfigValue('TimerRepeat', {}) as Record<string, number> }
  obj['new.command'] = 300
  setConfigValue('TimerRepeat', obj)
}

function updateTimerRepeatCommand(oldCmd: string, newCmd: string) {
  const obj = { ...getConfigValue('TimerRepeat', {}) as Record<string, number> }
  const interval = obj[oldCmd] ?? 300
  delete obj[oldCmd]
  obj[newCmd] = interval
  setConfigValue('TimerRepeat', obj)
}

function updateTimerRepeatInterval(cmd: string, interval: number) {
  const obj = { ...getConfigValue('TimerRepeat', {}) as Record<string, number> }
  obj[cmd] = interval
  setConfigValue('TimerRepeat', obj)
}

function removeTimerRepeat(cmd: string) {
  const obj = { ...getConfigValue('TimerRepeat', {}) as Record<string, number> }
  delete obj[cmd]
  setConfigValue('TimerRepeat', obj)
}

function addPresetTimer(command: string, interval: number) {
  const obj = { ...getConfigValue('TimerRepeat', {}) as Record<string, number> }
  obj[command] = interval
  setConfigValue('TimerRepeat', obj)
}

// --- RealTime-Timer helpers ---

const realTimeEntries = computed(() => {
  const obj = getConfigValue('RealTime-Timer', {}) as Record<string, string>
  return Object.entries(obj).map(([time, command]) => ({ time, command }))
})

function addRealTimeEntry() {
  const obj = { ...getConfigValue('RealTime-Timer', {}) as Record<string, string> }
  obj['12:00:00'] = 'say Scheduled message'
  setConfigValue('RealTime-Timer', obj)
}

function updateRealTimeTime(oldTime: string, newTime: string) {
  const obj = { ...getConfigValue('RealTime-Timer', {}) as Record<string, string> }
  const command = obj[oldTime] ?? ''
  delete obj[oldTime]
  obj[newTime] = command
  setConfigValue('RealTime-Timer', obj)
}

function updateRealTimeCommand(time: string, command: string) {
  const obj = { ...getConfigValue('RealTime-Timer', {}) as Record<string, string> }
  obj[time] = command
  setConfigValue('RealTime-Timer', obj)
}

function removeRealTimeEntry(time: string) {
  const obj = { ...getConfigValue('RealTime-Timer', {}) as Record<string, string> }
  delete obj[time]
  setConfigValue('RealTime-Timer', obj)
}

// --- OnPlayerConnected helpers ---

const connectCommands = computed(() => {
  return (getConfigValue('OnPlayerConnectCommands', []) as string[])
})

function addConnectCommand() {
  const cmds = [...connectCommands.value, '']
  setConfigValue('OnPlayerConnectCommands', cmds)
}

function updateConnectCommand(index: number, value: string) {
  const cmds = [...connectCommands.value]
  cmds[index] = value
  setConfigValue('OnPlayerConnectCommands', cmds)
}

function removeConnectCommand(index: number) {
  const cmds = [...connectCommands.value]
  cmds.splice(index, 1)
  setConfigValue('OnPlayerConnectCommands', cmds)
}

// --- OnPlayerDisconnected helpers ---

const disconnectCommands = computed(() => {
  return (getConfigValue('OnPlayerDisconnectCommands', []) as string[])
})

function addDisconnectCommand() {
  const cmds = [...disconnectCommands.value, '']
  setConfigValue('OnPlayerDisconnectCommands', cmds)
}

function updateDisconnectCommand(index: number, value: string) {
  const cmds = [...disconnectCommands.value]
  cmds[index] = value
  setConfigValue('OnPlayerDisconnectCommands', cmds)
}

function removeDisconnectCommand(index: number) {
  const cmds = [...disconnectCommands.value]
  cmds.splice(index, 1)
  setConfigValue('OnPlayerDisconnectCommands', cmds)
}

// --- Action handlers ---

async function handleConfigChange(id: string) {
  if (store.isDirty) {
    if (!confirm('Unsaved changes will be lost. Continue?')) return
  }
  await store.loadConfig(id)
}

async function handleCreateConfig() {
  if (!newConfigName.value.trim()) return
  const config = await store.createConfig(
    newConfigName.value.trim(),
    newConfigDesc.value.trim() || undefined,
  )
  if (config) {
    showCreateModal.value = false
    newConfigName.value = ''
    newConfigDesc.value = ''
  }
}

async function handleDeleteConfig() {
  if (!store.currentConfig) return
  if (!confirm(`Delete "${store.currentConfig.config_name}"? This cannot be undone.`)) return
  await store.deleteConfig(store.currentConfig.id)
}

async function handleApply() {
  if (!store.currentConfig) return
  if (!confirm('Apply this TimedExecute config to the server? This will overwrite the current config.')) return
  if (store.isDirty) {
    await store.saveCurrentConfig()
  }
  await store.applyToServer(store.currentConfig.id)
}

async function handleImport() {
  if (!importConfigName.value.trim()) return
  const config = await store.importFromServer(importConfigName.value.trim())
  if (config) {
    showImportModal.value = false
    importConfigName.value = ''
  }
}

// DS Select model
const selectedConfigId = computed<string>({
  get: () => store.currentConfig?.id ?? '',
  set: (v: string | undefined) => { handleConfigChange(v ?? '') },
})
const configSelectOptions = computed(() =>
  store.configs.map(c => ({
    value: c.id,
    label: c.config_name + (c.is_active ? ' (active)' : ''),
  }))
)

// Switch wrappers
const enableTimerRepeat = computed<boolean>({
  get: () => getConfigValue('EnableTimerRepeat', true) as boolean,
  set: (v: boolean) => setConfigValue('EnableTimerRepeat', v),
})
const enableRealTimeTimer = computed<boolean>({
  get: () => getConfigValue('EnableRealTime-Timer', false) as boolean,
  set: (v: boolean) => setConfigValue('EnableRealTime-Timer', v),
})

// Modal bindings
const newConfigNameModel = computed<string>({
  get: () => newConfigName.value,
  set: (v: string | undefined) => { newConfigName.value = v ?? '' },
})
const importConfigNameModel = computed<string>({
  get: () => importConfigName.value,
  set: (v: string | undefined) => { importConfigName.value = v ?? '' },
})
</script>

<template>
  <div class="te">
    <!-- Page head -->
    <div class="te__head">
      <div class="te__head-id">
        <div class="te__head-chip">
          <Icon name="clock" :size="20" :stroke-width="2" />
        </div>
        <div>
          <div class="t-eyebrow">Plugin configuration</div>
          <h1 class="te__title">Timed Execute</h1>
        </div>
      </div>
      <div class="te__head-actions">
        <Button size="sm" icon="plus" @click="showCreateModal = true">New config</Button>
      </div>
    </div>

    <!-- Toolbar panel -->
    <Panel>
      <div class="te__toolbar">
        <Select
          v-if="store.configs.length > 0"
          v-model="selectedConfigId"
          :options="configSelectOptions"
          size="sm"
          style="min-width: 200px"
        />
        <span v-else class="te__no-configs">No configs yet</span>

        <div class="te__toolbar-actions">
          <Button
            size="sm"
            icon="save"
            :loading="store.isSaving"
            :disabled="!store.currentConfig || !store.isDirty || store.isSaving"
            @click="store.saveCurrentConfig()"
          >{{ store.isSaving ? 'Saving…' : 'Save' }}</Button>

          <Button
            size="sm"
            variant="outline"
            icon="play"
            :loading="store.isApplying"
            :disabled="!store.currentConfig || store.isApplying"
            @click="handleApply"
          >{{ store.isApplying ? 'Applying…' : 'Apply to server' }}</Button>

          <Button
            size="sm"
            variant="secondary"
            icon="download"
            @click="showImportModal = true"
          >Import from server</Button>

          <Button
            size="sm"
            variant="danger-soft"
            icon="trash-2"
            :disabled="!store.currentConfig"
            @click="handleDeleteConfig"
          >Delete</Button>
        </div>
      </div>
    </Panel>

    <!-- Loading -->
    <div v-if="store.isLoading" class="te__loading">
      <span class="te__spinner" />
    </div>

    <!-- Empty — no config -->
    <Panel v-else-if="!store.currentConfig">
      <EmptyState
        icon="clock"
        title="No TimedExecute config selected"
        description="Create a new config, import from server, or select one from the dropdown above."
      >
        <template #action>
          <Button icon="plus" @click="showCreateModal = true">Create first config</Button>
        </template>
      </EmptyState>
    </Panel>

    <!-- Config editor -->
    <template v-else>
      <!-- Tab bar -->
      <Tabs v-model="activeTab" :items="tabItems" variant="line" />

      <!-- Timed commands tab -->
      <Panel v-if="activeTab === 'timed'" title="Timer repeat" subtitle="Commands executed repeatedly at set intervals (seconds)">
        <template #actions>
          <Switch v-model="enableTimerRepeat" label="Enabled" size="sm" />
        </template>

        <!-- Preset quick-add -->
        <div class="te__presets">
          <span class="te__presets-label">Quick add:</span>
          <button class="te__preset" @click="addPresetTimer('server.save', 300)">server.save (5 min)</button>
          <button class="te__preset" @click="addPresetTimer('say Server restart warning!', 3600)">Restart warning (1 h)</button>
          <button v-if="gameProfile.mods === 'umod'" class="te__preset" @click="addPresetTimer('oxide.reload *', 7200)">Reload plugins (2 h)</button>
        </div>

        <EmptyState
          v-if="timerRepeatEntries.length === 0"
          icon="clock"
          description="No timed commands configured. Add a command or use a preset above."
        />

        <div v-else class="te__entries">
          <div
            v-for="(entry, index) in timerRepeatEntries"
            :key="index"
            class="te__entry"
          >
            <div class="te__entry-cmd">
              <input
                :value="entry.command"
                @change="updateTimerRepeatCommand(entry.command, ($event.target as HTMLInputElement).value)"
                placeholder="console command"
                class="cc-input-raw te__input-grow"
              />
            </div>
            <div class="te__entry-interval">
              <input
                :value="entry.interval"
                @input="updateTimerRepeatInterval(entry.command, Number(($event.target as HTMLInputElement).value))"
                type="number"
                min="1"
                class="cc-input-raw cc-input-raw--mono te__input-interval"
              />
              <span class="te__unit">sec</span>
            </div>
            <Button variant="danger-soft" size="sm" icon="trash-2" @click="removeTimerRepeat(entry.command)" />
          </div>
        </div>

        <div class="te__add-row">
          <Button variant="secondary" size="sm" icon="plus" @click="addTimerRepeat">Add command</Button>
        </div>
      </Panel>

      <!-- Real-time tab -->
      <Panel v-else-if="activeTab === 'realtime'" title="Real-time timer" subtitle="Commands executed at specific times of day (HH:MM:SS)">
        <template #actions>
          <Switch v-model="enableRealTimeTimer" label="Enabled" size="sm" />
        </template>

        <EmptyState
          v-if="realTimeEntries.length === 0"
          icon="clock"
          description="No real-time commands configured. Add a time-based command below."
        />

        <div v-else class="te__entries">
          <div
            v-for="(entry, index) in realTimeEntries"
            :key="index"
            class="te__entry"
          >
            <input
              :value="entry.time"
              @change="updateRealTimeTime(entry.time, ($event.target as HTMLInputElement).value)"
              placeholder="HH:MM:SS"
              class="cc-input-raw cc-input-raw--mono te__input-time"
            />
            <input
              :value="entry.command"
              @change="updateRealTimeCommand(entry.time, ($event.target as HTMLInputElement).value)"
              placeholder="console command"
              class="cc-input-raw te__input-grow"
            />
            <Button variant="danger-soft" size="sm" icon="trash-2" @click="removeRealTimeEntry(entry.time)" />
          </div>
        </div>

        <div class="te__add-row">
          <Button variant="secondary" size="sm" icon="plus" @click="addRealTimeEntry">Add time entry</Button>
        </div>
      </Panel>

      <!-- On connect tab -->
      <Panel v-else-if="activeTab === 'connect'" title="On player connect" subtitle="Commands executed when a player joins the server">
        <EmptyState
          v-if="connectCommands.length === 0"
          icon="user"
          description="No connect commands configured. Add a command below."
        />

        <div v-else class="te__entries">
          <div
            v-for="(cmd, index) in connectCommands"
            :key="index"
            class="te__entry"
          >
            <input
              :value="cmd"
              @change="updateConnectCommand(index, ($event.target as HTMLInputElement).value)"
              placeholder="e.g. say Welcome {player.name}!"
              class="cc-input-raw te__input-grow"
            />
            <Button variant="danger-soft" size="sm" icon="trash-2" @click="removeConnectCommand(index)" />
          </div>
        </div>

        <div class="te__add-row">
          <Button variant="secondary" size="sm" icon="plus" @click="addConnectCommand">Add command</Button>
        </div>
      </Panel>

      <!-- On disconnect tab -->
      <Panel v-else-if="activeTab === 'disconnect'" title="On player disconnect" subtitle="Commands executed when a player leaves the server">
        <EmptyState
          v-if="disconnectCommands.length === 0"
          icon="user"
          description="No disconnect commands configured. Add a command below."
        />

        <div v-else class="te__entries">
          <div
            v-for="(cmd, index) in disconnectCommands"
            :key="index"
            class="te__entry"
          >
            <input
              :value="cmd"
              @change="updateDisconnectCommand(index, ($event.target as HTMLInputElement).value)"
              placeholder="e.g. say {player.name} has left"
              class="cc-input-raw te__input-grow"
            />
            <Button variant="danger-soft" size="sm" icon="trash-2" @click="removeDisconnectCommand(index)" />
          </div>
        </div>

        <div class="te__add-row">
          <Button variant="secondary" size="sm" icon="plus" @click="addDisconnectCommand">Add command</Button>
        </div>
      </Panel>
    </template>

    <!-- Create config modal -->
    <div v-if="showCreateModal" class="te__modal-backdrop" @click.self="showCreateModal = false">
      <div class="te__modal">
        <div class="te__modal-head">
          <h2 class="te__modal-title">New TimedExecute config</h2>
        </div>
        <div class="te__modal-body">
          <Input
            v-model="newConfigNameModel"
            label="Config name"
            placeholder="e.g. Default Timer Settings"
            @keydown.enter="handleCreateConfig"
          />
          <div class="te__field">
            <span class="te__field-label">Description (optional)</span>
            <textarea
              v-model="newConfigDesc"
              rows="2"
              placeholder="What is this config for?"
              class="cc-textarea"
            />
          </div>
        </div>
        <div class="te__modal-foot">
          <Button variant="ghost" @click="showCreateModal = false">Cancel</Button>
          <Button :disabled="!newConfigName.trim()" @click="handleCreateConfig">Create</Button>
        </div>
      </div>
    </div>

    <!-- Import from server modal -->
    <div v-if="showImportModal" class="te__modal-backdrop" @click.self="showImportModal = false">
      <div class="te__modal">
        <div class="te__modal-head">
          <h2 class="te__modal-title">Import from server</h2>
        </div>
        <div class="te__modal-body">
          <p class="te__modal-desc">Import the current TimedExecute config from your live server. This will create a new config profile.</p>
          <Input
            v-model="importConfigNameModel"
            label="Config name"
            placeholder="e.g. Imported server config"
            @keydown.enter="handleImport"
          />
        </div>
        <div class="te__modal-foot">
          <Button variant="ghost" @click="showImportModal = false">Cancel</Button>
          <Button :disabled="!importConfigName.trim()" @click="handleImport">Import</Button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* ---- Page shell ---- */
.te { max-width: 900px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; }

/* ---- Page head ---- */
.te__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.te__head-id { display: flex; align-items: center; gap: 12px; }
.te__head-chip {
  width: 40px; height: 40px; flex: none; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-border);
}
.te__title {
  font-size: var(--text-2xl); font-weight: 700; letter-spacing: -0.02em;
  color: var(--text-primary); margin-top: 3px;
}
.te__head-actions { display: flex; align-items: center; gap: 8px; }

/* ---- Toolbar ---- */
.te__toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.te__toolbar-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.te__no-configs { font-size: var(--text-sm); color: var(--text-muted); }

/* ---- Loading ---- */
.te__loading { display: flex; justify-content: center; padding: 48px 0; }
.te__spinner {
  width: 28px; height: 28px; border-radius: 50%;
  border: 2px solid var(--accent); border-top-color: transparent;
  animation: te-spin 0.6s linear infinite;
}
@keyframes te-spin { to { transform: rotate(360deg); } }

/* ---- Presets ---- */
.te__presets { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.te__presets-label { font-size: var(--text-xs); color: var(--text-muted); }
.te__preset {
  height: var(--control-h-sm); padding: 0 10px; border: 0; cursor: pointer;
  border-radius: var(--radius-sm); font-size: var(--text-xs); font-family: var(--font-sans);
  font-weight: 500; color: var(--text-secondary);
  background: var(--surface-raised-2); box-shadow: var(--ring-default);
  transition: var(--transition-colors);
}
.te__preset:hover { background: var(--surface-active); color: var(--text-primary); }

/* ---- Entry rows ---- */
.te__entries { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.te__entry {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-radius: var(--radius-md);
  background: var(--surface-raised-2); box-shadow: var(--ring-default);
}
.te__entry-cmd { flex: 1; min-width: 0; }
.te__entry-interval { display: flex; align-items: center; gap: 6px; }
.te__unit { font-size: var(--text-xs); color: var(--text-muted); white-space: nowrap; }

/* ---- Inline raw inputs (entries) ---- */
.cc-input-raw {
  height: var(--control-h-sm); padding: 0 9px;
  background: var(--surface-inset); border: 0; border-radius: var(--radius-sm);
  box-shadow: var(--ring-default); outline: 0;
  font-family: var(--font-sans); font-size: var(--text-sm); color: var(--text-primary);
  transition: var(--transition-colors);
}
.cc-input-raw::placeholder { color: var(--text-muted); }
.cc-input-raw:focus { box-shadow: inset 0 0 0 1px var(--accent), var(--glow-accent-sm); }
.cc-input-raw--mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.te__input-grow { width: 100%; }
.te__input-interval { width: 72px; text-align: right; }
.te__input-time { width: 90px; }

/* ---- Add row ---- */
.te__add-row { padding-top: 2px; }

/* ---- Modal ---- */
.te__modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.6); z-index: 50;
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.te__modal {
  background: var(--surface-base); border-radius: var(--radius-lg); box-shadow: var(--ring-default);
  width: 100%; max-width: 440px; display: flex; flex-direction: column;
}
.te__modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--border-subtle);
}
.te__modal-title { font-size: var(--text-base); font-weight: 600; color: var(--text-primary); }
.te__modal-body { padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.te__modal-desc { font-size: var(--text-sm); color: var(--text-tertiary); line-height: 1.5; }
.te__modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px; border-top: 1px solid var(--border-subtle);
}
.te__field { display: flex; flex-direction: column; gap: 6px; }
.te__field-label { font-size: var(--text-xs); font-weight: 600; color: var(--text-secondary); }

/* ---- Textarea ---- */
.cc-textarea {
  background: var(--surface-inset); border-radius: var(--radius-md); box-shadow: var(--ring-default);
  border: 0; outline: 0; padding: 9px 11px; resize: none; width: 100%;
  font-family: var(--font-sans); font-size: var(--text-sm); color: var(--text-primary);
  transition: var(--transition-colors);
}
.cc-textarea::placeholder { color: var(--text-muted); }
.cc-textarea:focus { box-shadow: inset 0 0 0 1px var(--accent), var(--glow-accent-sm); }
</style>
