// @vitest-environment jsdom

import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { BridgeTab } from '../../settings/tabs/BridgeTab';
import { useBridgeState } from '../../settings/tabs/bridge/useBridgeState';

vi.mock('../../settings/helpers', () => ({
  t: (key: string) => key,
}));

vi.mock('../../settings/tabs/bridge/useBridgeState', () => ({
  useBridgeState: vi.fn(),
}));

vi.mock('../../settings/tabs/bridge/PlatformSection', () => ({
  PlatformSection: ({ platform }: { platform: string }) => <div data-testid={`platform-${platform}`} />,
}));

vi.mock('../../settings/tabs/bridge/WechatSection', () => ({
  WechatSection: () => <div data-testid="platform-wechat" />,
}));

vi.mock('../../settings/tabs/bridge/BridgeAgentRow', () => ({
  BridgeAgentRow: () => <div data-testid="bridge-agent-row" />,
}));

function bridgeState(overrides = {}) {
  return {
    status: {
      telegram: {},
      feishu: {},
      qq: {},
      wechat: {},
      permissionMode: 'auto',
      readOnly: false,
      receiptEnabled: true,
      knownUsers: {},
      owner: {},
    },
    globalSettingsSaving: false,
    selectedAgentId: 'hana',
    setSelectedAgentId: vi.fn(),
    publicIshiki: '',
    setPublicIshiki: vi.fn(),
    savePublicIshiki: vi.fn(),
    tgToken: '',
    setTgToken: vi.fn(),
    fsAppId: '',
    setFsAppId: vi.fn(),
    fsAppSecret: '',
    setFsAppSecret: vi.fn(),
    qqAppId: '',
    setQqAppId: vi.fn(),
    qqAppSecret: '',
    setQqAppSecret: vi.fn(),
    saveBridgeConfig: vi.fn(),
    testPlatform: vi.fn(),
    testingPlatform: null,
    showToast: vi.fn(),
    setOwner: vi.fn(),
    loadStatus: vi.fn(),
    saveGlobalSettings: vi.fn(),
    ...overrides,
  };
}

describe('BridgeTab permission mode', () => {
  afterEach(() => {
    cleanup();
    vi.clearAllMocks();
  });

  it('renders bridge permission mode as a three-option select without ask mode', async () => {
    const saveGlobalSettings = vi.fn();
    vi.mocked(useBridgeState).mockReturnValue(bridgeState({ saveGlobalSettings }) as never);

    render(<BridgeTab />);

    expect(screen.getByText('settings.bridge.receiptEnabled')).not.toBeNull();
    expect(screen.queryByText('settings.bridge.readOnly')).toBeNull();
    expect(screen.getByText('settings.bridge.permissionMode')).not.toBeNull();

    fireEvent.click(screen.getByRole('button', { name: /settings\.bridge\.permissionModeAuto/ }));

    expect(screen.getByRole('option', { name: /settings\.bridge\.permissionModeAuto/ })).not.toBeNull();
    expect(screen.getByRole('option', { name: /settings\.bridge\.permissionModeOperate/ })).not.toBeNull();
    expect(screen.getByRole('option', { name: /settings\.bridge\.permissionModeReadOnly/ })).not.toBeNull();
    expect(screen.queryByRole('option', { name: /ask/i })).toBeNull();

    fireEvent.click(screen.getByRole('option', { name: /settings\.bridge\.permissionModeOperate/ }));

    await waitFor(() => {
      expect(saveGlobalSettings).toHaveBeenCalledWith({ permissionMode: 'operate' });
    });
  });

  it('saves the bridge receipt toggle through global bridge settings', async () => {
    const saveGlobalSettings = vi.fn();
    vi.mocked(useBridgeState).mockReturnValue(bridgeState({ saveGlobalSettings }) as never);

    render(<BridgeTab />);

    const receiptToggle = screen.getByRole('switch', { name: /settings\.bridge\.receiptEnabled/ });
    expect(receiptToggle.getAttribute('aria-checked')).toBe('true');

    fireEvent.click(receiptToggle);

    expect(saveGlobalSettings).toHaveBeenCalledWith({ receiptEnabled: false });
  });

  it('keeps bridge permission mode in loading state until backend truth arrives', () => {
    vi.mocked(useBridgeState).mockReturnValue(bridgeState({ status: null }) as never);

    render(<BridgeTab />);

    const trigger = screen.getByRole('button', { name: /common\.loading/ }) as HTMLButtonElement;
    expect(trigger.disabled).toBe(true);
    expect(screen.queryByRole('button', { name: /settings\.bridge\.permissionModeAuto/ })).toBeNull();
  });
});
