import { computed, nextTick, onMounted, reactive, ref } from 'vue/dist/vue.esm-bundler.js';
import { ElMessage, ElMessageBox } from 'element-plus';
import zhCn from 'element-plus/es/locale/lang/zh-cn.mjs';
import { authState } from '../auth/auth-store.js';
import { createPhoneAsset, deletePhoneAsset, listPhoneAssets, updatePhoneAsset } from './phone-api-client.js';

/**
 * 代码作用（白话）：显示手机号资产列表，并管理新增、编辑、保存和删除弹窗状态。
 * 关联文件：phone-api-client.js、PhoneAssetController.java、app.css。
 * 关联逻辑（调用链/数据流）：路由进入 -> 页面方法 -> 前端接口客户端 -> 后端接口 -> 列表或弹窗更新。
 */
export default {
  /**
   * 代码作用（白话）：创建列表、筛选、弹窗和表单所需的响应式数据及页面操作方法。
   * 关联文件：phone-api-client.js、PhoneAssetController.java、app.css。
   * 关联逻辑（调用链/数据流）：路由进入 -> setup 初始化 -> 用户操作 -> 接口调用或弹窗状态变化。
   */
  setup() {
    const elementLocale = zhCn;
    const loading = ref(false);
    const saving = ref(false);
    const records = ref([]);
    const total = ref(0);
    const dialogVisible = ref(false);
    const editingId = ref(null);
    /** 代码作用（白话）：把当前手机号资产权限转换为是否展示写操作；关联文件：auth-store.js、PhoneAssetController.java。关联逻辑（调用链/数据流）：/api/auth/me -> EDIT 判断 -> 新增/编辑/删除控件 -> 后端二次校验。 */
    const canEdit = computed(() => authState.user?.pagePermissions?.['phone-assets'] === 'EDIT');
    const filters = reactive({ page: 1, size: 20, phoneNumber: '', iccid: '', realNameOwner: '', disposalStatus: 'ALL' });
    let searchTimer = null;
    let latestRequest = 0;
    const form = reactive({
      phoneNumber: '',
      cardType: '',
      iccid: '',
      realNameOwner: '',
      managementType: '',
      disposalStatus: '正常使用',
      deviceId: null
    });

    /**
     * 代码作用（白话）：加载当前筛选条件下的一页手机号资产。
     * 关联文件：phone-api-client.js、PhoneAssetController.java。
     * 关联逻辑（调用链/数据流）：查询/分页/保存成功 -> listPhoneAssets -> GET 接口 -> records 与 total。
     */
    async function loadPage() {
      const requestId = ++latestRequest;
      loading.value = true;
      try {
        const result = await listPhoneAssets(filters);
        if (requestId !== latestRequest) return;
        records.value = result.records;
        total.value = result.total;
      } catch (error) {
        if (requestId === latestRequest) ElMessage.error(error.message);
      } finally {
        if (requestId === latestRequest) loading.value = false;
      }
    }

    /**
     * 代码作用（白话）：把手机号变成最多 11 位数字，供输入和粘贴共用。
     * 关联文件：PhoneAssetSaveRequest.java、PhoneAssetService.java。
     * 关联逻辑（调用链/数据流）：浏览器输入 -> 过滤数字 -> form.phoneNumber -> 保存请求 -> 后端格式校验。
     */
    function normalizePhoneNumber(value) {
      return String(value || '').replace(/\D/g, '').slice(0, 11);
    }

    /**
     * 代码作用（白话）：把 ICCID 变成最多 20 位的数字或英文字母，供输入和粘贴共用。
     * 关联文件：PhoneAssetView.js、phone-api-client.js。
     * 关联逻辑（调用链/数据流）：浏览器输入 -> 过滤有效字符 -> form.iccid -> 保存请求。
     */
    function normalizeIccid(value) {
      return String(value || '').replace(/[^a-zA-Z0-9]/g, '').slice(0, 20);
    }

    /**
     * 代码作用（白话）：处理手机号实时输入，确保计数器只计算有效数字。
     * 关联文件：PhoneAssetView.js、PhoneAssetService.java。
     * 关联逻辑（调用链/数据流）：手机号 input 事件 -> normalizePhoneNumber -> form.phoneNumber -> 输入框 suffix。
     */
    function limitPhoneNumber(value) {
      form.phoneNumber = normalizePhoneNumber(value);
    }

    /**
     * 代码作用（白话）：处理 ICCID 实时输入，确保计数器只计算有效的数字和英文字母。
     * 关联文件：PhoneAssetView.js、phone-api-client.js。
     * 关联逻辑（调用链/数据流）：ICCID input 事件 -> normalizeIccid -> form.iccid -> 输入框 suffix。
     */
    function limitIccid(value) {
      form.iccid = normalizeIccid(value);
    }

    /**
     * 代码作用（白话）：将粘贴文字插入当前选择位置后再过滤，避免浏览器 maxlength 先截掉有效字符。
     * 关联文件：PhoneAssetView.js、app.css。
     * 关联逻辑（调用链/数据流）：paste 事件 -> 原始剪贴板文字 -> 过滤方法 -> form 字段 -> 框内计数器。
     */
    function replaceSelectionWithPastedValue(event, fieldName, normalizeValue) {
      const pastedText = event.clipboardData?.getData('text');
      if (pastedText === undefined) return;
      event.preventDefault();
      const input = event.target;
      const start = input.selectionStart ?? input.value.length;
      const end = input.selectionEnd ?? input.value.length;
      const nextValue = input.value.slice(0, start) + pastedText + input.value.slice(end);
      form[fieldName] = normalizeValue(nextValue);
    }

    /**
     * 代码作用（白话）：处理手机号粘贴并保留前 11 位有效数字。
     * 关联文件：PhoneAssetView.js、PhoneAssetService.java。
     * 关联逻辑（调用链/数据流）：手机号 paste -> replaceSelectionWithPastedValue -> form.phoneNumber -> 保存校验。
     */
    function handlePhonePaste(event) {
      replaceSelectionWithPastedValue(event, 'phoneNumber', normalizePhoneNumber);
    }

    /**
     * 代码作用（白话）：处理 ICCID 粘贴并保留前 20 个有效字符。
     * 关联文件：PhoneAssetView.js、phone-api-client.js。
     * 关联逻辑（调用链/数据流）：ICCID paste -> replaceSelectionWithPastedValue -> form.iccid -> 保存请求。
     */
    function handleIccidPaste(event) {
      replaceSelectionWithPastedValue(event, 'iccid', normalizeIccid);
    }

    /**
     * 代码作用（白话）：把表单恢复成新增手机号资产时原有的默认值。
     * 关联文件：PhoneAssetView.js、PhoneAssetSaveRequest.java。
     * 关联逻辑（调用链/数据流）：新增按钮 -> resetForm -> form -> 弹窗；保存成功后的下一次新增同样复用。
     */
    function resetForm() {
      Object.assign(form, {
        phoneNumber: '',
        cardType: '',
        iccid: '',
        realNameOwner: '',
        managementType: '',
        disposalStatus: '正常使用',
        deviceId: null
      });
    }

    /**
     * 代码作用（白话）：在弹窗显示完成后把内部内容滚动条移回顶部。
     * 关联文件：PhoneAssetView.js、app.css。
     * 关联逻辑（调用链/数据流）：Element Plus opened 事件 -> 弹窗专属类 -> 内容区域 scrollTop=0。
     */
    async function resetDialogScroll() {
      await nextTick();
      const body = document.querySelector('.phone-asset-modal .el-dialog__body');
      if (body) body.scrollTop = 0;
    }

    /**
     * 代码作用（白话）：打开空白的新增手机号资产弹窗。
     * 关联文件：PhoneAssetView.js、phone-api-client.js。
     * 关联逻辑（调用链/数据流）：点击新增 -> resetForm -> dialogVisible=true -> Element Plus 弹窗显示。
     */
    function openCreate() {
      editingId.value = null;
      resetForm();
      dialogVisible.value = true;
    }

    /**
     * 代码作用（白话）：用当前表格行的数据回填同一个编辑弹窗。
     * 关联文件：PhoneAssetView.js、phone-api-client.js。
     * 关联逻辑（调用链/数据流）：点击编辑 -> row -> form -> PUT 保存。
     */
    function openEdit(row) {
      editingId.value = row.id;
      Object.assign(form, {
        phoneNumber: normalizePhoneNumber(row.phoneNumber),
        cardType: row.cardType || '',
        iccid: normalizeIccid(row.iccid),
        realNameOwner: row.realNameOwner || '',
        managementType: row.managementType || '',
        disposalStatus: row.disposalStatus || '正常使用',
        deviceId: row.deviceId ?? null
      });
      dialogVisible.value = true;
    }

    /**
     * 代码作用（白话）：提交新增或编辑表单，成功后保持原有提示、关闭弹窗并刷新列表。
     * 关联文件：phone-api-client.js、PhoneAssetController.java。
     * 关联逻辑（调用链/数据流）：确认保存 -> POST/PUT -> 成功提示 -> dialogVisible=false -> loadPage。
     */
    async function submitForm() {
      saving.value = true;
      try {
        const payload = { ...form, phoneNumber: normalizePhoneNumber(form.phoneNumber) };
        if (editingId.value === null) await createPhoneAsset(payload);
        else await updatePhoneAsset(editingId.value, payload);
        ElMessage.success(editingId.value === null ? '新增成功' : '编辑成功');
        dialogVisible.value = false;
        await loadPage();
      } catch (error) {
        ElMessage.error(error.message);
      } finally {
        saving.value = false;
      }
    }

    /**
     * 代码作用（白话）：要求用户确认后删除一条手机号资产，并按原逻辑刷新列表。
     * 关联文件：phone-api-client.js、PhoneAssetController.java。
     * 关联逻辑（调用链/数据流）：删除按钮 -> 确认框 -> DELETE -> 成功提示 -> loadPage。
     */
    async function confirmDelete(row) {
      try {
        await ElMessageBox.confirm(`确认删除手机号 ${row.phoneNumber} 吗？`, '删除确认', { type: 'warning' });
        await deletePhoneAsset(row.id);
        ElMessage.success('删除成功');
        if (records.value.length === 1 && filters.page > 1) filters.page -= 1;
        await loadPage();
      } catch (error) {
        if (error !== 'cancel' && error !== 'close') ElMessage.error(error.message);
      }
    }

    /** 代码作用（白话）：停止输入约 300 毫秒后自动查询，避免连续输入反复请求。关联文件：PhoneAssetView.js、phone-api-client.js。关联逻辑（调用链/数据流）：输入事件 -> 防抖计时 -> loadPage -> GET 接口。 */
    function scheduleSearch() { window.clearTimeout(searchTimer); searchTimer = window.setTimeout(() => { filters.page = 1; loadPage(); }, 300); }
    /** 代码作用（白话）：把列表手机号筛选值限定为 11 位数字，粘贴内容也按相同规则处理。关联文件：PhoneAssetView.js、PhoneAssetService.java。关联逻辑（调用链/数据流）：手机号输入 -> limitSearchPhone -> scheduleSearch -> 后端号码匹配。 */
    function limitSearchPhone(value) { filters.phoneNumber = String(value || '').replace(/\D/g, '').slice(0, 11); scheduleSearch(); }
    /** 代码作用（白话）：按 Enter 时立刻执行当前筛选。关联文件：PhoneAssetView.js、phone-api-client.js。关联逻辑（调用链/数据流）：Enter -> 清除计时 -> page=1 -> loadPage。 */
    function submitSearch() { window.clearTimeout(searchTimer); filters.page = 1; loadPage(); }
    /** 代码作用（白话）：切换使用状态后马上查询，不等待输入防抖。关联文件：PhoneAssetView.js、phone-api-client.js。关联逻辑（调用链/数据流）：状态 change -> page=1 -> loadPage。 */
    /** Code purpose (plain language): restores the status filter to its explicit All selection after the clear icon is clicked. Related files: PhoneAssetView.js, phone-api-client.js. Data flow: clear icon -> ALL -> request omits status -> full list. */
    function restoreAllDisposalStatuses() { filters.disposalStatus = 'ALL'; submitSearch(); }
    function changeStatus() { submitSearch(); }
    /** 代码作用（白话）：清空所有筛选条件并恢复第一页列表。关联文件：PhoneAssetView.js、phone-api-client.js。关联逻辑（调用链/数据流）：重置 -> filters 默认值 -> loadPage。 */
    function resetSearch() { window.clearTimeout(searchTimer); Object.assign(filters, { page: 1, size: 20, phoneNumber: '', iccid: '', realNameOwner: '', disposalStatus: 'ALL' }); loadPage(); }
    /** 代码作用（白话）：切换页码并读取对应数据。关联文件：PhoneAssetView.js、phone-api-client.js。关联逻辑（调用链/数据流）：分页器 -> filters.page -> loadPage。 */
    function changePage(page) { filters.page = page; loadPage(); }
    /** 代码作用（白话）：切换每页条数后回到第一页查询。关联文件：PhoneAssetView.js、phone-api-client.js。关联逻辑（调用链/数据流）：每页条数 -> size/page -> loadPage。 */
    function changePageSize(size) { filters.size = size; filters.page = 1; loadPage(); }

    /**
     * 代码作用（白话）：页面首次显示时请求手机号资产列表。
     * 关联文件：PhoneAssetView.js、phone-api-client.js。
     * 关联逻辑（调用链/数据流）：组件挂载 -> onMounted 回调 -> loadPage -> 列表渲染。
     */
    /** Code purpose (plain language): converts stored disposal status values into the shorter labels required by the list UI. Related files: PhoneAssetService.java, PhoneAssetView.js. Data flow: API record -> formatDisposalStatus -> table/status option label. */
    function formatDisposalStatus(value) {
      if (value === '正常使用') return '正常';
      if (value === '已注销') return '注销';
      return value || '未设置';
    }
    onMounted(() => {
      loadPage();
    });

    return {
      changePage,
      changePageSize,
      changeStatus,
      canEdit,
      confirmDelete,
      dialogVisible,
      editingId,
      elementLocale,
      filters,
      formatDisposalStatus,
      form,
      handleIccidPaste,
      handlePhonePaste,
      limitIccid,
      limitPhoneNumber,
      limitSearchPhone,
      loading,
      openCreate,
      openEdit,
      records,
      resetDialogScroll,
      resetSearch,
      restoreAllDisposalStatuses,
      saving,
      scheduleSearch,
      submitForm,
      submitSearch,
      total
    };
  },
  template: `
    <el-config-provider :locale="elementLocale"><section class="phone-asset-page phone-asset-list-page">
      <header class="phone-asset-list-page__header"><h2>手机号资产</h2><el-button v-if="canEdit" class="phone-asset-list-page__add" type="primary" @click="openCreate">新增手机号资产</el-button></header>
      <section class="phone-asset-list-page__panel phone-asset-list-page__search" aria-label="筛选手机号资产"><el-form class="phone-asset-list-page__filters" @submit.prevent="submitSearch"><el-input v-model="filters.phoneNumber" maxlength="11" inputmode="numeric" placeholder="手机号前3位、后4位或完整号码" @input="limitSearchPhone" @keydown.enter.prevent="submitSearch" /><el-input v-model="filters.iccid" maxlength="20" placeholder="请输入 ICCID" @input="scheduleSearch" @keydown.enter.prevent="submitSearch" /><el-input v-model="filters.realNameOwner" placeholder="请输入实名人" @input="scheduleSearch" @keydown.enter.prevent="submitSearch" /><el-select v-model="filters.disposalStatus" placeholder="使用状态：" clearable @change="changeStatus" @clear="restoreAllDisposalStatuses"><template #prefix>使用状态：</template><el-option label="全部" value="ALL" /><el-option label="正常" value="正常使用" /><el-option label="闲置" value="闲置" /><el-option label="停机" value="停机" /><el-option label="注销" value="已注销" /></el-select><el-button @click="resetSearch">重置</el-button></el-form></section>
      <section class="phone-asset-list-page__panel phone-asset-list-page__table"><header class="phone-asset-list-page__table-header"><h3>资产列表</h3><span>共 {{ total }} 条</span></header><el-table v-loading="loading" :data="records" empty-text="暂无匹配数据" class="phone-asset-list-page__grid"><el-table-column prop="phoneNumber" label="手机号" min-width="150" show-overflow-tooltip /><el-table-column label="号码类型" min-width="120"><template #default="{ row }"><a v-if="row.numberType === 'EXTERNAL' && row.sourceAssetType === 'WECOM'" class="phone-asset-list-page__external-link" :href="'#/reference/wecom?phoneAssetId=' + row.id">外部号码</a><span v-else>{{ row.numberType === 'EXTERNAL' ? '外部号码' : '自有号码' }}</span></template></el-table-column><el-table-column prop="cardType" label="运营商" min-width="110" show-overflow-tooltip /><el-table-column prop="iccid" label="ICCID" min-width="220" show-overflow-tooltip /><el-table-column prop="realNameOwner" label="实名人" min-width="150" show-overflow-tooltip /><el-table-column prop="managementType" label="管理模式" min-width="120" show-overflow-tooltip /><el-table-column label="使用状态" min-width="130"><template #default="{ row }"><span class="phone-asset-list-page__status"><i :class="['phone-asset-list-page__status-dot', row.disposalStatus]"></i>{{ formatDisposalStatus(row.disposalStatus) }}</span></template></el-table-column><el-table-column prop="deviceId" label="关联设备（ID）" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit" label="操作" width="120"><template #default="{ row }"><span class="phone-asset-list-page__actions"><el-button link @click="openEdit(row)">编辑</el-button><el-button link type="danger" @click="confirmDelete(row)">删除</el-button></span></template></el-table-column></el-table><footer v-if="total" class="phone-asset-list-page__pagination"><span>共 {{ total }} 条</span><el-pagination layout="sizes, prev, pager, next, jumper" :current-page="filters.page" :page-size="filters.size" :page-sizes="[5,10,20,50]" :total="total" @current-change="changePage" @size-change="changePageSize" /></footer></section>
      <el-dialog v-model="dialogVisible" class="phone-asset-modal" modal-class="phone-asset-modal-mask" :title="editingId === null ? '新增手机号资产' : '编辑手机号资产'" width="560px" @opened="resetDialogScroll">
        <el-form class="phone-asset-modal__form" label-width="96px">
          <el-form-item class="phone-asset-modal__form-row" label="手机号" required>
          <el-input :model-value="form.phoneNumber" class="phone-asset-modal__count-input" maxlength="11" inputmode="numeric" autocomplete="off" placeholder="请输入手机号" @update:model-value="limitPhoneNumber" @paste="handlePhonePaste">
              <template #suffix><span class="phone-asset-modal__character-count" aria-live="polite">{{ form.phoneNumber.length }}/11</span></template>
            </el-input>
          </el-form-item>
          <el-form-item class="phone-asset-modal__form-row" label="卡类型">
            <el-select v-model="form.cardType" clearable placeholder="请选择" popper-class="phone-asset-modal__select-popper"><el-option label="移动" value="移动" /><el-option label="电信" value="电信" /><el-option label="联通" value="联通" /><el-option label="广电" value="广电" /><el-option label="虚拟号码" value="虚拟号码" /></el-select>
          </el-form-item>
          <el-form-item class="phone-asset-modal__form-row" label="ICCID">
            <el-input v-model="form.iccid" class="phone-asset-modal__count-input" maxlength="20" autocomplete="off" placeholder="请输入 ICCID" @input="limitIccid" @paste="handleIccidPaste">
              <template #suffix><span class="phone-asset-modal__character-count" aria-live="polite">{{ form.iccid.length }}/20</span></template>
            </el-input>
          </el-form-item>
          <el-form-item class="phone-asset-modal__form-row" label="实名归属"><el-input v-model="form.realNameOwner" maxlength="20" placeholder="请输入实名归属" /></el-form-item>
          <el-form-item class="phone-asset-modal__form-row" label="管理方式"><el-select v-model="form.managementType" clearable placeholder="请选择" popper-class="phone-asset-modal__select-popper"><el-option label="自有" value="自有" /><el-option label="租用" value="租用" /><el-option label="代运营" value="代运营" /></el-select></el-form-item>
          <el-form-item class="phone-asset-modal__form-row" label="处置状态"><el-select v-model="form.disposalStatus" placeholder="请选择" popper-class="phone-asset-modal__select-popper"><el-option label="正常" value="正常使用" /><el-option label="闲置" value="闲置" /><el-option label="停机" value="停机" /><el-option label="注销" value="已注销" /></el-select></el-form-item>
          <el-form-item class="phone-asset-modal__form-row" label="设备 ID"><el-input v-model.number="form.deviceId" type="number" placeholder="请输入设备 ID" /></el-form-item>
        </el-form>
        <template #footer>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="saving" @click="submitForm">确认保存</el-button>
        </template>
      </el-dialog>
    </section></el-config-provider>
  `
};
