<template>
  <div class="page">
    <PageHeader :title="t('tunnels.title')" :description="t('tunnels.description')">
      <template #actions>
        <el-button @click="load">{{ t('common.refresh') }}</el-button>
        <ImportExportActions resource="tunnels" export-filename="wormhole-tunnels.json" @done="load" />
        <el-button type="primary" @click="openDialog()">{{ t('tunnels.add') }}</el-button>
      </template>
    </PageHeader>

    <AppCard>
      <div class="card-toolbar">
        <el-input v-model="query" :placeholder="t('tunnels.searchPlaceholder')" clearable class="toolbar-input--wide" @keyup.enter="search" @clear="search" />
        <el-button @click="search">{{ t('common.search') }}</el-button>
      </div>
      <el-table :data="list" v-loading="loading" size="small">
        <el-table-column prop="id" :label="t('common.id')" width="60" />
        <el-table-column prop="name" :label="t('common.name')" min-width="100" />
        <el-table-column :label="t('common.client')" width="120">
          <template #default="{ row }">{{ clientName(row.client_id) }}</template>
        </el-table-column>
        <el-table-column prop="mode" :label="t('common.mode')" width="72" />
        <el-table-column :label="t('tunnels.listenPort')" width="100">
          <template #default="{ row }">
            <el-link type="primary" :underline="false" @click="openTunnel(row)">{{ row.listen_port }}</el-link>
          </template>
        </el-table-column>
        <el-table-column prop="target_addr" :label="t('common.target')" min-width="140" />
        <el-table-column :label="t('tunnels.visitorAuth')" width="88">
          <template #default="{ row }">
            <el-tag :type="row.visitor_auth_enabled ? 'warning' : 'info'" size="small">
              {{ row.visitor_auth_enabled ? t('common.on') : t('common.off') }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('common.status')" width="88">
          <template #default="{ row }">
            <el-tag :type="row.run_status ? 'success' : 'info'" size="small">
              {{ row.run_status ? t('common.running') : row.status ? t('common.stopped') : t('common.paused') }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('common.actions')" width="260" fixed="right">
          <template #default="{ row }">
            <el-button v-if="row.status && !row.run_status" size="small" link @click="resume(row)">{{ t('common.start') }}</el-button>
            <el-button v-if="row.run_status" size="small" link @click="stop(row)">{{ t('common.stop') }}</el-button>
            <el-button v-if="row.status" size="small" link @click="pause(row)">{{ t('common.pause') }}</el-button>
            <el-button v-if="!row.status" size="small" link type="primary" @click="resume(row)">{{ t('common.resume') }}</el-button>
            <el-button size="small" link type="primary" @click="openDialog(row)">{{ t('common.edit') }}</el-button>
            <el-button size="small" link type="danger" @click="remove(row)">{{ t('common.delete') }}</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="card-pager">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50]"
          layout="total, sizes, prev, pager, next"
          @current-change="load"
          @size-change="search"
        />
      </div>
    </AppCard>

    <el-dialog v-model="dialogVisible" :title="form.id ? t('tunnels.edit') : t('tunnels.add')" width="600px" destroy-on-close>
      <el-form :model="form" label-width="100px">
        <el-form-item :label="t('common.client')" required>
          <ClientSelect v-model="form.client_id" :clients="clients" :disabled="!!form.id" />
        </el-form-item>
        <el-form-item :label="t('common.name')"><el-input v-model="form.name" /></el-form-item>
        <el-form-item :label="t('common.mode')">
          <el-select v-model="form.mode">
            <el-option :label="t('tunnels.tcp')" value="tcp" />
            <el-option :label="t('tunnels.udp')" value="udp" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('tunnels.listenPort')"><el-input-number v-model="form.listen_port" :min="1" :max="65535" class="w-full" /></el-form-item>
        <el-form-item :label="t('tunnels.targetAddr')"><el-input v-model="form.target_addr" placeholder="127.0.0.1:8080" /></el-form-item>
        <ProxyHeadersFields v-model:ip-forward-mode="form.ip_forward_mode" v-model:custom-headers="form.custom_headers" />
        <VisitorAuthFields
          v-model:visitor-auth-enabled="form.visitor_auth_enabled"
          v-model:visitor-bind-mode="form.visitor_bind_mode"
          v-model:visitor-ttl-seconds="form.visitor_ttl_seconds"
          v-model:visitor-ids="form.visitor_ids"
          :visitors="visitors"
          tunnel-hint
        />
        <el-form-item :label="t('common.enabled')"><el-switch v-model="form.status" /></el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
        <el-button type="primary" @click="save">{{ t('common.save') }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
import PageHeader from '@/components/PageHeader.vue'
import AppCard from '@/components/AppCard.vue'
import ClientSelect from '@/components/ClientSelect.vue'
import ProxyHeadersFields from '@/components/ProxyHeadersFields.vue'
import VisitorAuthFields from '@/components/VisitorAuthFields.vue'
import ImportExportActions from '@/components/ImportExportActions.vue'
import { openTunnel } from '@/utils/targetLink'
import api from '@/api'

const { t } = useI18n()
const list = ref([])
const clients = ref([])
const visitors = ref([])
const loading = ref(false)
const dialogVisible = ref(false)
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const query = ref('')
const defaultForm = () => ({
  id: null, client_id: null, name: '', mode: 'tcp', listen_port: 9000,
  target_addr: '127.0.0.1:80', ip_forward_mode: 'replace', custom_headers: '', status: true,
  visitor_auth_enabled: false, visitor_bind_mode: 'all', visitor_ttl_seconds: 7200, visitor_ids: [],
})
const form = reactive(defaultForm())

function clientName(id) {
  const c = clients.value.find((item) => item.id === id)
  return c ? `${c.name} (#${id})` : `#${id}`
}

async function loadClients() {
  const { data } = await api.get('/clients')
  clients.value = data
}

async function loadVisitors() {
  try {
    const { data } = await api.get('/users')
    visitors.value = data
  } catch {
    visitors.value = []
  }
}

async function load() {
  loading.value = true
  try {
    const { data } = await api.get('/tunnels', { params: { page: page.value, page_size: pageSize.value, q: query.value || undefined } })
    list.value = data.items || []
    total.value = data.total || 0
    await loadClients()
    await loadVisitors()
  } finally {
    loading.value = false
  }
}

function search() {
  page.value = 1
  load()
}

function openDialog(row) {
  if (row) {
    Object.assign(form, {
      ...row,
      visitor_ids: row.visitor_ids || [],
      visitor_bind_mode: row.visitor_bind_mode || 'all',
      visitor_ttl_seconds: row.visitor_ttl_seconds || 7200,
    })
  } else {
    Object.assign(form, defaultForm())
    if (clients.value.length) form.client_id = clients.value[0].id
  }
  dialogVisible.value = true
}

async function save() {
  if (!form.client_id) { ElMessage.warning(t('common.selectClient')); return }
  try {
    if (form.id) await api.put(`/tunnels/${form.id}`, form)
    else await api.post('/tunnels', form)
    ElMessage.success(t('message.saveSuccess'))
    dialogVisible.value = false
    load()
  } catch (e) {
    ElMessage.error(e.response?.data?.error || t('message.saveFailed'))
  }
}

async function stop(row) {
  await api.post(`/tunnels/${row.id}/stop`)
  load()
}

async function pause(row) {
  await api.post(`/tunnels/${row.id}/pause`)
  load()
}

async function resume(row) {
  await api.post(`/tunnels/${row.id}/resume`)
  load()
}

async function remove(row) {
  await ElMessageBox.confirm(t('tunnels.confirmDelete'), t('common.hint'), { type: 'warning' })
  await api.delete(`/tunnels/${row.id}`)
  ElMessage.success(t('message.deleteSuccess'))
  load()
}

onMounted(load)
</script>
