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

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

import {
  activateLingxianProviderProfile,
  fetchLingxianCatalog,
  getLingxianProviderConfig,
  importLingxianCatalog,
  pageLingxianCatalog,
  saveLingxianProviderConfig,
} from '#/api/legacy/baishun-game';
import { getAllowedSysOrigins } from '#/views/system/shared';

import {
  Button,
  Card,
  Collapse,
  CollapsePanel,
  Form,
  FormItem,
  Input,
  Pagination,
  Select,
  Table,
  Tag,
  message,
} from 'antdv-next';

defineOptions({ name: 'OperateLingxianConfig' });

const defaultGameListUrl =
  'https://sg-test.leadercc.com/yumichat_games/test_game_list.json';

function createProviderForm(sysOrigin = '') {
  return {
    appKey: '',
    gameListUrl: defaultGameListUrl,
    profile: 'PROD',
    sysOrigin,
    testRoomId: '',
    testToken: '',
    testUid: '',
  };
}

const accessStore = useAccessStore();
const sysOriginOptions = computed(() => {
  const options = getAllowedSysOrigins(accessStore.accessCodes || []);
  return options.length > 0 ? options : getAllowedSysOrigins([]);
});
const profileOptions = [
  { label: '正式环境', value: 'PROD' },
  { label: '测试环境', value: 'TEST' },
];
const importShowcaseOptions = [
  { label: '默认上架', value: true as any },
  { label: '默认下架', value: false as any },
];

const contextQuery = reactive({ profile: 'PROD', sysOrigin: '' });
const providerForm = reactive(createProviderForm());
const catalogQuery = reactive<Record<string, any>>({
  cursor: 1,
  keyword: '',
  limit: 20,
});

const providerLoading = ref(false);
const providerSaving = ref(false);
const catalogLoading = ref(false);
const catalogFetching = ref(false);
const catalogImporting = ref(false);
const profileActivating = ref(false);
const totalCatalog = ref(0);
const catalogList = ref<Array<Record<string, any>>>([]);
const selectedCatalogKeys = ref<Array<string>>([]);
const activeProfile = ref('PROD');
const importDefaultShowcase = ref(true as any);

const isCurrentProfileActive = computed(
  () => activeProfile.value === contextQuery.profile,
);
const activeProfileLabel = computed(
  () =>
    profileOptions.find((item) => item.value === activeProfile.value)?.label ||
    activeProfile.value,
);

const catalogColumns = [
  { 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: 90 },
  { dataIndex: 'added', key: 'added', title: '统一游戏列表', width: 140 },
  { dataIndex: 'downloadUrl', key: 'downloadUrl', title: '入口地址', width: 440 },
  { dataIndex: 'previewUrl', key: 'previewUrl', title: '半屏地址', width: 440 },
  { dataIndex: 'updateTime', key: 'updateTime', title: '更新时间', width: 180 },
];

const catalogRowSelection = computed(() => ({
  selectedRowKeys: selectedCatalogKeys.value,
  onChange: (keys: Array<number | string>) => {
    selectedCatalogKeys.value = keys.map((item) => String(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, contextQuery.profile],
  ([sysOrigin, profile]) => {
    if (!sysOrigin || !profile) {
      return;
    }
    Object.assign(providerForm, createProviderForm(sysOrigin), {
      profile,
      sysOrigin,
    });
    selectedCatalogKeys.value = [];
    void Promise.all([loadProviderConfig(), loadCatalog(true)]);
  },
  { immediate: true },
);

function applyProviderForm(record: Record<string, any>) {
  activeProfile.value = String(record.activeProfile || activeProfile.value || 'PROD');
  Object.assign(providerForm, createProviderForm(contextQuery.sysOrigin), {
    ...record,
    gameListUrl: record.gameListUrl || defaultGameListUrl,
    profile: contextQuery.profile,
    sysOrigin: contextQuery.sysOrigin,
  });
}

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

async function persistProviderConfig(showSuccess = true) {
  providerForm.gameListUrl =
    String(providerForm.gameListUrl || '').trim() || defaultGameListUrl;
  if (!contextQuery.sysOrigin || !providerForm.gameListUrl || !providerForm.appKey) {
    message.warning('请补全灵仙游戏列表地址和 Key');
    return false;
  }
  providerSaving.value = true;
  try {
    const result = await saveLingxianProviderConfig({
      ...providerForm,
      profile: contextQuery.profile,
      sysOrigin: contextQuery.sysOrigin,
    });
    applyProviderForm(result || providerForm);
    if (showSuccess) {
      message.success('灵仙配置已保存');
    }
    return true;
  } catch {
    return false;
  } finally {
    providerSaving.value = false;
  }
}

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

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

async function handleActivateProfile() {
  if (!(await persistProviderConfig(false))) {
    return;
  }
  profileActivating.value = true;
  try {
    const result = await activateLingxianProviderProfile({
      profile: contextQuery.profile,
      sysOrigin: contextQuery.sysOrigin,
    });
    applyProviderForm(result || providerForm);
    message.success(`已切换到${activeProfileLabel.value}`);
    await loadCatalog(true);
  } finally {
    profileActivating.value = false;
  }
}

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

async function handleImportSelected() {
  if (selectedCatalogKeys.value.length === 0) {
    message.warning('请选择要添加到统一游戏列表的灵仙游戏');
    return;
  }
  catalogImporting.value = true;
  try {
    const result = await importLingxianCatalog({
      profile: contextQuery.profile,
      sysOrigin: contextQuery.sysOrigin,
      vendorGameIds: selectedCatalogKeys.value,
      defaultShowcase: importDefaultShowcase.value,
    });
    selectedCatalogKeys.value = [];
    message.success(
      `添加完成：新增 ${Number(result.imported || 0)}，已存在 ${Number(result.existing || 0)}`,
    );
    await 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="app 侧只读取当前启用环境。">
            <Select
              v-model:value="contextQuery.profile"
              :options="profileOptions"
              option-label-prop="label"
            />
          </FormItem>
          <FormItem label="游戏列表地址">
            <Input
              v-model:value="providerForm.gameListUrl"
              :placeholder="defaultGameListUrl"
            />
          </FormItem>
          <FormItem label="Key">
            <Input
              v-model:value="providerForm.appKey"
              placeholder="请输入灵仙签名 Key"
              type="password"
            />
          </FormItem>
        </div>
        <Collapse class="test-user-collapse" ghost>
          <CollapsePanel key="test-user" header="测试用户">
            <div class="form-grid">
              <FormItem label="UID">
                <Input v-model:value="providerForm.testUid" placeholder="可选" />
              </FormItem>
              <FormItem label="Token">
                <Input
                  v-model:value="providerForm.testToken"
                  placeholder="可选"
                  type="password"
                />
              </FormItem>
              <FormItem label="RoomID">
                <Input v-model:value="providerForm.testRoomId" placeholder="可选" />
              </FormItem>
            </div>
          </CollapsePanel>
        </Collapse>
        <div class="toolbar">
          <Button
            type="primary"
            :loading="providerSaving"
            @click="persistProviderConfig(true)"
          >
            保存配置
          </Button>
          <Button
            :disabled="isCurrentProfileActive"
            :loading="profileActivating"
            @click="handleActivateProfile"
          >
            启用此环境
          </Button>
          <Button :loading="catalogFetching" @click="handleFetchCatalog">
            获取灵仙游戏列表
          </Button>
          <Tag :color="isCurrentProfileActive ? 'success' : 'warning'">
            当前启用：{{ activeProfileLabel }}
          </Tag>
        </div>
      </Form>
    </Card>

    <Card class="content-card" title="灵仙目录">
      <div class="toolbar">
        <Input
          v-model:value="catalogQuery.keyword"
          placeholder="搜索目录名称 / 内部ID / 灵仙ID"
          style="width: 280px"
          @pressEnter="loadCatalog(true)"
        />
        <Button :loading="catalogLoading" type="primary" @click="loadCatalog(true)">
          搜索
        </Button>
        <Button :loading="catalogFetching" @click="handleFetchCatalog">
          重新获取目录
        </Button>
        <Select
          v-model:value="importDefaultShowcase"
          :options="importShowcaseOptions"
          style="width: 120px"
        />
        <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: 1780 }"
      >
        <template #bodyCell="{ column, record }">
          <template v-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 ? '已进入统一游戏列表' : '未添加' }}
            </Tag>
          </template>
          <template v-else-if="column.key === 'downloadUrl' || column.key === 'previewUrl'">
            <a
              v-if="record[column.key]"
              :href="record[column.key]"
              class="link-cell"
              rel="noreferrer"
              target="_blank"
            >
              {{ record[column.key] }}
            </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>
    </Card>
  </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;
}

.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));
}

.test-user-collapse {
  margin-bottom: 12px;
}

.link-cell {
  display: inline-block;
  max-width: 420px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

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