import { describe, expect, it } from 'vitest';

describe('resolveStatus', () => {
  function resolveStatus(configured: boolean): { status: string; statusLabel: string } {
    if (configured) return { status: 'connected', statusLabel: 'connected' };
    return { status: 'unconfigured', statusLabel: 'not_configured' };
  }

  it('returns connected when configured is true', () => {
    const result = resolveStatus(true);
    expect(result.status).toBe('connected');
    expect(result.statusLabel).toBe('connected');
  });

  it('returns unconfigured when configured is false', () => {
    const result = resolveStatus(false);
    expect(result.status).toBe('unconfigured');
    expect(result.statusLabel).toBe('not_configured');
  });
});

describe('CHANNEL_KEY_MAP', () => {
  const CHANNEL_KEY_MAP: Record<string, string> = {
    WeChat: 'wechat',
    WeCom: 'wecom',
    DingTalk: 'dingtalk',
    Feishu: 'feishu',
  };

  it('maps WeChat to wechat', () => {
    expect(CHANNEL_KEY_MAP['WeChat']).toBe('wechat');
  });

  it('maps WeCom to wecom', () => {
    expect(CHANNEL_KEY_MAP['WeCom']).toBe('wecom');
  });

  it('maps DingTalk to dingtalk', () => {
    expect(CHANNEL_KEY_MAP['DingTalk']).toBe('dingtalk');
  });

  it('maps Feishu to feishu', () => {
    expect(CHANNEL_KEY_MAP['Feishu']).toBe('feishu');
  });

  it('returns undefined for lowercase keys', () => {
    expect(CHANNEL_KEY_MAP['wechat']).toBeUndefined();
    expect(CHANNEL_KEY_MAP['wecom']).toBeUndefined();
    expect(CHANNEL_KEY_MAP['dingtalk']).toBeUndefined();
    expect(CHANNEL_KEY_MAP['feishu']).toBeUndefined();
  });

  it('has exactly 4 entries', () => {
    expect(Object.keys(CHANNEL_KEY_MAP)).toHaveLength(4);
  });
});

describe('status mapping from backend', () => {
  const CHANNEL_KEY_MAP: Record<string, string> = {
    WeChat: 'wechat',
    WeCom: 'wecom',
    DingTalk: 'dingtalk',
    Feishu: 'feishu',
  };

  function mapChannels(
    backendChannels: Record<string, boolean>,
  ): Record<string, boolean> {
    const result: Record<string, boolean> = {
      wechat: false,
      wecom: false,
      dingtalk: false,
      feishu: false,
    };
    for (const [backendKey, configured] of Object.entries(backendChannels)) {
      const mapped = CHANNEL_KEY_MAP[backendKey];
      if (mapped) result[mapped] = configured;
    }
    return result;
  }

  it('maps all four channels when all are configured', () => {
    const backend = {
      WeChat: true,
      WeCom: true,
      DingTalk: true,
      Feishu: true,
    };
    const result = mapChannels(backend);
    expect(result.wechat).toBe(true);
    expect(result.wecom).toBe(true);
    expect(result.dingtalk).toBe(true);
    expect(result.feishu).toBe(true);
  });

  it('maps correctly when some channels are unconfigured', () => {
    const backend = {
      WeChat: true,
      WeCom: false,
      DingTalk: true,
      Feishu: false,
    };
    const result = mapChannels(backend);
    expect(result.wechat).toBe(true);
    expect(result.wecom).toBe(false);
    expect(result.dingtalk).toBe(true);
    expect(result.feishu).toBe(false);
  });

  it('ignores unknown channel keys', () => {
    const backend = {
      WeChat: true,
      Telegram: true,
      Slack: false,
    };
    const result = mapChannels(backend);
    expect(result.wechat).toBe(true);
    expect(result.wecom).toBe(false);
  });

  it('handles empty backend channels', () => {
    const result = mapChannels({});
    expect(result.wechat).toBe(false);
    expect(result.wecom).toBe(false);
    expect(result.dingtalk).toBe(false);
    expect(result.feishu).toBe(false);
  });
});

describe('saveXxxConfig TOML section construction', () => {
  function buildFeishuSection(appId: string, appSecret: string): string {
    return `\n[channels.feishu]\nenabled = true\napp_id = "${appId}"\napp_secret = "${appSecret}"\nallowed_users = ["*"]\nreceive_mode = "websocket"\n`;
  }

  function buildDingtalkSection(clientId: string, clientSecret: string): string {
    return `\n[channels.dingtalk]\nenabled = true\nclient_id = "${clientId}"\nclient_secret = "${clientSecret}"\nallowed_users = ["*"]\n`;
  }

  function buildWecomSection(botId: string, secret: string): string {
    return `\n[channels.wecom]\nenabled = true\nbot_id = "${botId}"\nsecret = "${secret}"\nallowed_users = ["*"]\n`;
  }

  it('builds feishu section with correct fields', () => {
    const section = buildFeishuSection('app123', 'sec456');
    expect(section).toContain('[channels.feishu]');
    expect(section).toContain('enabled = true');
    expect(section).toContain('app_id = "app123"');
    expect(section).toContain('app_secret = "sec456"');
    expect(section).toContain('receive_mode = "websocket"');
  });

  it('builds dingtalk section with correct fields', () => {
    const section = buildDingtalkSection('client789', 'secret012');
    expect(section).toContain('[channels.dingtalk]');
    expect(section).toContain('enabled = true');
    expect(section).toContain('client_id = "client789"');
    expect(section).toContain('client_secret = "secret012"');
  });

  it('builds wecom section with correct fields', () => {
    const section = buildWecomSection('bot345', 'sec678');
    expect(section).toContain('[channels.wecom]');
    expect(section).toContain('enabled = true');
    expect(section).toContain('bot_id = "bot345"');
    expect(section).toContain('secret = "sec678"');
  });

  it('detects existing section in TOML', () => {
    const toml = '[channels.feishu]\nenabled = true';
    expect(toml.includes('[channels.feishu]')).toBe(true);
    expect(toml.includes('[channels.dingtalk]')).toBe(false);
  });

  it('detects existing [channels] header', () => {
    const toml = '[channels]\n[channels.feishu]\nenabled = true';
    expect(toml.includes('[channels]')).toBe(true);
  });
});

describe('disconnectChannel TOML deletion', () => {
  function removeChannelKey(
    config: Record<string, unknown>,
    channelKey: string,
  ): Record<string, unknown> {
    const channels = config.channels as Record<string, unknown> | undefined;
    if (channels && channelKey in channels) {
      const updated = { ...channels };
      delete updated[channelKey];
      return { ...config, channels: updated };
    }
    return config;
  }

  it('removes feishu from channels config', () => {
    const config = {
      channels: {
        feishu: { enabled: true },
        wecom: { enabled: true },
      },
    };
    const result = removeChannelKey(config, 'feishu');
    const channels = result.channels as Record<string, unknown>;
    expect('feishu' in channels).toBe(false);
    expect('wecom' in channels).toBe(true);
  });

  it('removes wecom from channels config', () => {
    const config = {
      channels: {
        feishu: { enabled: true },
        wecom: { enabled: true },
      },
    };
    const result = removeChannelKey(config, 'wecom');
    const channels = result.channels as Record<string, unknown>;
    expect('wecom' in channels).toBe(false);
    expect('feishu' in channels).toBe(true);
  });

  it('does nothing when channel key does not exist', () => {
    const config = {
      channels: {
        feishu: { enabled: true },
      },
    };
    const result = removeChannelKey(config, 'dingtalk');
    const channels = result.channels as Record<string, unknown>;
    expect('feishu' in channels).toBe(true);
  });

  it('does nothing when channels is undefined', () => {
    const config = {};
    const result = removeChannelKey(config, 'feishu');
    expect(result).toEqual({});
  });
});

describe('getChannelIdentifier logic', () => {
  function extractChannelId(
    channelKey: string,
    channels: Record<string, Record<string, unknown>> | undefined,
  ): string {
    const section = channels?.[channelKey];
    switch (channelKey) {
      case 'wecom':
        return String(section?.bot_id ?? '—');
      case 'dingtalk':
        return String(section?.client_id ?? '—');
      case 'feishu':
        return String(section?.app_id ?? '—');
      default:
        return '—';
    }
  }

  it('extracts bot_id for wecom', () => {
    const channels = { wecom: { bot_id: 'bot_abc' } };
    expect(extractChannelId('wecom', channels)).toBe('bot_abc');
  });

  it('extracts client_id for dingtalk', () => {
    const channels = { dingtalk: { client_id: 'client_xyz' } };
    expect(extractChannelId('dingtalk', channels)).toBe('client_xyz');
  });

  it('extracts app_id for feishu', () => {
    const channels = { feishu: { app_id: 'app_123' } };
    expect(extractChannelId('feishu', channels)).toBe('app_123');
  });

  it('returns placeholder when channel not configured', () => {
    expect(extractChannelId('wecom', {})).toBe('—');
    expect(extractChannelId('dingtalk', undefined)).toBe('—');
    expect(extractChannelId('feishu', {})).toBe('—');
  });

  it('returns placeholder when field is missing', () => {
    const channels = { wecom: { enabled: true } };
    expect(extractChannelId('wecom', channels)).toBe('—');
  });
});
