<template>
  <!-- 纯数据组件 -->
  <div style="display:none"></div>
</template>

<script setup lang="ts">
/**
 * Power（PSU）悬浮信息 + 设置项上下文菜单
 */
import { onMounted, ref, reactive, defineEmits } from 'vue';
import axios from 'axios';
import { traduction } from '@/utils/language';

import { KV, MenuItem, CtxAction } from '../shared/types';
import { firstNonEmpty, fmt as u, normalizeBySuffixNumber as normalizeName } from '../shared/format';

type DeepSleep = 'On' | 'Off' | string;
type PowerModeApi = 'Sharing' | 'Active/Standby' | string;
type PowerModeUI = 'Sharing' | 'MainBackup' | string;

type SupplyRow = {
  Name?: string; Mode?: 'Active' | 'Standby' | string;
  Manufacturer?: string; PartNumber?: string; Model?: string;
  ManufactureDate?: string; ProductionDate?: string;
  OutputVoltage?: number | string; FirmwareVersion?: string;
  InputWatts?: number | string; SerialNumber?: string;
  LineInputVoltage?: number | string; PowerSupplyChannel?: string | number;
  PowerSupplyType?: string; PowerCapacityWatts?: number | string;
};

const emit = defineEmits<{ (e: 'psu-list', names: string[]): void }>();
const toUI = (m: PowerModeApi): PowerModeUI => (m === 'Active/Standby' ? 'MainBackup' : (m as PowerModeUI));
const toAPI = (m: PowerModeUI): PowerModeApi => (m === 'MainBackup' ? 'Active/Standby' : (m as PowerModeApi));

const names = ref<string[]>([]);
const list = ref<Array<{ name: string; mode: string }>>([]);
const infoMap = ref<Record<string, string>>({});
const detailMap = ref<Record<string, any>>({});
const summary = reactive<{ PowerMode: PowerModeApi; DeepSleep: DeepSleep }>({ PowerMode: 'Sharing', DeepSleep: 'Off' });

const GET_URL = '/UI/Rest/System/PowerSupply';
const patchPower = (payload: any) => axios.patch(GET_URL, payload, { withCredentials: true });

async function pullPower() {
  const { data } = await axios.get(GET_URL, { withCredentials: true });

  summary.PowerMode = (data?.PowerMode || 'Sharing') as PowerModeApi;
  summary.DeepSleep = (data?.DeepSleep || 'Off') as DeepSleep;

  let src: SupplyRow[] = [];
  if (Array.isArray(data?.SupplyList) && data.SupplyList.length) {
    src = data.SupplyList;
  } else if (Array.isArray(data?.ExpectedSupplyList)) {
    src = data.ExpectedSupplyList;
  }

  const nextNames: string[] = [];
  const nextList: Array<{ name: string; mode: string }> = [];
  const imap: Record<string, string> = {};
  const dmap: Record<string, any> = {};

  src.forEach((i, idx) => {
    const name = normalizeName(firstNonEmpty(i?.Name, `PSU${idx + 1}`), 'PSU') || `PSU${idx + 1}`;

    nextNames.push(name);
    nextList.push({ name, mode: String(firstNonEmpty(i?.Mode || '')) });

    const Manufacturer = firstNonEmpty(i?.Manufacturer);
    const PowerCapacityWatts = firstNonEmpty(i?.PowerCapacityWatts);
    imap[name] = [name, u(PowerCapacityWatts, 'W'), Manufacturer].filter(Boolean).join(' | ');

    const slotMatch = String(name).match(/(?<slot>\d+)$/);
    dmap[name] = {
      name,
      inputWatts: firstNonEmpty(i?.InputWatts),
      slot: Number(slotMatch?.groups?.slot || ''),
      manufacturer: Manufacturer,
      model: firstNonEmpty(i?.Model),
      serialNumber: firstNonEmpty(i?.SerialNumber),
      firmwareVersion: firstNonEmpty(i?.FirmwareVersion),
      partNumber: firstNonEmpty(i?.PartNumber),
      produceDate: firstNonEmpty(i?.ManufactureDate, i?.ProductionDate),
      powerCapacityWatts: PowerCapacityWatts,
      powerSupplyType: firstNonEmpty(i?.PowerSupplyType),
      lineInputVoltage: firstNonEmpty(i?.LineInputVoltage),
      outputVoltage: firstNonEmpty(i?.OutputVoltage),
    };
  });

  names.value = nextNames;
  list.value = nextList;
  infoMap.value = imap;
  detailMap.value = dmap;
  emit('psu-list', nextNames);
}

async function refresh() {
  await pullPower();
}

async function buildPairs(name: string) {
  const key = normalizeName(name, 'PSU');
  let d = detailMap.value[key];
  if (!d && names.value.length === 1) {
    d = detailMap.value[names.value[0]];
  }
  if (!d) {
    return [];
  }

  const pairs: KV[] = [
    { k: traduction('COMMON_NAME'), v: String(d.name || key) },
    { k: traduction('POWER_CURRENT'), v: u(d.inputWatts, 'W') },
    { k: traduction('POWER_SLOT'), v: String(d.slot) },
    { k: traduction('COMMON_MANUFACTURER'), v: String(d.manufacturer) },
    { k: traduction('PROCESSOR_MODEL'), v: String(d.model) },
    { k: traduction('COMMON_SERIALNUMBER'), v: String(d.serialNumber) },
    { k: traduction('COMMON_FIXED_VERSION'), v: String(d.firmwareVersion) },
    { k: traduction('OTHER_PART_NUMBER'), v: String(d.partNumber) },
    { k: traduction('PRODUCTION_DATE'), v: String(d.produceDate) },
    { k: traduction('POWER_CAPACITY_WATTS'), v: u(d.powerCapacityWatts, 'W') },
    { k: traduction('POWER_SUPPLY_TYPE'), v: String(d.powerSupplyType) },
    { k: traduction('POWER_LINE_INPUT_VOLTAGE'), v: u(d.lineInputVoltage, 'V') },
    { k: traduction('POWER_OUTPUT_VOLTAGE'), v: u(d.outputVoltage, 'V') },
  ];
  return pairs;
}

function getBasicText(name: string) {
  const key = normalizeName(name, 'PSU');
  return infoMap.value[key] ?? key;
}

function getNames(): string[] {
  return names.value.slice();
}

async function setPowerMode(modeUI: PowerModeUI) {
  const r: any = await patchPower({ PowerMode: toAPI(modeUI) });
  if (r?.data?.error) {
    return false;
  }
  await refresh();
  return true;
}

async function setMainBackupWithPrimary(psuName: string) {
  const tgt = normalizeName(psuName, 'PSU');
  const body = {
    PowerMode: toAPI('MainBackup'),
    SupplyList: names.value.map((nm) => ({ Name: nm, Mode: nm === tgt ? 'Active' : 'Standby' })),
  };
  const r: any = await patchPower(body);
  if (r?.data?.error) {
    return false;
  }
  await refresh();
  return true;
}

async function setPrimarySupply(psuName: string) {
  const tgt = normalizeName(psuName, 'PSU');
  const body = { SupplyList: names.value.map((nm) => ({ Name: nm, Mode: nm === tgt ? 'Active' : 'Standby' })) };
  const r: any = await patchPower(body);
  if (r?.data?.error) {
    return false;
  }
  await refresh();
  return true;
}

async function setDeepSleep(v: DeepSleep) {
  const r: any = await patchPower({ DeepSleep: v });
  if (r?.data?.error) {
    return false;
  }
  await refresh();
  return true;
}

/** ====== 菜单 ====== */
async function getContextMenu(_name?: string): Promise<{ title: string; items: MenuItem[] }> {
  const items: MenuItem[] = [];
  const modeUI = toUI(summary.PowerMode);
  const isSharing = modeUI === 'Sharing';
  const isMainBackup = modeUI === 'MainBackup';
  const activeName = list.value.find((i) => String(i.mode).toLowerCase() === 'active')?.name;

  // 1) 工作模式
  const mainBackupChildren: MenuItem[] =
    names.value.length >= 2
      ? names.value.map((nm) => ({
          key: `psu.mode.mainbackup.${nm}`,
          label: nm,
          active: isMainBackup && nm === activeName,
          action: { op: 'setMainBackupWithPrimary', params: { name: nm } },
        }))
      // 只有 1 个电源时，退化为仅切换模式（不指定主用）
      : [{
          key: 'psu.mode.mainbackup.onlyone',
          label: traduction('POWER_MAIN_STANDBY'),
          active: isMainBackup,
          action: { op: 'setPowerMode', params: { mode: 'MainBackup' } },
        }];

  items.push({
    key: 'psu.mode',
    label: traduction('POWER_WORKING_MODE'),
    hint: isSharing ? traduction('POWER_LOAD_BALANCING') : traduction('POWER_MAIN_STANDBY'),
    children: [
      {
        key: 'psu.mode.sharing',
        label: traduction('POWER_LOAD_BALANCING'),
        active: isSharing,
        action: { op: 'setPowerMode', params: { mode: 'Sharing' } },
      },
      {
        key: 'psu.mode.mainbackup',
        label: traduction('POWER_MAIN_STANDBY'),
        active: isMainBackup,
        children: mainBackupChildren,
      },
    ],
  });

  // 2) 主用电源（主备模式下）
  if (isMainBackup && names.value.length >= 2) {
    items.push({
      key: 'psu.primary',
      label: traduction('POWER_MAIN'),
      hint: activeName || '',
      children: names.value.map((nm) => ({
        key: `psu.primary.${nm}`,
        label: nm,
        active: nm === activeName,
        action: { op: 'setPrimarySupply', params: { name: nm } },
      })),
    });
  }

  // 3) 深度休眠
  const isOn = summary.DeepSleep === 'On';
  items.push({
    key: 'psu.deepsleep',
    label: traduction('POWER_DEEP_DORMANCY'),
    hint: isOn ? traduction('FDM_ENABLED') : traduction('FDM_DISABLED'),
    children: [
      {
        key: 'psu.deepsleep.on',
        label: traduction('FDM_ENABLED'),
        active: isOn,
        action: { op: 'setDeepSleep', params: { value: 'On' } },
      },
      {
        key: 'psu.deepsleep.off',
        label: traduction('FDM_DISABLED'),
        active: !isOn,
        action: { op: 'setDeepSleep', params: { value: 'Off' } },
      },
    ],
  });

  // 4) 刷新
  items.push({ key: 'psu.refresh', label: traduction('COMMON_REFRESH'), action: { op: 'refresh' } });
  return { title: 'Psu', items };
}

async function execContextAction(action: CtxAction): Promise<boolean> {
  const { op, params = {} } = action || {};
  if (!op) {
    return false;
  }
  try {
    switch (op) {
      case 'setPowerMode':
        return await setPowerMode(params.mode);
      case 'setMainBackupWithPrimary':
        return await setMainBackupWithPrimary(params.name);
      case 'setPrimarySupply':
        return await setPrimarySupply(params.name);
      case 'setDeepSleep':
        return await setDeepSleep(params.value);
      case 'refresh':
        await refresh();
        return true;
      default:
        return false;
    }
  } catch {
    return false;
  }
}

/** ====== 对外暴露 ====== */
defineExpose({
  buildPairs,
  getBasicText,
  getContextMenu,
  execContextAction,
  refresh,
  getNames,
});

onMounted(refresh);
</script>
