// mock.ts — MockClient：演示数据,供阶段 A 的 UI 验收使用,零网络依赖。
import {
  ApiClient,
  ApiError,
  Device,
  LoginResult,
  Me,
  RedeemResult,
  Session,
  SubscriptionInfo,
  TotpSetup,
} from './types';
import { setSession, clearSession } from './session';

const delay = (ms = 420) => new Promise((r) => setTimeout(r, ms));

function makeSession(): Session {
  return {
    accessToken: 'mock-access-' + Math.random().toString(36).slice(2),
    refreshToken: 'mock-refresh-' + Math.random().toString(36).slice(2),
    accessExpiresAt: Date.now() + 10 * 60_000,
  };
}

export class MockClient implements ApiClient {
  // 演示态：PRO 会员,已开启 2FA(故登录走二段式)
  private totpEnabled = true;
  private pending: string | null = null;
  private subUrl = 'https://sub.pangolin.vpn/s/8f3kx92m';
  private devices: Device[] = [
    { id: 'd1', name: 'iPhone 15 Pro', platform: 'iOS 18', lastActive: '刚刚', current: true },
    { id: 'd2', name: 'MacBook Air', platform: 'macOS 15', lastActive: '2 小时前', current: false },
  ];

  async login(email: string, password: string): Promise<LoginResult> {
    await delay();
    // 演示锁定/失败：用特定凭证触发,便于验收双语文案
    if (password === 'locked') {
      throw new ApiError(
        { code: 'account_locked', message_zh: '失败次数过多,账户已临时锁定', message_en: 'Too many attempts — account temporarily locked' },
        30,
      );
    }
    if (password === 'wrong' || !/\S+@\S+\.\S+/.test(email)) {
      throw new ApiError({ code: 'invalid_credentials', message_zh: '邮箱或密码错误', message_en: 'Wrong email or password' });
    }
    if (this.totpEnabled) {
      this.pending = 'mock-pending-' + Math.random().toString(36).slice(2);
      return { kind: 'totp_required', pendingToken: this.pending };
    }
    const s = makeSession();
    setSession(s);
    return { kind: 'session', session: s };
  }

  async loginTotp(_pendingToken: string, code: string): Promise<Session> {
    await delay();
    if (code === '000000') {
      throw new ApiError({ code: 'totp_invalid', message_zh: '动态码不正确,请重试', message_en: 'Invalid code, try again' });
    }
    const s = makeSession();
    setSession(s);
    this.pending = null;
    return s;
  }

  async refresh(): Promise<Session> {
    await delay(150);
    const s = makeSession();
    setSession(s);
    return s;
  }

  async getMe(): Promise<Me> {
    await delay(260);
    return {
      email: 'me@pangolin.vpn',
      plan: 'pro',
      expiresAt: '2026-12-31',
      devicesUsed: 2,
      devicesMax: 5,
      quotaTodayMin: null,
      dataTodayGB: 0.8,
      weeklyGB: [1.8, 2.4, 1.2, 3.1, 4.0, 5.2, 2.6],
      totpEnabled: this.totpEnabled,
    };
  }

  async getSubscription(): Promise<SubscriptionInfo> {
    await delay(160);
    return { url: this.subUrl };
  }

  async resetSubscription(): Promise<SubscriptionInfo> {
    await delay(500);
    this.subUrl = 'https://sub.pangolin.vpn/s/' + Math.random().toString(36).slice(2, 10);
    return { url: this.subUrl };
  }

  async listDevices(): Promise<Device[]> {
    await delay(220);
    return [...this.devices];
  }

  async removeDevice(id: string): Promise<void> {
    await delay(360);
    this.devices = this.devices.filter((d) => d.id !== id);
  }

  async redeem(code: string): Promise<RedeemResult> {
    await delay(520);
    const c = code.trim().toUpperCase();
    if (c === 'LOCKED') {
      throw new ApiError(
        { code: 'rate_limited', message_zh: '操作过于频繁,请稍后再试', message_en: 'Too many requests, slow down' },
        20,
      );
    }
    if (c === 'USED') {
      throw new ApiError({ code: 'code_used', message_zh: '激活码已被使用', message_en: 'Activation code already used' });
    }
    if (c.length < 4 || c === 'INVALID') {
      throw new ApiError({ code: 'code_invalid', message_zh: '激活码无效', message_en: 'Invalid activation code' });
    }
    return { plan: 'pro', expiresAt: '2027-12-31' };
  }

  async totpSetup(): Promise<TotpSetup> {
    await delay(260);
    const secret = 'JBSWY3DPEHPK3PXP';
    return {
      secret,
      otpauthUri: `otpauth://totp/Pangolin:me@pangolin.vpn?secret=${secret}&issuer=Pangolin`,
    };
  }

  async totpVerify(code: string): Promise<void> {
    await delay(300);
    if (code === '000000' || code.length !== 6) {
      throw new ApiError({ code: 'totp_invalid', message_zh: '动态码不正确,请重试', message_en: 'Invalid code, try again' });
    }
    this.totpEnabled = true;
  }

  async totpDisable(code: string): Promise<void> {
    await delay(300);
    if (code === '000000' || code.length !== 6) {
      throw new ApiError({ code: 'totp_invalid', message_zh: '动态码不正确,请重试', message_en: 'Invalid code, try again' });
    }
    this.totpEnabled = false;
  }

  async logout(): Promise<void> {
    await delay(120);
    this.pending = null;
    clearSession();
  }
}
