// @vitest-environment jsdom
import { cleanup, render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { afterEach, describe, expect, it, vi } from 'vitest';

import { AppShell, type InstanceContext } from '../app-shell.js';
import { SensitiveRevealProvider } from '../privacy/sensitive-reveal.js';
import {
  OverviewSystemPage,
  type OverviewDataSource,
  type OverviewSnapshot,
} from './overview-system.js';
import type { InstanceCapabilityMap } from './instance-detail.js';

afterEach(cleanup);

const owner: InstanceContext = {
  id: 'alpha',
  name: 'Alpha',
  origin: 'https://alpha.example',
  status: 'online',
  authentication: 'authenticated',
  freshness: 'fresh',
  resources: {
    cpuPercent: 18.4,
    memoryPercent: 63.2,
    maxTemperatureCelsius: 46.7,
    phoneNumbers: ['13800138000'],
  },
};
const overviewCapabilities: InstanceCapabilityMap = {
  overview: { state: 'supported' },
};
const snapshot: OverviewSnapshot = {
  observedAt: '2026-07-17T10:00:00Z',
  device: { Model: 'SIMBox 8', Uptime: '2 days' },
  sim: { Slots: 8, Active: 6 },
  network: { Operator: 'Example Mobile', Registration: 'registered' },
  stats: { 'Messages today': 42, Calls: 7 },
  cpu: { Usage: '18%', Temperature: '46 °C' },
  connectivity: { State: 'connected', Latency: '21 ms' },
};

function deferredSource() {
  let resolve!: (value: OverviewSnapshot) => void;
  let reject!: (reason: unknown) => void;
  const load = vi.fn<OverviewDataSource['load']>(
    (_instanceId, _signal) =>
      new Promise((done, fail) => {
        void _instanceId;
        void _signal;
        resolve = done;
        reject = fail;
      }),
  );
  return {
    source: { load },
    load,
    resolve: (value: OverviewSnapshot) => resolve(value),
    reject: (reason: unknown) => reject(reason),
  };
}

describe('Phase 6.1 Overview / System read slice', () => {
  it('loads only through an injected source and renders six structured sections', async () => {
    const pending = deferredSource();
    render(
      <AppShell
        pathname="/instances/alpha/overview"
        instance={owner}
        capabilities={overviewCapabilities}
        overviewDataSource={pending.source}
      />,
    );

    expect(screen.getByRole('status', { name: '概览加载状态' }).textContent).toContain(
      '正在加载概览',
    );
    expect(pending.load).toHaveBeenCalledWith('alpha', expect.any(AbortSignal));
    pending.resolve(snapshot);

    for (const heading of ['设备', 'SIM', '网络', '统计', 'CPU', '连接状态']) {
      expect(await screen.findByRole('heading', { name: heading })).toBeTruthy();
    }
    expect(within(screen.getByRole('region', { name: '设备' })).getByText('SIMBox 8')).toBeTruthy();
    expect(screen.getByText(/观测时间：2026-07-17T10:00:00Z/)).toBeTruthy();
    expect(screen.getByRole('button', { name: '重启服务' })).toBeTruthy();
    expect(screen.getByRole('button', { name: '系统重启' })).toBeTruthy();
    expect(screen.getByText(/服务重启与系统重启均为高风险操作/i)).toBeTruthy();
  });

  it('translates only known field names and values while preserving unknown safe data', async () => {
    render(
      <OverviewSystemPage
        instance={owner}
        dataSource={{
          load: async () => ({
            ...snapshot,
            device: { Model: 'SIMBox 8', Enabled: true, Mystery: 'vendor-value' },
            network: { Registration: 'registered' },
            connectivity: { State: 'connected' },
          }),
        }}
      />,
    );

    const device = await screen.findByRole('region', { name: '设备' });
    expect(within(device).getByText('型号')).toBeTruthy();
    expect(within(device).getByText('Enabled')).toBeTruthy();
    expect(within(device).getByText('是')).toBeTruthy();
    expect(within(device).getByText('Mystery')).toBeTruthy();
    expect(within(device).getByText('vendor-value')).toBeTruthy();
    expect(within(screen.getByRole('region', { name: '网络' })).getByText('已注册')).toBeTruthy();
    expect(
      within(screen.getByRole('region', { name: '连接状态' })).getByText('已连接'),
    ).toBeTruthy();
  });

  it('renders the route-owned Fleet resource summary without inventing another endpoint', () => {
    render(
      <SensitiveRevealProvider>
        <AppShell
          pathname="/instances/alpha/overview"
          instance={owner}
          capabilities={overviewCapabilities}
        />
        ,
      </SensitiveRevealProvider>,
    );
    const operations = screen.getByRole('region', { name: '运行状态与资源' });
    expect(within(operations).getByText('在线')).toBeTruthy();
    expect(within(operations).getByRole('meter', { name: 'CPU使用率' }).getAttribute('value')).toBe(
      '18.4',
    );
    expect(
      within(operations).getByRole('meter', { name: '内存使用率' }).getAttribute('value'),
    ).toBe('63.2');
    expect(within(operations).getByText('46.7 °C')).toBeTruthy();
    expect(within(operations).getByText('138 •••• 8000')).toBeTruthy();
    expect(within(operations).queryByText('13800138000')).toBeNull();
    expect(screen.queryByText(/没有可用的安全概览只读数据源/i)).toBeNull();
    expect(screen.getByRole('button', { name: '重启服务' })).toBeTruthy();
    expect(screen.getByRole('button', { name: '系统重启' })).toBeTruthy();
  });

  it('reveals the overview phone number through the console-wide switch', async () => {
    const user = userEvent.setup();
    render(
      <AppShell
        pathname="/instances/alpha/overview"
        instance={owner}
        capabilities={overviewCapabilities}
      />,
    );
    const operations = screen.getByRole('region', { name: '运行状态与资源' });
    expect(within(operations).getByText('138 •••• 8000')).toBeTruthy();

    await user.click(screen.getByRole('button', { name: '显示敏感标识' }));
    expect(within(operations).getByText('13800138000')).toBeTruthy();
    expect(within(operations).queryByText('138 •••• 8000')).toBeNull();
  });

  it('shows authentication-required without loading or leaking prior owner data', async () => {
    const load = vi.fn<OverviewDataSource['load']>().mockResolvedValue(snapshot);
    const { rerender } = render(<OverviewSystemPage instance={owner} dataSource={{ load }} />);
    expect(await screen.findByText('SIMBox 8')).toBeTruthy();

    rerender(
      <OverviewSystemPage
        instance={{
          ...owner,
          id: 'bravo',
          name: 'Bravo',
          authentication: 'auth-required',
          status: 'auth-required',
        }}
        dataSource={{ load }}
      />,
    );
    expect(screen.getByRole('alert').textContent).toMatch(/需要先完成认证/i);
    expect(screen.queryByText('SIMBox 8')).toBeNull();
    expect(load).toHaveBeenCalledTimes(1);
  });

  it('marks injected data stale from owner context while retaining structured values', async () => {
    render(
      <OverviewSystemPage
        instance={{ ...owner, freshness: 'stale' }}
        dataSource={{ load: async () => snapshot }}
      />,
    );
    expect((await screen.findByRole('status', { name: '概览数据新鲜度' })).textContent).toMatch(
      /可能已过期/i,
    );
    expect(screen.getByText('SIMBox 8')).toBeTruthy();
  });

  it('surfaces read errors and supports a real injected retry', async () => {
    const user = userEvent.setup();
    const load = vi
      .fn<OverviewDataSource['load']>()
      .mockRejectedValueOnce(new Error('collector unavailable'))
      .mockResolvedValueOnce(snapshot);
    render(<OverviewSystemPage instance={owner} dataSource={{ load }} />);

    expect((await screen.findByRole('alert')).textContent).toContain('无法加载概览数据。');
    await user.click(screen.getByRole('button', { name: '重试加载概览' }));
    expect(await screen.findByText('SIMBox 8')).toBeTruthy();
    expect(load).toHaveBeenCalledTimes(2);
  });

  it('aborts old reads, fences late owners, and reloads on refreshSignal', async () => {
    const alpha = deferredSource();
    const bravo = deferredSource();
    const load = vi.fn<OverviewDataSource['load']>((instanceId, signal) =>
      instanceId === 'alpha'
        ? alpha.source.load(instanceId, signal)
        : bravo.source.load(instanceId, signal),
    );
    const source = { load };
    const { rerender } = render(
      <OverviewSystemPage instance={owner} dataSource={source} refreshSignal={0} />,
    );
    const alphaSignal = load.mock.calls[0]?.[1];

    rerender(
      <OverviewSystemPage
        instance={{ ...owner, id: 'bravo', name: 'Bravo' }}
        dataSource={source}
        refreshSignal={0}
      />,
    );
    expect(alphaSignal?.aborted).toBe(true);
    alpha.resolve({ ...snapshot, device: { Model: 'Alpha stale' } });
    bravo.resolve({ ...snapshot, device: { Model: 'Bravo current' } });
    expect(await screen.findByText('Bravo current')).toBeTruthy();
    expect(screen.queryByText('Alpha stale')).toBeNull();

    rerender(
      <OverviewSystemPage
        instance={{ ...owner, id: 'bravo', name: 'Bravo' }}
        dataSource={source}
        refreshSignal={1}
      />,
    );
    expect(load).toHaveBeenCalledTimes(3);
  });

  it('keeps unsupported capability explicit and does not invoke the overview source', () => {
    const load = vi.fn<OverviewDataSource['load']>();
    render(
      <AppShell
        pathname="/instances/alpha/overview"
        instance={owner}
        capabilities={{
          overview: { state: 'unsupported', explanation: 'No overview read support' },
        }}
        overviewDataSource={{ load }}
      />,
    );
    expect(screen.getAllByText('No overview read support').length).toBeGreaterThan(0);
    expect(load).not.toHaveBeenCalled();
  });
});
