<template>
  <div class="cron-page">
    <div class="d-flex align-center justify-space-between mb-4">
      <div>
        <div class="d-flex align-center" style="gap: 8px;">
          <h2 class="text-h5 font-weight-bold">{{ tm('page.title') }}</h2>
          <v-chip size="x-small" color="orange-darken-2" variant="tonal" label>{{ tm('page.beta') }}</v-chip>
        </div>
        <div class="text-body-2 text-medium-emphasis">
          {{ tm('page.subtitle') }}
          <span v-if="proactivePlatforms.length">
            {{ tm('page.proactive.supported', { platforms: proactivePlatformText }) }}
          </span>
          <span v-else>{{ tm('page.proactive.unsupported') }}</span>
        </div>
      </div>
      <div class="d-flex align-center" style="gap: 8px;">
        <v-btn variant="tonal" color="primary" @click="openCreate">{{ tm('actions.create') }}</v-btn>
        <v-btn variant="tonal" color="primary" :loading="loading" @click="loadJobs">{{ tm('actions.refresh') }}</v-btn>
      </div>
    </div>

    <v-card class="rounded-lg" variant="flat">
      <v-card-text>
        <div class="d-flex align-center justify-space-between mb-3">
          <div class="text-subtitle-1 font-weight-bold">{{ tm('table.title') }}</div>
        </div>

        <v-alert v-if="!jobs.length && !loading" type="info" variant="tonal">{{ tm('table.empty') }}</v-alert>

        <v-data-table :items="jobs" :headers="headers" :loading="loading" item-key="job_id" density="comfortable"
          class="elevation-0">
          <template #item.name="{ item }">
            <div class="py-4">
              <div class="font-weight-medium">{{ item.name }}</div>
              <div class="text-caption text-medium-emphasis">{{ item.description }}</div>
            </div>
          </template>
          <template #item.type="{ item }">
            <v-chip size="small" :color="item.run_once ? 'orange' : 'primary'" variant="tonal">
              {{ jobTypeLabel(item) }}
            </v-chip>
          </template>
          <template #item.cron_expression="{ item }">
            <div v-if="item.run_once">{{ formatTime(item.run_at) }}</div>
            <div v-else>
              <div>{{ item.cron_expression || tm('table.notAvailable') }}</div>
              <div class="text-caption text-medium-emphasis">{{ item.timezone || tm('table.timezoneLocal') }}</div>
            </div>
          </template>
          <template #item.session="{ item }">
            <div>{{ item.session || tm('table.notAvailable') }}</div>
          </template>
          <template #item.next_run_time="{ item }">{{ formatTime(item.next_run_time) }}</template>
          <template #item.last_run_at="{ item }">{{ formatTime(item.last_run_at) }}</template>
          <template #item.note="{ item }">{{ item.note || tm('table.notAvailable') }}</template>
          <template #item.actions="{ item }">
            <div class="d-flex align-center flex-nowrap" style="gap: 12px; min-width: 140px;">
              <v-switch v-model="item.enabled" inset density="compact" hide-details color="primary"
                class="mt-0" @change="toggleJob(item)" />
              <v-btn size="small" variant="text" color="error" @click="deleteJob(item)">
                {{ tm('actions.delete') }}
              </v-btn>
            </div>
          </template>
        </v-data-table>
      </v-card-text>
    </v-card>

    <v-snackbar v-model="snackbar.show" :color="snackbar.color" timeout="2600">
      {{ snackbar.message }}
    </v-snackbar>

    <v-dialog v-model="createDialog" max-width="560">
      <v-card>
        <v-card-title class="text-h6">{{ tm('form.title') }}</v-card-title>
        <v-card-subtitle class="text-body-2 text-medium-emphasis">
          {{ tm('form.chatHint') }}
        </v-card-subtitle>
        <v-card-text>
          <v-switch v-model="newJob.run_once" :label="tm('form.runOnce')" inset color="primary" hide-details />
          <v-text-field v-model="newJob.name" :label="tm('form.name')" variant="outlined" density="comfortable" />
          <v-text-field v-model="newJob.note" :label="tm('form.note')" variant="outlined" density="comfortable" />
          <v-text-field v-if="!newJob.run_once" v-model="newJob.cron_expression" :label="tm('form.cron')"
            :placeholder="tm('form.cronPlaceholder')" variant="outlined" density="comfortable" />
          <v-text-field v-else v-model="newJob.run_at" :label="tm('form.runAt')" type="datetime-local"
            variant="outlined" density="comfortable" />
          <v-text-field v-model="newJob.session" :label="tm('form.session')" variant="outlined" density="comfortable" />
          <v-text-field v-model="newJob.timezone" :label="tm('form.timezone')" variant="outlined"
            density="comfortable" />
          <v-switch v-model="newJob.enabled" :label="tm('form.enabled')" inset color="primary" hide-details />
        </v-card-text>
        <v-card-actions class="justify-end">
          <v-btn variant="text" @click="createDialog = false">{{ tm('actions.cancel') }}</v-btn>
          <v-btn variant="tonal" color="primary" :loading="creating" @click="createJob">{{ tm('actions.submit')
            }}</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import axios from 'axios'
import { useModuleI18n } from '@/i18n/composables'

const { tm } = useModuleI18n('features/cron')

const loading = ref(false)
const jobs = ref<any[]>([])
const proactivePlatforms = ref<{ id: string; name: string; display_name?: string }[]>([])
const createDialog = ref(false)
const creating = ref(false)
const newJob = ref({
  run_once: false,
  name: '',
  note: '',
  cron_expression: '',
  run_at: '',
  session: '',
  timezone: '',
  enabled: true
})

const snackbar = ref({ show: false, message: '', color: 'success' })

const proactivePlatformText = computed(() =>
  proactivePlatforms.value.map((p) => `${p.display_name || p.name}(${p.id})`).join(' / ')
)

const headers = computed(() => [
  { title: tm('table.headers.name'), key: 'name', minWidth: '200px' },
  { title: tm('table.headers.type'), key: 'type', width: 110 },
  { title: tm('table.headers.cron'), key: 'cron_expression', minWidth: '160px' },
  { title: tm('table.headers.session'), key: 'session', minWidth: '200px' },
  { title: tm('table.headers.nextRun'), key: 'next_run_time', minWidth: '160px' },
  { title: tm('table.headers.lastRun'), key: 'last_run_at', minWidth: '160px' },
  { title: tm('table.headers.note'), key: 'note', minWidth: '220px' },
  { title: tm('table.headers.actions'), key: 'actions', width: 160, sortable: false }
])

function toast(message: string, color: 'success' | 'error' | 'warning' = 'success') {
  snackbar.value = { show: true, message, color }
}

function formatTime(val: any): string {
  if (!val) return tm('table.notAvailable')
  try {
    return new Date(val).toLocaleString()
  } catch (e) {
    return String(val)
  }
}

function jobTypeLabel(item: any): string {
  if (item.run_once) return tm('table.type.once')
  const type = item.job_type || 'active_agent'
  const map: Record<string, string> = {
    active_agent: tm('table.type.activeAgent'),
    workflow: tm('table.type.workflow')
  }
  return map[type] || tm('table.type.unknown', { type })
}

async function loadJobs() {
  loading.value = true
  try {
    const res = await axios.get('/api/cron/jobs')
    if (res.data.status === 'ok') {
      const data = Array.isArray(res.data.data) ? res.data.data : []
      jobs.value = data.map((job: any) => ({
        ...job,
        session: job?.payload?.session || job?.session || ''
      }))
    } else {
      toast(res.data.message || tm('messages.loadFailed'), 'error')
    }
  } catch (e: any) {
    toast(e?.response?.data?.message || tm('messages.loadFailed'), 'error')
  } finally {
    loading.value = false
  }
}

async function loadPlatforms() {
  try {
    const res = await axios.get('/api/platform/stats')
    if (res.data.status === 'ok' && Array.isArray(res.data.data?.platforms)) {
      proactivePlatforms.value = res.data.data.platforms
        .filter((p: any) => p?.meta?.support_proactive_message)
        .map((p: any) => ({
          id: p?.id || p?.meta?.id || 'unknown',
          name: p?.meta?.name || p?.type || '',
          display_name: p?.meta?.display_name || p?.display_name
        }))
    }
  } catch (e) {
    // ignore platform fetch errors in UI; subtitle will show fallback
  }
}

async function toggleJob(job: any) {
  try {
    const res = await axios.patch(`/api/cron/jobs/${job.job_id}`, { enabled: job.enabled })
    if (res.data.status !== 'ok') {
      toast(res.data.message || tm('messages.updateFailed'), 'error')
      await loadJobs()
    }
  } catch (e: any) {
    toast(e?.response?.data?.message || tm('messages.updateFailed'), 'error')
    await loadJobs()
  }
}

async function deleteJob(job: any) {
  try {
    const res = await axios.delete(`/api/cron/jobs/${job.job_id}`)
    if (res.data.status === 'ok') {
      toast(tm('messages.deleteSuccess'))
      jobs.value = jobs.value.filter((j) => j.job_id !== job.job_id)
    } else {
      toast(res.data.message || tm('messages.deleteFailed'), 'error')
    }
  } catch (e: any) {
    toast(e?.response?.data?.message || tm('messages.deleteFailed'), 'error')
  }
}

function openCreate() {
  resetNewJob()
  createDialog.value = true
}

function resetNewJob() {
  newJob.value = {
    run_once: false,
    name: '',
    note: '',
    cron_expression: '',
    run_at: '',
    session: '',
    timezone: '',
    enabled: true
  }
}

async function createJob() {
  if (!newJob.value.session) {
    toast(tm('messages.sessionRequired'), 'warning')
    return
  }
  if (!newJob.value.note) {
    toast(tm('messages.noteRequired'), 'warning')
    return
  }
  if (!newJob.value.run_once && !newJob.value.cron_expression) {
    toast(tm('messages.cronRequired'), 'warning')
    return
  }
  if (newJob.value.run_once && !newJob.value.run_at) {
    toast(tm('messages.runAtRequired'), 'warning')
    return
  }
  creating.value = true
  try {
    const payload: any = { ...newJob.value }
    const res = await axios.post('/api/cron/jobs', payload)
    if (res.data.status === 'ok') {
      toast(tm('messages.createSuccess'))
      createDialog.value = false
      resetNewJob()
      await loadJobs()
    } else {
      toast(res.data.message || tm('messages.createFailed'), 'error')
    }
  } catch (e: any) {
    toast(e?.response?.data?.message || tm('messages.createFailed'), 'error')
  } finally {
    creating.value = false
  }
}

onMounted(() => {
  loadJobs()
  loadPlatforms()
})
</script>

<style scoped>
.cron-page {
  padding: 20px;
  padding-top: 8px;
  padding-bottom: 40px;
}
</style>
