<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage } from 'element-plus'
import api from '@/api/client'
import PageHeader from '@/components/PageHeader.vue'
import AppCard from '@/components/AppCard.vue'

const { t } = useI18n()

interface CountryStat {
  code: string
  name: string
  count: number
}

interface OutboundMember {
  runtime_name: string
  name: string
}

interface OutboundGroup {
  runtime_name: string
  name: string
  type: string
  source: string
  now: string
  now_name: string
  selectable: boolean
  is_country?: boolean
  members: OutboundMember[]
}

const loading = ref(false)
const savingGroup = ref('')
const defaultPolicy = ref('DIRECT')
const groups = ref<OutboundGroup[]>([])
const countries = ref<CountryStat[]>([])

const countryGroups = computed(() => groups.value.filter(g => g.is_country))
const policyGroups = computed(() => groups.value.filter(g => !g.is_country))

const policyOptions = computed(() => {
  const opts = [
    { value: 'DIRECT', label: t('rules.targetDirect') },
    { value: 'REJECT', label: t('rules.targetReject') },
  ]
  for (const c of countries.value) {
    opts.push({ value: `country:${c.code}`, label: t('outbound.countryPoolName', { name: c.name }) })
  }
  for (const g of policyGroups.value) {
    opts.push({ value: g.runtime_name, label: t('outbound.policyGroupName', { name: g.name, type: groupTypeLabel(g.type) }) })
  }
  return opts
})

function groupTypeLabel(type: string) {
  const map: Record<string, string> = {
    Selector: t('outbound.typeSelector'),
    URLTest: t('outbound.typeURLTest'),
    Fallback: t('outbound.typeFallback'),
    LoadBalance: t('outbound.typeLoadBalance'),
    Relay: t('outbound.typeRelay'),
  }
  return map[type] || type
}

async function load() {
  loading.value = true
  try {
    const [outbound, countryRes] = await Promise.all([
      api.get('/outbound'),
      api.get('/countries'),
    ])
    const data = outbound.data
    defaultPolicy.value = data.default_policy || 'DIRECT'
    groups.value = data.groups || []
    countries.value = countryRes.data.items || []
  } finally {
    loading.value = false
  }
}

async function saveDefaultPolicy() {
  await api.put('/outbound/default-policy', { policy: defaultPolicy.value })
  ElMessage.success(t('outbound.saved'))
  load()
}

async function selectGroup(group: OutboundGroup, proxy: string) {
  savingGroup.value = group.runtime_name
  try {
    await api.put(`/outbound/groups/${encodeURIComponent(group.runtime_name)}`, { proxy })
    ElMessage.success(t('outbound.groupSwitched'))
    await load()
  } finally {
    savingGroup.value = ''
  }
}

onMounted(load)
</script>

<template>
  <div class="page">
    <PageHeader :title="t('outbound.title')" :description="t('outbound.desc')">
      <template #actions>
        <el-button @click="load">{{ t('common.refresh') }}</el-button>
      </template>
    </PageHeader>

    <AppCard :title="t('outbound.defaultTitle')" padded>
      <p class="form-hint form-hint--flush u-mb-4">{{ t('outbound.defaultHint') }}</p>
      <div class="inline-actions">
        <el-select v-model="defaultPolicy" filterable class="toolbar-select--wide">
          <el-option
            v-for="opt in policyOptions"
            :key="opt.value"
            :label="opt.label"
            :value="opt.value"
          />
        </el-select>
        <el-button type="primary" @click="saveDefaultPolicy">{{ t('outbound.save') }}</el-button>
      </div>
    </AppCard>

    <AppCard :title="t('outbound.countryPools')">
      <div class="card-toolbar card-toolbar--desc">
        <p class="form-hint form-hint--flush">{{ t('outbound.countryPoolsHint') }}</p>
      </div>
      <el-table :data="countryGroups" v-loading="loading" size="small" :empty-text="t('outbound.emptyCountry')">
        <el-table-column prop="name" :label="t('outbound.countryPool')" min-width="140" />
        <el-table-column :label="t('outbound.currentNode')" min-width="160">
          <template #default="{ row }">
            <div class="geo-status">
              <span>{{ row.now_name || row.now || t('common.none') }}</span>
              <span class="form-hint form-hint--flush">{{ t('outbound.auto') }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column :label="t('outbound.memberCount')" width="90">
          <template #default="{ row }">{{ row.members.length }}</template>
        </el-table-column>
        <el-table-column prop="source" :label="t('common.source')" width="90" />
      </el-table>
    </AppCard>

    <AppCard :title="t('outbound.policyGroups')">
      <div class="card-toolbar card-toolbar--desc">
        <p class="form-hint form-hint--flush">{{ t('outbound.policyGroupsHint') }}</p>
      </div>
      <el-table :data="policyGroups" v-loading="loading" size="small" :empty-text="t('outbound.emptyPolicy')">
        <el-table-column prop="name" :label="t('outbound.policyGroup')" min-width="140" />
        <el-table-column :label="t('common.type')" width="110">
          <template #default="{ row }">
            <el-tag size="small" :type="row.selectable ? 'primary' : 'success'">
              {{ groupTypeLabel(row.type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('outbound.currentNode')" min-width="160">
          <template #default="{ row }">
            <div class="geo-status">
              <span>{{ row.now_name || row.now || t('common.none') }}</span>
              <span v-if="!row.selectable" class="form-hint form-hint--flush">{{ t('outbound.auto') }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column :label="t('outbound.switchNode')" min-width="220">
          <template #default="{ row }">
            <el-select
              v-if="row.selectable"
              :model-value="row.now"
              filterable
              :loading="savingGroup === row.runtime_name"
              class="table-cell-select"
              @change="(v: string) => selectGroup(row, v)"
            >
              <el-option
                v-for="m in row.members"
                :key="m.runtime_name"
                :label="m.name"
                :value="m.runtime_name"
              />
            </el-select>
            <span v-else-if="row.type === 'Fallback'" class="form-hint">{{ t('outbound.fallbackHint') }}</span>
            <span v-else class="form-hint">{{ t('outbound.skipDirect') }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="source" :label="t('common.source')" width="90" />
      </el-table>
    </AppCard>
  </div>
</template>
