<!-- 渠道管理页，负责渠道配置、余额状态和启停操作。 -->
<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { ElMessageBox, type FormInstance } from "element-plus";
import AppIcon from "@/components/AppIcon.vue";
import ChannelFormFields from "@/components/ChannelFormFields.vue";
import PageHeader from "@/components/PageHeader.vue";
import http, { apiError } from "@/api/http";
import { useToastStore } from "@/stores/toast";

const toast = useToastStore();
const loading = ref(false);
const saving = ref(false);
const dialogOpen = ref(false);
const editingId = ref("");
const formRef = ref<FormInstance>();
const items = ref<Record<string, any>[]>([]);
const total = ref(0);
const query = reactive({ keyword: "", enabled: "", page: 1, page_size: 15 });
const form = reactive<Record<string, any>>({});
const rules = {
  name: [{ required: true, message: "请填写渠道名", trigger: "blur" }],
  base_url: [{ required: true, message: "请填写渠道 URL", trigger: "blur" }],
  api_key: [
    {
      validator: (_rule: unknown, value: string, callback: (error?: Error) => void) => {
        if (!editingId.value && !String(value || "").trim()) callback(new Error("请填写 API Key"));
        else callback();
      },
      trigger: "blur",
    },
  ],
};

async function load() {
  loading.value = true;
  try {
    const { data } = await http.get("/resources/channels", { params: query });
    items.value = data.data.items || [];
    total.value = Number(data.data.total || 0);
  } catch (error) {
    showError(error);
  } finally {
    loading.value = false;
  }
}
function reset(row?: Record<string, any>) {
  Object.keys(form).forEach((key) => delete form[key]);
  Object.assign(form, {
    name: row?.name || "",
    channel_type: row?.channel_type || "relay",
    base_url: row?.base_url || "",
    api_key: "",
    api_key_masked: row?.api_key_masked || "",
    warning_threshold: Number(row?.warning_threshold ?? 500),
    exchange_cny_amount: 1,
    exchange_point_amount: Number(row?.channel_points_per_cny ?? 1),
    max_concurrency: Number(row?.max_concurrency ?? 500),
    max_user_concurrency: Number(row?.max_user_concurrency ?? 10),
    enabled: row?.enabled ?? true,
  });
  editingId.value = row?.id || "";
}
function openCreate() {
  reset();
  dialogOpen.value = true;
}
function openEdit(row: Record<string, any>) {
  reset(row);
  dialogOpen.value = true;
}
async function save() {
  if (!(await formRef.value?.validate().catch(() => false))) return;
  const cnyAmount = Number(form.exchange_cny_amount);
  const pointAmount = Number(form.exchange_point_amount);
  if (!Number.isFinite(cnyAmount) || cnyAmount <= 0 || !Number.isFinite(pointAmount) || pointAmount <= 0) {
    toast.warning("请填写大于 0 的人民币金额和渠道积分");
    return;
  }
  if (editingId.value && String(form.api_key || "").trim()) {
    try {
      await ElMessageBox.confirm("此次修改将覆盖已加密保存的 API Key，是否继续？", "确认覆盖敏感配置", {
        type: "warning",
        confirmButtonText: "继续覆盖",
        cancelButtonText: "取消",
      });
    } catch {
      return;
    }
  }
  saving.value = true;
  try {
    const payload = {
      ...form,
      channel_points_per_cny: Number((pointAmount / cnyAmount).toFixed(6)),
    };
    delete payload.exchange_cny_amount;
    delete payload.exchange_point_amount;
    delete payload.api_key_masked;
    if (!payload.api_key) delete payload.api_key;
    if (editingId.value) await http.put(`/resources/channels/${editingId.value}`, payload);
    else await http.post("/resources/channels", payload);
    dialogOpen.value = false;
    toast.success(editingId.value ? "渠道已更新" : "渠道已创建");
    await load();
  } catch (error) {
    showError(error);
  } finally {
    saving.value = false;
  }
}
async function toggle(row: Record<string, any>, enabled: boolean) {
  try {
    await ElMessageBox.confirm(`${enabled ? "启用" : "停用"}后将立即生效，是否继续？`, "确认状态变更", {
      type: "warning",
      confirmButtonText: "确认",
      cancelButtonText: "取消",
    });
    await http.patch(`/resources/channels/${row.id}/enabled`, { enabled });
    row.enabled = enabled;
    toast.success("渠道状态已更新");
  } catch (error) {
    row.enabled = !enabled;
    if (error !== "cancel" && error !== "close") showError(error);
  }
}
async function remove(row: Record<string, any>) {
  try {
    await ElMessageBox.confirm(`确定删除渠道“${row.name}”吗？`, "删除渠道", {
      type: "warning",
      confirmButtonText: "删除",
      cancelButtonText: "取消",
    });
    await http.delete(`/resources/channels/${row.id}`);
    toast.success("渠道已删除");
    await load();
  } catch (error) {
    if (error !== "cancel" && error !== "close") showError(error);
  }
}
function search() {
  query.page = 1;
  void load();
}
function resetQuery() {
  query.keyword = "";
  query.enabled = "";
  search();
}
function balance(row: Record<string, any>) {
  return Number(row.balance) < 0 ? "无限" : `${Number(row.balance || 0).toFixed(2)} ${row.currency || ""}`;
}
function showError(error: unknown) {
  const detail = apiError(error);
  toast.error(detail.message, detail.copyText);
}

onMounted(load);
</script>

<template>
  <div class="page-stack management-page">
    <PageHeader
      title="渠道管理"
      description="维护 API 地址、密钥、汇率、余额和并发配置"
    >
      <el-button
        type="primary"
        @click="openCreate"
        ><AppIcon name="Plus" />新建渠道</el-button
      >
    </PageHeader>
    <section class="panel filter-bar">
      <el-input
        v-model="query.keyword"
        clearable
        placeholder="输入渠道名或地址"
        ><template #prefix><AppIcon name="Search" /></template
      ></el-input>
      <el-select
        v-model="query.enabled"
        clearable
        placeholder="启用状态"
        ><el-option
          label="已启用"
          value="true" /><el-option
          label="已停用"
          value="false"
      /></el-select>
      <el-button
        type="primary"
        @click="search"
        >查询</el-button
      >
      <el-button @click="resetQuery">重置</el-button>
    </section>
    <section
      v-loading="loading"
      class="panel table-panel"
    >
      <el-table
        v-if="items.length"
        :data="items"
        class="desktop-table"
      >
        <el-table-column
          prop="name"
          label="渠道名"
          min-width="130"
        />
        <el-table-column
          prop="base_url"
          label="渠道 URL"
          min-width="240"
          show-overflow-tooltip
        />
        <el-table-column
          prop="api_key_masked"
          label="API Key"
          min-width="190"
        />
        <el-table-column
          label="渠道汇率"
          min-width="180"
          ><template #default="{ row }"
            >1.00 元 = {{ Number(row.channel_points_per_cny || 0).toFixed(2) }} 积分</template
          ></el-table-column
        >
        <el-table-column
          prop="max_concurrency"
          label="最大并发"
          min-width="100"
        />
        <el-table-column
          prop="max_user_concurrency"
          label="单用户并发"
          min-width="120"
        />
        <el-table-column
          label="当前余额"
          min-width="130"
          ><template #default="{ row }">{{ balance(row) }}</template></el-table-column
        >
        <el-table-column
          label="启用"
          min-width="90"
          ><template #default="{ row }"
            ><el-switch
              :model-value="row.enabled"
              @change="toggle(row, Boolean($event))" /></template
        ></el-table-column>
        <el-table-column
          label="操作"
          width="140"
          fixed="right"
          ><template #default="{ row }"
            ><el-button
              link
              type="primary"
              @click="openEdit(row)"
              >编辑</el-button
            ><el-button
              link
              type="danger"
              @click="remove(row)"
              >删除</el-button
            ></template
          ></el-table-column
        >
      </el-table>
      <div
        v-if="items.length"
        class="mobile-card-list"
      >
        <article
          v-for="row in items"
          :key="row.id"
          class="data-card"
        >
          <dl>
            <dt>渠道名</dt>
            <dd>{{ row.name }}</dd>
            <dt>地址</dt>
            <dd>{{ row.base_url }}</dd>
            <dt>渠道汇率</dt>
            <dd>{{ Number(row.channel_points_per_cny || 0).toFixed(2) }}</dd>
            <dt>当前余额</dt>
            <dd>{{ balance(row) }}</dd>
            <dt>最大并发</dt>
            <dd>{{ row.max_concurrency }} / 用户 {{ row.max_user_concurrency }}</dd>
          </dl>
          <div class="card-actions">
            <el-button @click="openEdit(row)">编辑</el-button
            ><el-button
              type="danger"
              plain
              @click="remove(row)"
              >删除</el-button
            >
          </div>
        </article>
      </div>
      <el-empty
        v-if="!items.length"
        description="暂无渠道"
      />
      <el-pagination
        v-if="total > query.page_size"
        v-model:current-page="query.page"
        :page-size="query.page_size"
        :total="total"
        layout="total, prev, pager, next"
        @current-change="load"
      />
    </section>

    <el-dialog
      v-model="dialogOpen"
      :title="editingId ? '编辑渠道' : '新建渠道'"
      width="min(820px, calc(100vw - 32px))"
      class="managed-scroll-dialog"
      align-center
      destroy-on-close
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-position="top"
        ><ChannelFormFields
          :form="form"
          :editing="Boolean(editingId)"
      /></el-form>
      <template #footer
        ><el-button @click="dialogOpen = false">取消</el-button
        ><el-button
          type="primary"
          :loading="saving"
          @click="save"
          >保存</el-button
        ></template
      >
    </el-dialog>
  </div>
</template>
