<script lang="ts" setup>
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import DetailDialog from './components/detail.vue';
import EditDialog from './components/edit.vue';
import DeleteDialog from './components/delete.vue';
import ActivationRecords from './components/activationRecords.vue';
import ExtractRecords from './components/extractRecords.vue';
import {
  activateCursorEquipment,
  addCursorEquipment,
  deleteCursorEquipment,
  getCursorEquipmentActivationRecords,
  getCursorEquipmentDetail,
  getCursorEquipmentExtractRecords,
  getCursorEquipmentList,
  updateCursorEquipment,
} from '@/api/cursorEquipment';

type EquipmentRow = Record<string, any>;

const loading = ref(false);
const actionLoading = ref(false);
const detailVisible = ref(false);
const editVisible = ref(false);
const deleteVisible = ref(false);
const activationVisible = ref(false);
const extractVisible = ref(false);
const currentRow = ref<EquipmentRow | null>(null);
const selectedRows = ref<EquipmentRow[]>([]);
const tableData = ref<EquipmentRow[]>([]);
const total = ref(0);
const isMobile = ref(false);

const query = reactive({
  keyword: '',
  status: '',
  os: '',
});

const pagination = reactive({
  page: 1,
  pageSize: 20,
});

const activationState = reactive({
  loading: false,
  records: [] as EquipmentRow[],
  total: 0,
  page: 1,
  pageSize: 20,
});

const extractState = reactive({
  loading: false,
  records: [] as EquipmentRow[],
  total: 0,
  page: 1,
  pageSize: 20,
});

const statusOptions = [
  { label: '未激活', value: 'inactive' },
  { label: '正常', value: 'active' },
  { label: '禁用', value: 'disabled' },
  { label: '已过期', value: 'expired' },
];

const osOptions = [
  { label: 'Windows', value: 'Windows' },
  { label: 'macOS', value: 'macOS' },
  { label: 'Linux', value: 'Linux' },
  { label: '其他', value: 'Other' },
];

const statusMap: Record<string, { label: string; type: string }> = {
  active: { label: '正常', type: 'success' },
  inactive: { label: '未激活', type: 'info' },
  disabled: { label: '禁用', type: 'danger' },
  expired: { label: '已过期', type: 'warning' },
};

const summary = computed(() => {
  const active = tableData.value.filter((item) => item.status === 'active').length;
  const inactive = tableData.value.filter((item) => item.status === 'inactive').length;
  const disabled = tableData.value.filter((item) => item.status === 'disabled').length;
  const expired = tableData.value.filter((item) => item.status === 'expired').length;
  return [
    { label: '当前页设备', value: tableData.value.length, type: 'primary' },
    { label: '正常设备', value: active, type: 'success' },
    { label: '未激活', value: inactive, type: 'info' },
    { label: '禁用/过期', value: disabled + expired, type: 'danger' },
  ];
});

watch(
  () => [query.keyword, query.status, query.os],
  () => {
    pagination.page = 1;
    fetchList();
  },
);

watch(
  () => [pagination.page, pagination.pageSize],
  () => {
    fetchList();
  },
);

watch(
  () => [activationState.page, activationState.pageSize],
  () => {
    if (activationVisible.value) fetchActivationRecords();
  },
);

watch(
  () => [extractState.page, extractState.pageSize],
  () => {
    if (extractVisible.value) fetchExtractRecords();
  },
);

function pick(raw: any, ...keys: string[]) {
  for (const key of keys) {
    if (raw?.[key] !== undefined && raw?.[key] !== null) return raw[key];
  }
  return '';
}

function formatTime(value: any) {
  if (!value) return '';
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return String(value);
  const p = (v: number) => String(v).padStart(2, '0');
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
}

function normalizeRow(raw: any): EquipmentRow {
  const status = String(pick(raw, 'status', 'Status') || 'inactive');
  return {
    id: pick(raw, 'id', 'ID', 'Id'),
    name: pick(raw, 'name', 'device_name', 'deviceName', 'Name', 'DeviceName'),
    deviceNo: pick(raw, 'device_no', 'deviceNo', 'DeviceNo', 'serial_no', 'serialNo'),
    machineCode: pick(raw, 'machine_code', 'machineCode', 'MachineCode', 'fingerprint'),
    licenseCode: pick(raw, 'license_code', 'licenseCode', 'LicenseCode'),
    os: pick(raw, 'os', 'OS', 'platform', 'Platform'),
    version: pick(raw, 'version', 'Version', 'client_version', 'clientVersion'),
    account: pick(raw, 'account', 'Account', 'email', 'Email'),
    owner: pick(raw, 'owner', 'Owner', 'user_name', 'userName', 'tenant_name', 'tenantName'),
    status,
    activationCount: Number(pick(raw, 'activation_count', 'activationCount', 'ActivationCount') || 0),
    extractCount: Number(pick(raw, 'extract_count', 'extractCount', 'ExtractCount') || 0),
    lastActivatedAt: formatTime(pick(raw, 'last_activated_at', 'lastActivatedAt', 'activated_at')),
    lastExtractedAt: formatTime(pick(raw, 'last_extracted_at', 'lastExtractedAt', 'extracted_at')),
    expiredAt: formatTime(pick(raw, 'expired_at', 'expiredAt', 'expire_time', 'expireTime')),
    createdAt: formatTime(pick(raw, 'create_time', 'created_at', 'createdAt', 'CreatedAt')),
    remark: pick(raw, 'remark', 'Remark'),
    raw,
  };
}

function normalizeRecord(raw: any): EquipmentRow {
  return {
    id: pick(raw, 'id', 'ID', 'Id'),
    status: pick(raw, 'status', 'Status', 'result', 'Result'),
    account: pick(raw, 'account', 'Account', 'email', 'Email'),
    platform: pick(raw, 'platform', 'Platform', 'source', 'Source'),
    type: pick(raw, 'type', 'Type', 'data_type', 'dataType'),
    content: pick(raw, 'content', 'Content', 'extract_content', 'extractContent', 'token', 'Token'),
    ip: pick(raw, 'ip', 'IP', 'client_ip', 'clientIp'),
    clientVersion: pick(raw, 'client_version', 'clientVersion', 'version', 'Version'),
    createdAt: formatTime(pick(raw, 'create_time', 'created_at', 'createdAt', 'CreatedAt')),
    remark: pick(raw, 'remark', 'Remark', 'message', 'Message'),
    raw,
  };
}

function statusLabel(status: string) {
  return statusMap[status]?.label || status || '-';
}

function statusTagType(status: string) {
  return statusMap[status]?.type || 'info';
}

function resetQuery() {
  query.keyword = '';
  query.status = '';
  query.os = '';
}

function handleSelectionChange(rows: EquipmentRow[]) {
  selectedRows.value = rows;
}

async function fetchList() {
  loading.value = true;
  try {
    const res = await getCursorEquipmentList({
      page: pagination.page,
      pageSize: pagination.pageSize,
      keyword: query.keyword || undefined,
      status: query.status || undefined,
      os: query.os || undefined,
    });
    if (res?.code !== 200) {
      ElMessage.error(res?.msg || '获取设备列表失败');
      return;
    }
    const list = Array.isArray(res?.data?.list) ? res.data.list : Array.isArray(res?.data) ? res.data : [];
    tableData.value = list.map(normalizeRow);
    total.value = Number(res?.data?.total || list.length || 0);
  } finally {
    loading.value = false;
  }
}

async function openDetail(row: EquipmentRow) {
  loading.value = true;
  try {
    const res = await getCursorEquipmentDetail(row.id);
    if (res?.code === 200) {
      currentRow.value = normalizeRow(res.data || row.raw || row);
    } else {
      currentRow.value = row;
      ElMessage.warning(res?.msg || '详情接口异常，已展示列表数据');
    }
    detailVisible.value = true;
  } finally {
    loading.value = false;
  }
}

function openAdd() {
  currentRow.value = null;
  editVisible.value = true;
}

function openEdit(row: EquipmentRow) {
  currentRow.value = row;
  editVisible.value = true;
}

function openDelete(row: EquipmentRow) {
  currentRow.value = row;
  deleteVisible.value = true;
}

async function handleSave(payload: EquipmentRow) {
  actionLoading.value = true;
  try {
    const api = payload.id ? updateCursorEquipment : addCursorEquipment;
    const res = await api(payload);
    if (res?.code !== 200) {
      ElMessage.error(res?.msg || '保存失败');
      return;
    }
    ElMessage.success(payload.id ? '设备已更新' : '设备已新增');
    editVisible.value = false;
    await fetchList();
  } finally {
    actionLoading.value = false;
  }
}

async function handleDelete() {
  if (!currentRow.value?.id) return;
  actionLoading.value = true;
  try {
    const res = await deleteCursorEquipment(currentRow.value.id);
    if (res?.code !== 200) {
      ElMessage.error(res?.msg || '删除失败');
      return;
    }
    ElMessage.success('设备已删除');
    deleteVisible.value = false;
    await fetchList();
  } finally {
    actionLoading.value = false;
  }
}

async function handleActivate(row: EquipmentRow) {
  try {
    await ElMessageBox.confirm(`确认激活设备「${row.name || row.deviceNo || row.id}」？`, '激活设备', {
      type: 'info',
      confirmButtonText: '确认激活',
      cancelButtonText: '取消',
    });
  } catch {
    return;
  }

  loading.value = true;
  try {
    const res = await activateCursorEquipment({ id: row.id });
    if (res?.code !== 200) {
      ElMessage.error(res?.msg || '激活失败');
      return;
    }
    ElMessage.success('设备已激活');
    await fetchList();
  } finally {
    loading.value = false;
  }
}

function openActivationRecords(row: EquipmentRow) {
  currentRow.value = row;
  activationState.page = 1;
  activationState.records = [];
  activationState.total = 0;
  activationVisible.value = true;
}

function openExtractRecords(row: EquipmentRow) {
  currentRow.value = row;
  extractState.page = 1;
  extractState.records = [];
  extractState.total = 0;
  extractVisible.value = true;
}

async function fetchActivationRecords() {
  if (!currentRow.value?.id) return;
  activationState.loading = true;
  try {
    const res = await getCursorEquipmentActivationRecords({
      equipmentId: currentRow.value.id,
      page: activationState.page,
      pageSize: activationState.pageSize,
    });
    if (res?.code !== 200) {
      ElMessage.error(res?.msg || '获取激活记录失败');
      return;
    }
    const list = Array.isArray(res?.data?.list) ? res.data.list : Array.isArray(res?.data) ? res.data : [];
    activationState.records = list.map(normalizeRecord);
    activationState.total = Number(res?.data?.total || list.length || 0);
  } finally {
    activationState.loading = false;
  }
}

async function fetchExtractRecords() {
  if (!currentRow.value?.id) return;
  extractState.loading = true;
  try {
    const res = await getCursorEquipmentExtractRecords({
      equipmentId: currentRow.value.id,
      page: extractState.page,
      pageSize: extractState.pageSize,
    });
    if (res?.code !== 200) {
      ElMessage.error(res?.msg || '获取提取记录失败');
      return;
    }
    const list = Array.isArray(res?.data?.list) ? res.data.list : Array.isArray(res?.data) ? res.data : [];
    extractState.records = list.map(normalizeRecord);
    extractState.total = Number(res?.data?.total || list.length || 0);
  } finally {
    extractState.loading = false;
  }
}

function updateDeviceType() {
  isMobile.value = window.innerWidth <= 768;
}

onMounted(() => {
  updateDeviceType();
  window.addEventListener('resize', updateDeviceType);
  fetchList();
});

onUnmounted(() => {
  window.removeEventListener('resize', updateDeviceType);
});
</script>

<template>
  <div class="cursor-equipment-page">
    <el-card shadow="never">
      <template #header>
        <div class="card-header">
          <span>设备管理（Cursor）</span>
          <el-button type="primary" @click="openAdd">新增设备</el-button>
        </div>
      </template>

      <div class="summary-grid">
        <div v-for="item in summary" :key="item.label" class="summary-card">
          <div class="summary-label">{{ item.label }}</div>
          <div class="summary-value" :class="`is-${item.type}`">{{ item.value }}</div>
        </div>
      </div>

      <div class="toolbar">
        <div class="toolbar-left">
          <el-input
            v-model="query.keyword"
            placeholder="搜索设备名称 / 编号 / 机器码 / 账号"
            clearable
            class="w-300"
          />
          <el-select v-model="query.status" placeholder="设备状态" clearable class="w-140">
            <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-select v-model="query.os" placeholder="系统平台" clearable class="w-140">
            <el-option v-for="item in osOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-button @click="resetQuery">重置</el-button>
        </div>
        <div class="toolbar-right">
          <el-button :loading="loading" @click="fetchList">刷新</el-button>
        </div>
      </div>

      <div class="table-scroll">
        <el-table
          v-loading="loading"
          class="equipment-table"
          :data="tableData"
          border
          stripe
          style="width: 100%"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="52" />
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column label="设备信息" min-width="220">
            <template #default="{ row }">
              <div class="device-name">{{ row.name || '-' }}</div>
              <div class="device-no">编号：{{ row.deviceNo || '-' }}</div>
            </template>
          </el-table-column>
          <el-table-column prop="machineCode" label="机器码" min-width="220" show-overflow-tooltip />
          <el-table-column label="状态" width="100" align="center">
            <template #default="{ row }">
              <el-tag :type="statusTagType(row.status)">
                {{ statusLabel(row.status) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="os" label="系统" width="100" align="center">
            <template #default="{ row }">{{ row.os || '-' }}</template>
          </el-table-column>
          <el-table-column prop="version" label="版本" width="110" align="center">
            <template #default="{ row }">{{ row.version || '-' }}</template>
          </el-table-column>
          <el-table-column prop="account" label="绑定账号" min-width="160" show-overflow-tooltip />
          <el-table-column prop="owner" label="归属用户" min-width="130" show-overflow-tooltip />
          <el-table-column label="激活/提取" width="120" align="center">
            <template #default="{ row }">
              <div class="count-line">
                <span>激活 {{ row.activationCount }}</span>
                <span>提取 {{ row.extractCount }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="lastActivatedAt" label="最后激活" width="180">
            <template #default="{ row }">{{ row.lastActivatedAt || '-' }}</template>
          </el-table-column>
          <el-table-column prop="expiredAt" label="过期时间" width="180">
            <template #default="{ row }">{{ row.expiredAt || '-' }}</template>
          </el-table-column>
          <el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
          <el-table-column label="操作" width="310" fixed="right" align="center">
            <template #default="{ row }">
              <el-button link type="primary" @click="openDetail(row)">详情</el-button>
              <el-button link type="warning" @click="openEdit(row)">编辑</el-button>
              <el-button v-if="row.status !== 'active'" link type="success" @click="handleActivate(row)">激活</el-button>
              <el-button link type="info" @click="openActivationRecords(row)">激活记录</el-button>
              <el-button link type="info" @click="openExtractRecords(row)">提取记录</el-button>
              <el-button link type="danger" @click="openDelete(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="pager">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.pageSize"
          background
          :layout="isMobile ? 'prev, pager, next' : 'total, sizes, prev, pager, next, jumper'"
          :page-sizes="[20, 50, 100]"
          :total="total"
        />
      </div>
    </el-card>

    <DetailDialog v-model="detailVisible" :row="currentRow" />

    <EditDialog
      v-model="editVisible"
      :row="currentRow"
      :loading="actionLoading"
      @submit="handleSave"
    />

    <DeleteDialog
      v-model="deleteVisible"
      :row="currentRow"
      :loading="actionLoading"
      @confirm="handleDelete"
    />

    <ActivationRecords
      v-model="activationVisible"
      v-model:page="activationState.page"
      v-model:page-size="activationState.pageSize"
      :row="currentRow"
      :loading="activationState.loading"
      :records="activationState.records"
      :total="activationState.total"
      @refresh="fetchActivationRecords"
    />

    <ExtractRecords
      v-model="extractVisible"
      v-model:page="extractState.page"
      v-model:page-size="extractState.pageSize"
      :row="currentRow"
      :loading="extractState.loading"
      :records="extractState.records"
      :total="extractState.total"
      @refresh="fetchExtractRecords"
    />
  </div>
</template>

<style lang="less" scoped>
.cursor-equipment-page {
  padding: 12px;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(120px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}

.summary-card {
  padding: 14px 16px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  background: #fbfcff;
}

.summary-label {
  color: #909399;
  font-size: 13px;
  margin-bottom: 8px;
}

.summary-value {
  font-size: 24px;
  font-weight: 700;
  color: #409eff;

  &.is-success {
    color: #67c23a;
  }

  &.is-info {
    color: #909399;
  }

  &.is-danger {
    color: #f56c6c;
  }
}

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.toolbar-left,
.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.w-300 {
  width: 300px;
}

.w-140 {
  width: 140px;
}

.table-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.equipment-table {
  min-width: 1280px;
}

.device-name {
  font-weight: 600;
  color: #303133;
  line-height: 1.6;
}

.device-no {
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
}

.count-line {
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: #606266;
  font-size: 12px;
}

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

@media (max-width: 768px) {
  .cursor-equipment-page {
    padding: 8px;
  }

  .card-header {
    align-items: flex-start;
    flex-direction: column;
  }

  .summary-grid {
    grid-template-columns: repeat(2, minmax(120px, 1fr));
  }

  .toolbar-left,
  .toolbar-right,
  .w-300,
  .w-140 {
    width: 100%;
  }

  .toolbar-right .el-button {
    width: 100%;
  }

  .pager {
    justify-content: center;
  }
}
</style>
