<script lang="ts" setup>
import { computed, reactive, ref, watch } from 'vue';

import { Page } from '@vben/common-ui';
import { useAccessStore } from '@vben/stores';

import {
  deleteBaishunGame,
  fetchBaishunCatalog,
  getBaishunProviderConfig,
  importBaishunCatalog,
  pageBaishunCatalog,
  pageBaishunGames,
  saveBaishunGame,
  saveBaishunProviderConfig,
} from '#/api/legacy/baishun-game';
import { getAllowedSysOrigins } from '#/views/system/shared';

import {
  Button,
  Card,
  Form,
  FormItem,
  Image,
  Input,
  InputNumber,
  Modal,
  Pagination,
  Select,
  Space,
  Table,
  TabPane,
  Tabs,
  Tag,
  message,
} from 'antdv-next';

import {
  GAME_CATEGORY_OPTIONS,
  GAME_CLIENT_ORIGIN_OPTIONS,
} from './constants';

defineOptions({ name: 'OperateBaishunGameManage' });

function createGameForm(sysOrigin = '') {
  return {
    amounts: '',
    category: 'OTHER',
    clientOrigin: 'COMMON',
    cover: '',
    fullScreen: true as any,
    gameCode: '',
    gameId: '',
    gameMode: 3 as any,
    gsp: '',
    height: 0,
    id: '',
    launchMode: 'H5_REMOTE',
    name: '',
    orientation: undefined as any,
    packageUrl: '',
    packageVersion: '',
    previewUrl: '',
    regions: '',
    safeHeight: 0,
    showcase: true as any,
    sort: 0,
    sysOrigin,
    vendorGameId: undefined as any,
    width: 0,
    currencyIcon: '',
  };
}

function createProviderForm(sysOrigin = '') {
  return {
    sysOrigin,
    platformBaseUrl: '',
    appId: undefined as any,
    appName: '',
    appChannel: '',
    appKey: '',
    gsp: 101 as any,
    launchCodeTtlSeconds: 300 as any,
    ssTokenTtlSeconds: 86400 as any,
  };
}

const accessStore = useAccessStore();
const sysOriginOptions = computed(() => {
  const options = getAllowedSysOrigins(accessStore.accessCodes || []);
  return options.length > 0 ? options : getAllowedSysOrigins([]);
});

const booleanOptions = [
  { label: '是', value: true as any },
  { label: '否', value: false as any },
];
const showcaseOptions = [
  { label: '全部', value: '' as any },
  { label: '上架', value: 'true' as any },
  { label: '下架', value: 'false' as any },
];
const clientOriginOptions = GAME_CLIENT_ORIGIN_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const categoryOptions = GAME_CATEGORY_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const launchModeOptions = [
  { label: 'H5_REMOTE', value: 'H5_REMOTE' },
  { label: 'H5_ZIP_LOCAL', value: 'H5_ZIP_LOCAL' },
];
const gameModeOptions = [
  { label: '1', value: 1 as any },
  { label: '2 半屏', value: 2 as any },
  { label: '3 默认', value: 3 as any },
];
const orientationOptions = [
  { label: '0', value: 0 as any },
  { label: '1', value: 1 as any },
  { label: '2', value: 2 as any },
];

const activeTab = ref('configured');
const contextQuery = reactive({ sysOrigin: '' });
const gameQuery = reactive<Record<string, any>>({
  cursor: 1,
  keyword: '',
  limit: 20,
  showcase: '',
});
const catalogQuery = reactive<Record<string, any>>({
  cursor: 1,
  keyword: '',
  limit: 20,
});

const gameLoading = ref(false);
const gameSaving = ref(false);
const providerLoading = ref(false);
const providerSaving = ref(false);
const catalogLoading = ref(false);
const catalogFetching = ref(false);
const catalogImporting = ref(false);
const totalGames = ref(0);
const totalCatalog = ref(0);
const modalOpen = ref(false);
const gameList = ref<Array<Record<string, any>>>([]);
const catalogList = ref<Array<Record<string, any>>>([]);
const selectedCatalogKeys = ref<Array<number>>([]);
const gameForm = reactive<Record<string, any>>(createGameForm());
const providerForm = reactive<Record<string, any>>(createProviderForm());

const gameColumns = [
  { dataIndex: 'cover', key: 'cover', title: '封面', width: 90 },
  { dataIndex: 'name', key: 'name', title: '名称', width: 180 },
  { dataIndex: 'gameId', key: 'gameId', title: '内部ID', width: 150 },
  { dataIndex: 'vendorGameId', key: 'vendorGameId', title: '百顺ID', width: 120 },
  { dataIndex: 'showcase', key: 'showcase', title: '状态', width: 100 },
  { dataIndex: 'clientOrigin', key: 'clientOrigin', title: '客户端', width: 100 },
  { dataIndex: 'gameMode', key: 'gameMode', title: 'Game Mode', width: 110 },
  { dataIndex: 'launchMode', key: 'launchMode', title: '启动模式', width: 130 },
  { dataIndex: 'safeHeight', key: 'safeHeight', title: '安全区', width: 110 },
  { dataIndex: 'sort', key: 'sort', title: '排序', width: 90 },
  { dataIndex: 'updateTime', key: 'updateTime', title: '更新时间', width: 180 },
  { dataIndex: 'actions', key: 'actions', title: '操作', width: 160 },
];

const catalogColumns = [
  { dataIndex: 'cover', key: 'cover', title: '封面', width: 90 },
  { dataIndex: 'name', key: 'name', title: '名称', width: 180 },
  { dataIndex: 'gameId', key: 'gameId', title: '内部ID', width: 150 },
  { dataIndex: 'vendorGameId', key: 'vendorGameId', title: '百顺ID', width: 120 },
  { dataIndex: 'status', key: 'status', title: '目录状态', width: 110 },
  { dataIndex: 'packageVersion', key: 'packageVersion', title: '包版本', width: 110 },
  { dataIndex: 'gsp', key: 'gsp', title: 'GSP', width: 90 },
  { dataIndex: 'added', key: 'added', title: '后台列表', width: 110 },
  { dataIndex: 'downloadUrl', key: 'downloadUrl', title: '入口地址', width: 360 },
  { dataIndex: 'updateTime', key: 'updateTime', title: '更新时间', width: 180 },
];

const catalogRowSelection = computed(() => ({
  selectedRowKeys: selectedCatalogKeys.value,
  onChange: (keys: Array<number | string>) => {
    selectedCatalogKeys.value = keys.map((item) => Number(item));
  },
  getCheckboxProps: (record: Record<string, any>) => ({
    disabled: Boolean(record.added),
  }),
}));

watch(
  sysOriginOptions,
  (options) => {
    if (!contextQuery.sysOrigin) {
      contextQuery.sysOrigin = String(options[0]?.value || '');
    }
  },
  { immediate: true },
);

watch(
  () => contextQuery.sysOrigin,
  (value) => {
    if (!value) {
      return;
    }
    Object.assign(providerForm, createProviderForm(value));
    selectedCatalogKeys.value = [];
    void Promise.all([loadProviderConfig(), loadGames(true), loadCatalog(true)]);
  },
  { immediate: true },
);

function resetGameForm() {
  Object.assign(gameForm, createGameForm(contextQuery.sysOrigin));
}

function applyProviderForm(record: Record<string, any>) {
  Object.assign(providerForm, createProviderForm(contextQuery.sysOrigin), {
    ...record,
    sysOrigin: contextQuery.sysOrigin,
    appId: Number(record.appId || 0) || undefined,
    gsp: Number(record.gsp || 101) || 101,
    launchCodeTtlSeconds:
      Number(record.launchCodeTtlSeconds || 300) || 300,
    ssTokenTtlSeconds:
      Number(record.ssTokenTtlSeconds || 86400) || 86400,
  });
}

async function loadProviderConfig() {
  if (!contextQuery.sysOrigin) {
    return;
  }
  providerLoading.value = true;
  try {
    const result = await getBaishunProviderConfig({
      sysOrigin: contextQuery.sysOrigin,
    });
    applyProviderForm(result || {});
  } finally {
    providerLoading.value = false;
  }
}

async function persistProviderConfig(showSuccess = true) {
  if (
    !contextQuery.sysOrigin ||
    !providerForm.platformBaseUrl ||
    !providerForm.appId ||
    !providerForm.appChannel ||
    !providerForm.appKey
  ) {
    message.warning('请补全百顺平台地址、AppId、AppChannel、AppKey');
    return false;
  }
  providerSaving.value = true;
  try {
    const result = await saveBaishunProviderConfig({
      ...providerForm,
      sysOrigin: contextQuery.sysOrigin,
      appId: Number(providerForm.appId || 0),
      gsp: Number(providerForm.gsp || 101),
      launchCodeTtlSeconds: Number(providerForm.launchCodeTtlSeconds || 300),
      ssTokenTtlSeconds: Number(providerForm.ssTokenTtlSeconds || 86400),
    });
    applyProviderForm(result || providerForm);
    if (showSuccess) {
      message.success('百顺配置已保存');
    }
    return true;
  } catch {
    return false;
  } finally {
    providerSaving.value = false;
  }
}

function openCreate() {
  resetGameForm();
  modalOpen.value = true;
}

function openEdit(record: Record<string, any>) {
  Object.assign(gameForm, createGameForm(contextQuery.sysOrigin), {
    ...record,
    id: String(record.id || ''),
    vendorGameId: Number(record.vendorGameId || 0) || undefined,
  });
  modalOpen.value = true;
}

async function loadGames(reset = false) {
  if (!contextQuery.sysOrigin) {
    return;
  }
  if (reset) {
    gameQuery.cursor = 1;
  }
  gameLoading.value = true;
  try {
    const result = await pageBaishunGames({
      ...gameQuery,
      sysOrigin: contextQuery.sysOrigin,
    });
    gameList.value = Array.isArray(result.records) ? result.records : [];
    totalGames.value = Number(result.total || 0);
  } finally {
    gameLoading.value = false;
  }
}

async function loadCatalog(reset = false) {
  if (!contextQuery.sysOrigin) {
    return;
  }
  if (reset) {
    catalogQuery.cursor = 1;
  }
  catalogLoading.value = true;
  try {
    const result = await pageBaishunCatalog({
      ...catalogQuery,
      sysOrigin: contextQuery.sysOrigin,
    });
    catalogList.value = Array.isArray(result.records) ? result.records : [];
    totalCatalog.value = Number(result.total || 0);
  } finally {
    catalogLoading.value = false;
  }
}

function handleGameSearch() {
  void loadGames(true);
}

function handleCatalogSearch() {
  void loadCatalog(true);
}

function handleGamePageChange(page: number, pageSize: number) {
  gameQuery.cursor = page;
  gameQuery.limit = pageSize;
  void loadGames();
}

function handleCatalogPageChange(page: number, pageSize: number) {
  catalogQuery.cursor = page;
  catalogQuery.limit = pageSize;
  void loadCatalog();
}

async function submitGameForm() {
  if (
    !gameForm.sysOrigin ||
    !gameForm.name ||
    !gameForm.gameId ||
    !gameForm.vendorGameId
  ) {
    message.warning('请补全系统、名称、内部ID和百顺ID');
    return;
  }
  gameSaving.value = true;
  try {
    await saveBaishunGame({
      ...gameForm,
      id: Number(gameForm.id || 0),
      vendorGameId: Number(gameForm.vendorGameId || 0),
    });
    message.success('保存成功');
    modalOpen.value = false;
    await Promise.all([loadGames(true), loadCatalog(true)]);
  } finally {
    gameSaving.value = false;
  }
}

function handleDelete(record: Record<string, any>) {
  Modal.confirm({
    title: '确认删除这个游戏配置吗？',
    async onOk() {
      await deleteBaishunGame(record.id, record.sysOrigin);
      message.success('删除成功');
      await Promise.all([loadGames(true), loadCatalog(true)]);
    },
  });
}

async function handleSaveProviderConfig() {
  await persistProviderConfig(true);
}

async function handleFetchCatalog() {
  if (!(await persistProviderConfig(false))) {
    return;
  }
  catalogFetching.value = true;
  try {
    const result = await fetchBaishunCatalog({
      sysOrigin: contextQuery.sysOrigin,
    });
    message.success(
      `获取完成：新增 ${Number(result.inserted || 0)}，更新 ${Number(result.updated || 0)}，跳过 ${Number(result.skipped || 0)}`,
    );
    activeTab.value = 'catalog';
    await loadCatalog(true);
  } finally {
    catalogFetching.value = false;
  }
}

async function handleImportSelected() {
  if (!contextQuery.sysOrigin) {
    return;
  }
  if (selectedCatalogKeys.value.length === 0) {
    message.warning('请选择要添加到后台列表的百顺游戏');
    return;
  }
  catalogImporting.value = true;
  try {
    const result = await importBaishunCatalog({
      sysOrigin: contextQuery.sysOrigin,
      vendorGameIds: selectedCatalogKeys.value,
    });
    selectedCatalogKeys.value = [];
    message.success(
      `添加完成：新增 ${Number(result.imported || 0)}，已存在 ${Number(result.existing || 0)}`,
    );
    await Promise.all([loadGames(true), loadCatalog(true)]);
  } finally {
    catalogImporting.value = false;
  }
}
</script>

<template>
  <Page title="三方-百顺">
    <Card :loading="providerLoading" title="百顺接入配置">
      <Form layout="vertical">
        <div class="form-grid provider-grid">
          <FormItem label="系统">
            <SysOriginSelect
              v-model:value="contextQuery.sysOrigin"
              :options="sysOriginOptions"
            />
          </FormItem>
          <FormItem
            label="平台地址"
            extra="填写百顺平台接口地址，例如 https://game-cn-test.jieyou.shop；不要填 Lucky Gift 域名。"
          >
            <Input
              v-model:value="providerForm.platformBaseUrl"
              placeholder="https://game-cn-test.jieyou.shop"
            />
          </FormItem>
          <FormItem label="AppId">
            <InputNumber
              v-model:value="providerForm.appId"
              :min="1"
              style="width: 100%"
            />
          </FormItem>
          <FormItem label="AppName">
            <Input v-model:value="providerForm.appName" placeholder="可选" />
          </FormItem>
          <FormItem label="AppChannel">
            <Input
              v-model:value="providerForm.appChannel"
              placeholder="yumiparty"
            />
          </FormItem>
          <FormItem label="AppKey">
            <Input
              v-model:value="providerForm.appKey"
              placeholder="请输入百顺密钥"
              type="password"
            />
          </FormItem>
          <FormItem label="默认 GSP">
            <InputNumber
              v-model:value="providerForm.gsp"
              :min="1"
              style="width: 100%"
            />
          </FormItem>
          <FormItem label="LaunchCode TTL(秒)">
            <InputNumber
              v-model:value="providerForm.launchCodeTtlSeconds"
              :min="1"
              style="width: 100%"
            />
          </FormItem>
          <FormItem label="SsToken TTL(秒)">
            <InputNumber
              v-model:value="providerForm.ssTokenTtlSeconds"
              :min="1"
              style="width: 100%"
            />
          </FormItem>
        </div>
        <div class="toolbar">
          <Button
            type="primary"
            :loading="providerSaving"
            @click="handleSaveProviderConfig"
          >
            保存配置
          </Button>
          <Button :loading="catalogFetching" @click="handleFetchCatalog">
            获取百顺游戏列表
          </Button>
          <span class="hint">
            房间页只读取“已添加游戏”，目录页只负责预览和选择导入。
          </span>
        </div>
      </Form>
    </Card>

    <Card class="content-card">
      <Tabs v-model:activeKey="activeTab">
        <TabPane key="configured" tab="已添加游戏">
          <div class="toolbar">
            <Select
              v-model:value="gameQuery.showcase"
              style="width: 120px"
              :options="showcaseOptions"
              @change="handleGameSearch"
            />
            <Input
              v-model:value="gameQuery.keyword"
              placeholder="搜索名称 / 内部ID / 百顺ID"
              style="width: 240px"
              @pressEnter="handleGameSearch"
            />
            <Button type="primary" :loading="gameLoading" @click="handleGameSearch">
              搜索
            </Button>
            <Button type="primary" @click="openCreate">
              新增
            </Button>
          </div>

          <Table
            :columns="gameColumns"
            :data-source="gameList"
            :loading="gameLoading"
            :pagination="false"
            row-key="id"
            :scroll="{ x: 1600 }"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'cover'">
                <Image v-if="record.cover" :src="record.cover" class="cover" />
                <span v-else>-</span>
              </template>
              <template v-else-if="column.key === 'showcase'">
                <Tag :color="record.showcase ? 'success' : 'default'">
                  {{ record.showcase ? '上架' : '下架' }}
                </Tag>
              </template>
              <template v-else-if="column.key === 'actions'">
                <Space>
                  <Button size="small" type="link" @click="openEdit(record)">
                    编辑
                  </Button>
                  <Button
                    danger
                    size="small"
                    type="link"
                    @click="handleDelete(record)"
                  >
                    删除
                  </Button>
                </Space>
              </template>
            </template>
          </Table>

          <div v-if="totalGames > 0" class="pager">
            <Pagination
              :current="gameQuery.cursor"
              :page-size="gameQuery.limit"
              :total="totalGames"
              show-size-changer
              @change="handleGamePageChange"
              @showSizeChange="handleGamePageChange"
            />
          </div>
        </TabPane>

        <TabPane key="catalog" tab="百顺目录">
          <div class="toolbar">
            <Input
              v-model:value="catalogQuery.keyword"
              placeholder="搜索目录名称 / 内部ID / 百顺ID"
              style="width: 260px"
              @pressEnter="handleCatalogSearch"
            />
            <Button :loading="catalogLoading" type="primary" @click="handleCatalogSearch">
              搜索
            </Button>
            <Button :loading="catalogFetching" @click="handleFetchCatalog">
              重新获取目录
            </Button>
            <Button
              type="primary"
              :loading="catalogImporting"
              @click="handleImportSelected"
            >
              添加已选游戏
            </Button>
          </div>

          <Table
            :columns="catalogColumns"
            :data-source="catalogList"
            :loading="catalogLoading"
            :pagination="false"
            row-key="vendorGameId"
            :row-selection="catalogRowSelection"
            :scroll="{ x: 1700 }"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'cover'">
                <Image v-if="record.cover" :src="record.cover" class="cover" />
                <span v-else>-</span>
              </template>
              <template v-else-if="column.key === 'status'">
                <Tag :color="record.status === 'ENABLED' ? 'success' : 'default'">
                  {{ record.status || '-' }}
                </Tag>
              </template>
              <template v-else-if="column.key === 'added'">
                <Tag :color="record.added ? 'success' : 'default'">
                  {{ record.added ? (record.showcase ? '已添加-上架' : '已添加-下架') : '未添加' }}
                </Tag>
              </template>
              <template v-else-if="column.key === 'downloadUrl'">
                <a
                  v-if="record.downloadUrl"
                  :href="record.downloadUrl"
                  class="link-cell"
                  rel="noreferrer"
                  target="_blank"
                >
                  {{ record.downloadUrl }}
                </a>
                <span v-else>-</span>
              </template>
            </template>
          </Table>

          <div v-if="totalCatalog > 0" class="pager">
            <Pagination
              :current="catalogQuery.cursor"
              :page-size="catalogQuery.limit"
              :total="totalCatalog"
              show-size-changer
              @change="handleCatalogPageChange"
              @showSizeChange="handleCatalogPageChange"
            />
          </div>
        </TabPane>
      </Tabs>
    </Card>

    <Modal
      :confirm-loading="gameSaving"
      :open="modalOpen"
      destroy-on-close
      :title="gameForm.id ? '编辑百顺游戏' : '新增百顺游戏'"
      width="860px"
      @cancel="modalOpen = false"
      @ok="submitGameForm"
    >
      <Form layout="vertical">
        <div class="form-grid">
          <FormItem label="系统">
            <SysOriginSelect
              v-model:value="gameForm.sysOrigin"
              :options="sysOriginOptions"
            />
          </FormItem>
          <FormItem label="名称">
            <Input v-model:value="gameForm.name" placeholder="请输入游戏名称" />
          </FormItem>
          <FormItem label="内部ID">
            <Input v-model:value="gameForm.gameId" placeholder="例如 bs_1100" />
          </FormItem>
          <FormItem label="百顺ID">
            <InputNumber
              v-model:value="gameForm.vendorGameId"
              :min="1"
              style="width: 100%"
            />
          </FormItem>
          <FormItem label="编号">
            <Input v-model:value="gameForm.gameCode" placeholder="默认取百顺ID" />
          </FormItem>
          <FormItem label="分类">
            <Select v-model:value="gameForm.category" :options="categoryOptions" />
          </FormItem>
          <FormItem label="客户端">
            <Select
              v-model:value="gameForm.clientOrigin"
              :options="clientOriginOptions"
            />
          </FormItem>
          <FormItem label="状态">
            <Select v-model:value="gameForm.showcase" :options="booleanOptions" />
          </FormItem>
          <FormItem label="是否全屏">
            <Select v-model:value="gameForm.fullScreen" :options="booleanOptions" />
          </FormItem>
          <FormItem label="Game Mode">
            <Select v-model:value="gameForm.gameMode" :options="gameModeOptions" />
          </FormItem>
          <FormItem label="启动模式">
            <Select v-model:value="gameForm.launchMode" :options="launchModeOptions" />
          </FormItem>
          <FormItem label="排序">
            <InputNumber v-model:value="gameForm.sort" :min="0" style="width: 100%" />
          </FormItem>
          <FormItem label="安全区高度">
            <InputNumber
              v-model:value="gameForm.safeHeight"
              :min="0"
              style="width: 100%"
            />
          </FormItem>
          <FormItem label="Orientation">
            <Select
              v-model:value="gameForm.orientation"
              :options="orientationOptions"
              allow-clear
            />
          </FormItem>
          <FormItem label="宽">
            <InputNumber v-model:value="gameForm.width" :min="0" style="width: 100%" />
          </FormItem>
          <FormItem label="高">
            <InputNumber v-model:value="gameForm.height" :min="0" style="width: 100%" />
          </FormItem>
          <FormItem label="GSP">
            <Input v-model:value="gameForm.gsp" placeholder="默认取系统百顺配置" />
          </FormItem>
          <FormItem label="金额">
            <Input v-model:value="gameForm.amounts" placeholder="可选" />
          </FormItem>
          <FormItem label="区域">
            <Input v-model:value="gameForm.regions" placeholder="多个区域用逗号分隔" />
          </FormItem>
          <FormItem label="货币图标">
            <Input v-model:value="gameForm.currencyIcon" placeholder="可选" />
          </FormItem>
        </div>
        <FormItem label="封面">
          <Input v-model:value="gameForm.cover" placeholder="请输入封面 URL" />
        </FormItem>
        <FormItem label="预览地址">
          <Input v-model:value="gameForm.previewUrl" placeholder="请输入预览地址" />
        </FormItem>
        <FormItem label="包地址">
          <Input v-model:value="gameForm.packageUrl" placeholder="请输入包地址" />
        </FormItem>
        <FormItem label="包版本">
          <Input v-model:value="gameForm.packageVersion" placeholder="请输入包版本" />
        </FormItem>
      </Form>
    </Modal>
  </Page>
</template>

<style scoped>
.content-card {
  margin-top: 16px;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 16px;
}

.pager {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}

.cover {
  width: 50px;
  height: 50px;
  object-fit: cover;
  border-radius: 6px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 16px;
}

.provider-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.hint {
  color: rgb(100 116 139);
  line-height: 32px;
}

.link-cell {
  display: inline-block;
  max-width: 340px;
  overflow: hidden;
  color: rgb(37 99 235);
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 1200px) {
  .provider-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 900px) {
  .form-grid,
  .provider-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
</style>
